diff --git a/.agents/skills/airflow-translations/locales/el.md b/.agents/skills/airflow-translations/locales/el.md index 10d2603d974ce..76e9dd1b78295 100644 --- a/.agents/skills/airflow-translations/locales/el.md +++ b/.agents/skills/airflow-translations/locales/el.md @@ -17,7 +17,6 @@ The following terms **must remain in English unchanged** (case-sensitive): - `XCom` / `XComs` — Airflow cross-communication mechanism - `Backfill` / `Backfills` — Historical data fill-in; kept as a recognizable technical term - `Pool` / `Pools` — Resource constraint mechanism -- `Slot` / `Slots` — Pool slot count - `Map Index` — Task mapping index - `PID` — Unix process identifier - `ID` — Universal abbreviation @@ -34,37 +33,39 @@ The following terms **must remain in English unchanged** (case-sensitive): The following Airflow-specific terms have established Greek translations that **must be used consistently**: -| English Term | Greek Translation | Notes | -| ---------------------- | ------------------------------------- | --------------------------------------------------- | -| Task | Εργασία | Plural: "Εργασίες" | -| Task Instance | Εκτέλεση Εργασίας | Plural: "Εκτελέσεις Εργασίας" | -| Task Group | Ομάδα Εργασιών | | -| Dag Run | Εκτέλεση Dag | Plural: "Εκτελέσεις Dag" | -| Run | Εκτέλεση | Plural: "Εκτελέσεις"; used standalone | -| Trigger (noun) | Ενεργοποίηση | | -| Trigger Rule | Κανόνας Ενεργοποίησης | | -| Triggerer | Ενεργοποιητής | Component name | -| Scheduler | Προγραμματιστής | | -| Schedule (noun) | Πρόγραμμα | | -| Executor | Εκτελεστής | | -| Connection | Σύνδεση | Plural: "Συνδέσεις" | -| Variable | Μεταβλητή | Plural: "Μεταβλητές" | -| Audit Log | Καταγραφή Ελέγχου | | -| Log | Καταγραφή | | -| State | Κατάσταση | | -| Queue (noun) | Ουρά | e.g., "Σε Ουρά" for "queued" | -| Config / Configuration | Ρυθμίσεις | | -| Operator | Τελεστής | Plural: "Τελεστές" | -| Asset | Οντότητα | Plural: "Οντότητες" — translated (Greek-specific) | -| Asset Event | Συμβάν Οντότητας | Plural: "Συμβάντα Οντοτήτων" | -| Plugin | Πρόσθετο | Plural: "Πρόσθετα" | -| Provider | Πάροχος | Plural: "Πάροχοι" | -| Dag Processor | Επεξεργαστής Dag | Component name | -| Heartbeat | Παλμός | | -| Map Index | Δείκτης Χάρτη | | -| Upstream (dependency) | Ανάντη | Used in states: "Αποτυχία Ανάντη" | -| Upstream (action) | Άνοδος | Used in clear-task action options | -| Downstream (action) | Κάθοδος | Used in clear-task action options | +| English Term | Greek Translation | Notes | +|------------------------|-----------------------|---------------------------------------------------| +| Task | Εργασία | Plural: "Εργασίες" | +| Task Instance | Εκτέλεση Εργασίας | Plural: "Εκτελέσεις Εργασίας" | +| Task Group | Ομάδα Εργασιών | | +| Dag Run | Εκτέλεση Dag | Plural: "Εκτελέσεις Dag" | +| Run | Εκτέλεση | Plural: "Εκτελέσεις"; used standalone | +| Trigger (noun) | Ενεργοποίηση | | +| Trigger Rule | Κανόνας Ενεργοποίησης | | +| Triggerer | Ενεργοποιητής | Component name | +| Scheduler | Προγραμματιστής | | +| Schedule (noun) | Πρόγραμμα | | +| Executor | Εκτελεστής | | +| Connection | Σύνδεση | Plural: "Συνδέσεις" | +| Variable | Μεταβλητή | Plural: "Μεταβλητές" | +| Audit Log | Καταγραφή Ελέγχου | | +| Log | Καταγραφή | | +| State | Κατάσταση | | +| Queue (noun) | Ουρά | e.g., "Σε Ουρά" for "queued" | +| Config / Configuration | Ρυθμίσεις | | +| Operator | Τελεστής | Plural: "Τελεστές" | +| Asset | Οντότητα | Plural: "Οντότητες" — translated (Greek-specific) | +| Asset Event | Συμβάν Οντότητας | Plural: "Συμβάντα Οντοτήτων" | +| Plugin | Πρόσθετο | Plural: "Πρόσθετα" | +| Provider | Πάροχος | Plural: "Πάροχοι" | +| Dag Processor | Επεξεργαστής Dag | Component name | +| Heartbeat | Παλμός | | +| Map Index | Δείκτης Χάρτη | | +| Upstream (dependency) | Ανάντη | Used in states: "Αποτυχία Ανάντη" | +| Upstream (action) | Άνοδος | Used in clear-task action options | +| Downstream (action) | Κάθοδος | Used in clear-task action options | +| Job (process) | Διεργασία | | +| Slot | Θέση | Plural: "Θέσεις"; e.g. "Θέσεις Pool" | > **Note on `Asset`:** Unlike French, Catalan, and other locales where "Asset" is kept in > English, Greek translates it as **Οντότητα** ("entity"). Use "Οντότητα" consistently @@ -230,7 +231,7 @@ Copy → "Αντιγραφή" **DON'T:** - Write "DAG" — always use "Dag" -- Translate `XCom`, `Backfill`, `Pool`, `Slot`, `ID`, `JSON`, `REST API`, `UTC`, `PID` +- Translate `XCom`, `Backfill`, `Pool`, `ID`, `JSON`, `REST API`, `UTC`, `PID` - Translate `{{variable}}` placeholder names - Drop Greek diacritics (e.g., never write "Εκτελεση" for "Εκτέλεση") - Use the informal "εσύ" form diff --git a/.agents/skills/upgrade-fab-provider/SKILL.md b/.agents/skills/upgrade-fab-provider/SKILL.md new file mode 100644 index 0000000000000..1b08f8aa22adb --- /dev/null +++ b/.agents/skills/upgrade-fab-provider/SKILL.md @@ -0,0 +1,270 @@ +--- +name: upgrade-fab-provider +description: > + Upgrade the pinned Flask-AppBuilder (FAB) dependency in the Apache Airflow + FAB provider (`providers/fab/`). Bumps the exact `flask-appbuilder==` pin and + its mirror constant, regenerates `uv.lock`, drives the `test_fab_alignment.py` + drift tripwire, reviews the vendored security-manager `override.py` against the + new upstream FAB, and conditionally re-vendors static assets / DB migrations. + Use when asked to "upgrade FAB", "bump flask-appbuilder", or move the FAB + provider to a newer Flask-AppBuilder release. +license: Apache-2.0 +--- + + + +# upgrade-fab-provider + +Airflow's FAB provider is **tightly coupled** to a specific Flask-AppBuilder +release because it vendors-in and subclasses large parts of FAB's security +manager. A version bump is therefore never "just change the pin" — it must be +reconciled against the vendored code, and that reconciliation is enforced by a +pytest **alignment test**, not a prek hook. + +The canonical reference for a real bump is PR **#66841** ("Bump flask-appbuilder +to 5.2.1 and mirror new auth event hooks") — commit `c72b6613fd`. Read its diff +first when in doubt: `git show c72b6613fd`. + +## The coupling — why this is not a one-line change + +- `providers/fab/pyproject.toml:75-80` explains it: Airflow vendored FAB's + security-manager code into + `providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py` + (~2700 lines) as `FabAirflowSecurityManagerOverride`. Every bump must review + that class against upstream FAB for new / changed / removed methods. +- `test_fab_alignment.py` mechanically detects drift between the **installed** + FAB package and the vendored override, and **fails CI** until the developer + reconciles it. + +## Inputs + +- **Target version** — the FAB version to move to. If not given, use the latest + release on PyPI (`https://pypi.org/pypi/flask-appbuilder/json` → `info.version`). + Confirm the target with the user if it is a **major or minor** bump (higher + reconciliation risk); a **patch** bump can proceed. + +## The files a bump touches + +**Always:** + +1. `providers/fab/pyproject.toml` — line ~80, the `flask-appbuilder==X.Y.Z` pin + (the **only** real dependency pin in the repo). +2. `providers/fab/tests/unit/fab/auth_manager/security_manager/test_fab_alignment.py` + — `EXPECTED_FAB_VERSION = "X.Y.Z"` (line ~43). Must move in lockstep with the pin. +3. `providers/fab/docs/index.rst` — the dependency table row + ``` ``flask-appbuilder`` ``==X.Y.Z`` ``` (line ~114). +4. `providers/fab/README.rst` — the Requirements table row (line ~60). **Do + not hand-edit** — it is auto-generated. Regenerate it from the bumped + `pyproject.toml` with the `sync-provider-readme` prek hook (Step 8); the hook + re-renders the table whenever `pyproject.toml` changes. (Pre-existing bumps + that predate this hook left it to release-time regeneration; today the hook is + per-commit, so CI flags the drift — run it.) +5. `uv.lock` — regenerated (see Step 4 for the pinned-uv caveat). + +**Conditionally:** + +6. `providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py` + — transplant any relevant upstream FAB changes (new auth hooks, changed + signatures, ported fixes). The reference bump added +37 lines here. **Note:** + a green alignment test does not prove the transplant is unnecessary — a + security fix may live inside a method Airflow vendors (see the 5.2.2 worked + example below). +7. `providers/fab/src/airflow/providers/fab/www/**` + `providers/fab/www-hash.txt` + — only if the new FAB ships changed static assets / templates that are + re-vendored (see Step 6). +8. `providers/fab/src/airflow/providers/fab/migrations/versions/**` — only if the + new FAB version ships DB migrations (see Step 7). + +**Never:** no newsfragment, and do **not** hand-edit `providers/fab/docs/changelog.rst` +— providers are released from `main` and the release manager regenerates the +changelog from `git log` (per `providers/AGENTS.md`). The commit subject is the +changelog entry. + +## Procedure + +### Step 1 — Determine the target version and current state + +- Read the current pin: `grep flask-appbuilder== providers/fab/pyproject.toml`. +- Resolve the target (PyPI latest, or the user's requested version). +- Classify the jump: patch / minor / major. For minor/major, skim the FAB + release notes (`https://github.com/dpgaspar/Flask-AppBuilder/releases`) for + security-manager / model / template changes before editing. + +### Step 2 — Bump the three source pins + +Edit in lockstep: + +- `providers/fab/pyproject.toml` — the `flask-appbuilder==X.Y.Z` line (keep the + trailing `# Whenever updating the version, run test_fab_alignment.py to verify.` + comment). +- `test_fab_alignment.py` — `EXPECTED_FAB_VERSION = "X.Y.Z"`. It is the tripwire; + editing it now is fine — you will keep re-running the test until it and the + other three tests pass. +- `providers/fab/docs/index.rst` — the dependency-table `==X.Y.Z` row. + +### Step 3 — Install the new FAB into the provider venv + +`uv --project providers/fab sync` installs the new pin. Confirm the installed +version: + +```bash +uv run --project providers/fab python -c \ + "import importlib.metadata as m; print(m.version('flask-appbuilder'))" +``` + +### Step 4 — Regenerate uv.lock (pinned uv!) + +The lock **must** be regenerated with the repo's pinned uv version, or it drifts +hundreds of unrelated marker lines: + +```bash +AIRFLOW_UV_VERSION=$(grep -oE 'AIRFLOW_UV_VERSION=[0-9.]+' Dockerfile.ci | head -1 | cut -d= -f2) +uvx --from uv==$AIRFLOW_UV_VERSION uv lock +``` + +If a conflict is irrecoverable, delete `uv.lock` and re-run `uv lock` with the +pinned version. Confirm the diff is limited to the FAB bump, not a wholesale +marker rewrite. + +### Step 5 — Run the alignment test and reconcile override.py + +```bash +uv run --project providers/fab pytest \ + providers/fab/tests/unit/fab/auth_manager/security_manager/test_fab_alignment.py -xvs +``` + +Under the host sandbox the test needs a writable `AIRFLOW_HOME` and the +rerun-failures socket disabled — if it errors on a socket `bind` or on +`~/airflow`, run it as: + +```bash +AIRFLOW_HOME="$TMPDIR/fab_home" uv run --project providers/fab pytest \ + providers/fab/tests/.../test_fab_alignment.py -q -p no:rerunfailures +``` + +The four tests and how to fix each: + +1. **`test_fab_version_matches_expected`** — trips on the version mismatch. It + passes once `EXPECTED_FAB_VERSION` == installed version, but only after you + have done the review below. +2. **`test_no_unaudited_fab_methods`** — a new FAB public method exists that is + neither implemented in `override.py` nor listed in `AUDITED_EXCLUSIONS`. + Fix: either implement/override it in `override.py`, or add it to + `AUDITED_EXCLUSIONS` **with a justification comment**. +3. **`test_no_stale_exclusions`** — `AUDITED_EXCLUSIONS` lists a method the new + FAB no longer has. Fix: remove that entry. +4. **`test_shared_method_signatures_compatible`** — FAB changed a method + signature (new required param). Fix: update the `override.py` signature, or + add to `KNOWN_SIGNATURE_DEVIATIONS` if the divergence is intentional. + +**The manual review that the test cannot fully automate:** diff the vendored +`override.py` against the new FAB's `flask_appbuilder/security/sqla/manager.py` +and `BaseSecurityManager` and **transplant behavioural changes** (bug fixes, new +auth event hooks), not just signatures — the test only checks method *presence* +and *required params*. Locate the installed source: + +```bash +uv run --project providers/fab python -c \ + "import flask_appbuilder.security.sqla.manager as m; print(m.__file__)" +``` + +### Step 6 — Re-vendor static assets / templates (only if changed) + +If the new FAB changed frontend assets that Airflow vendors under +`providers/fab/src/airflow/providers/fab/www/` (templates in +`templates/appbuilder/`, static JS/CSS), re-vendor them, then regenerate the +fingerprint: + +```bash +prek run compile-fab-assets --all-files +``` + +This runs `scripts/ci/prek/compile_provider_assets.py fab` (pnpm build over +`www/`) and rewrites `providers/fab/www-hash.txt`. A patch bump usually does +**not** touch assets — skip this step unless FAB's templates/static changed. +Commit the regenerated `www-hash.txt` if it changed. + +### Step 7 — DB migrations (only if FAB ships them) + +If the new FAB adds/changes security-model tables, add the corresponding +migration under `providers/fab/src/airflow/providers/fab/migrations/versions/` +and run: + +```bash +prek run update-migration-references-fab check-revision-heads-map-fab --all-files +``` + +Patch bumps normally have no migrations — skip unless the release notes mention +schema changes. + +### Step 8 — Static checks + tests + +```bash +prek run --from-ref main --stage pre-commit +uv run --project providers/fab pytest providers/fab/tests/unit/fab/auth_manager -xvs +``` + +The pre-commit stage runs `sync-provider-readme` (regenerating `README.rst`) and +other FAB hooks. Re-run the alignment test until all four tests pass. The full +provider suite is `breeze testing providers-tests --test-type "Providers[fab]"`. + +### Step 9 — Self-review and commit + +- `git diff main...HEAD` — verify only the intended files changed, and `uv.lock` + is a clean FAB-scoped diff. +- Commit subject in imperative mood, plain prose, **no** Conventional-Commits + prefix, e.g. `Bump flask-appbuilder to X.Y.Z in FAB provider`. Body explains + *why* (what upstream changes were mirrored), not what. +- No newsfragment, no changelog edit (provider release manager regenerates from + git log). +- Prepend your PR to the history list in `providers/fab/CONTRIBUTING.rst` so the + FAB-upgrade record stays current. +- Push to `origin` and open the PR per the repo's PR conventions. + +## Gotchas + +- **`EXPECTED_FAB_VERSION` is a second pin.** Forgetting it makes + `test_fab_alignment.py` fail even when everything else is correct. +- **`uv.lock` marker drift.** Always use the pinned uv (Step 4) — a bare + `uv lock` rewrites hundreds of environment-marker lines and buries the real diff. +- **The alignment test uses AST, not import**, to read FAB's `SecurityManager` + (to avoid SQLAlchemy model-registry collisions with Airflow's vendored models). + A green test proves *structural* alignment; it does **not** prove behavioural + parity — Step 5's manual transplant review is still required. +- **`docs/index.rst` dependency table** may look auto-generated but the reference + PR edited it by hand; if a docs-regen prek hook rewrites it, let the hook win. +- **`README.rst` is generated, but the sync hook is per-commit.** Don't hand-edit + it; run `prek run sync-provider-readme` (or the full pre-commit stage) after + bumping `pyproject.toml` — CI fails on the drift otherwise. +- **Don't touch `providers/fab/docs/upgrading.rst`** — that is end-user guidance + for upgrading the *provider package* in a deployment, not the developer bump + workflow. + +## Worked example — 5.2.1 to 5.2.2 (patch) + +A patch bump that needed **no `override.py` change**, but only after a real +behavioural review — the green alignment test alone was not sufficient evidence: + +- FAB 5.2.2 shipped three security-manager fixes: LDAP search-filter escaping, + OAuth email-allowlist regex anchoring (`email + "$"`), and API-login provider + validation. +- All three touch methods Airflow *vendors* (`_search_ldap`, `auth_user_ldap`, + `auth_user_oauth`) — so the alignment test passing did **not** mean "nothing to + do". Each had to be checked by hand: + - **LDAP escaping** — Airflow's vendored `_search_ldap` **already** escapes via + `ldap.filter.escape_filter_chars` (and adds filter-parenthesis validation); it + was ahead of FAB. No transplant. + - **OAuth allowlist anchoring** — the match lives in FAB's `AuthOAuthView` + (`views.py`), and Airflow's `CustomAuthOAuthView.oauth_authorized` delegates + via `super().oauth_authorized()`, so the fix is inherited from the installed + FAB 5.2.2. No transplant. + - **API-login validation / Azure-JWT warning / uuid4** — in FAB core Airflow + doesn't vendor. Inherited. +- Net change set: `pyproject.toml`, `test_fab_alignment.py`, `docs/index.rst`, + `README.rst` (via hook), `uv.lock`. Commit: `Bump flask-appbuilder to 5.2.2 in + FAB provider`. + +The lesson the skill encodes: **for every security/behavioural fix in the FAB +release notes, locate the method and check whether Airflow vendors it** — the +alignment test guards structure, you guard behaviour. diff --git a/.apache-magpie-overrides/setup-isolated-setup-install.md b/.apache-magpie-overrides/setup-isolated-setup-install.md new file mode 100644 index 0000000000000..0874037043d0e --- /dev/null +++ b/.apache-magpie-overrides/setup-isolated-setup-install.md @@ -0,0 +1,81 @@ + + +# Override: setup-isolated-setup-install — seed the breeze permission baseline + +## What this overrides + +Augments the **settings merge** the `setup-isolated-setup-install` skill +performs (its "Golden rules → Do not overwrite an existing settings file +silently" desired-merge, and the project-local settings write in **Step P**). +When wiring the isolated / secure agent setup for this repo, add the +project-specific Bash permission allow-list below to the adopter's +**project-local** settings file (`/.claude/settings.local.json`) — +merged alongside the sandbox `allowRead` / `allowWrite` entries Step P already +writes there, surfaced in the same diff, and applied with the same approval. + +This seeds a per-machine baseline at install time; it does **not** introduce a +committed project-scope `.claude/settings.json` (that path stays gitignored in +this repo). + +## Permissions to add + +Add each of these to `permissions.allow` (create the key if absent). Never +remove or reorder pre-existing entries — this is an additive merge, and an +entry already present is a no-op: + +```text +Bash(breeze *) +Bash(ANSWER=yes breeze *) +Bash(SKIP_BREEZE_SELF_UPGRADE_CHECK=1 breeze *) +Bash(SKIP_BREEZE_SELF_UPGRADE_CHECK=true breeze *) +Bash(SKIP_BREEZE_SELF_UPGRADE_CHECK= breeze *) +Bash(uvx *dev/breeze*) +Bash(uv run *dev/breeze*) +Bash(docker ps *) +Bash(docker info *) +``` + +## Why + +`breeze` is the mandated entrypoint for all local development in Apache +Airflow — the contributor instructions forbid running `pytest` / `python` / +`airflow` directly on the host (see this repo's `AGENTS.md` / `CLAUDE.md`). +Without these allows, every breeze invocation prompts for Bash permission, +which is pure friction for a command contributors run constantly. + +- The `uvx` / `uv run *dev/breeze*` forms cover the breeze shim that runs + breeze from `dev/breeze` (see [ADR 0017](../dev/breeze/doc/adr/0017-use-uvx-to-run-breeze-from-local-sources.md)). +- The env-prefixed forms cover the common `ANSWER=yes` and + `SKIP_BREEZE_SELF_UPGRADE_CHECK` wrappers used throughout the dev/CI scripts. + +Only **non-destructive** commands are allowed: breeze itself (which drives +docker internally, so its docker usage is covered by the single breeze call) +plus read-only `docker ps` / `docker info`. No `docker rm`, no +`docker network prune`, nothing that writes outside the breeze workflow — +those stay prompt-gated. + +## Scope notes + +- These land in the gitignored, per-machine `.claude/settings.local.json`, + applied when a contributor sets up the isolated build — there is no shared + committed settings file to review or maintain. +- A contributor's own additional per-machine allows live in the same + `settings.local.json`; this override only seeds the breeze baseline and + leaves everything else untouched. diff --git a/.claude/skills/upgrade-fab-provider b/.claude/skills/upgrade-fab-provider new file mode 120000 index 0000000000000..d7c96f92a70e3 --- /dev/null +++ b/.claude/skills/upgrade-fab-provider @@ -0,0 +1 @@ +../../.agents/skills/upgrade-fab-provider \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 19a4483ab598f..3f8a8bbc004a8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -94,7 +94,7 @@ airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/ @Lee-W @jason810496 @guan /providers/common/messaging/ @vincbeck /providers/common/ai/ @gopidesupavan @kaxil /providers/dbt/cloud/ @josh-fell -/providers/edge3/ @jscheffl @dheerajturaga +/providers/edge3/ @jscheffl @dheerajturaga @shubhamraj-git /providers/fab/ @vincbeck /providers/google/ @shahar1 /providers/hashicorp/ @hussein-awala @@ -114,11 +114,11 @@ airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/ @Lee-W @jason810496 @guan /generated/provider_metadata.json @potiuk @eladkal @shahar1 @vincbeck @jscheffl # Provider Registry -/registry/ @kaxil -/dev/registry/ @kaxil -/dev/breeze/src/airflow_breeze/commands/registry_commands*.py @kaxil -/dev/breeze/src/airflow_breeze/utils/publish_registry_versions.py @kaxil -/dev/breeze/tests/test_publish_registry_versions.py @kaxil +/registry/ @kaxil @amoghrajesh +/dev/registry/ @kaxil @amoghrajesh +/dev/breeze/src/airflow_breeze/commands/registry_commands*.py @kaxil @amoghrajesh +/dev/breeze/src/airflow_breeze/utils/publish_registry_versions.py @kaxil @amoghrajesh +/dev/breeze/tests/test_publish_registry_versions.py @kaxil @amoghrajesh # Dev tools /.github/workflows/ @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @jason810496 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7ea505eb178e7..fd2d2832e3883 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -5,7 +5,7 @@ Thank you for contributing! Please provide above a brief description of the changes made in this pull request. -Write a good git commit message following this guide: http://chris.beams.io/posts/git-commit/ +Write a good git commit message following this guide: https://chris.beams.io/posts/git-commit/ Please make sure that your code changes are covered with tests. And in case of new features or big changes remember to adjust the documentation. diff --git a/.github/actions/post_tests_failure/action.yml b/.github/actions/post_tests_failure/action.yml index e6bbf03ad9416..275339a54457a 100644 --- a/.github/actions/post_tests_failure/action.yml +++ b/.github/actions/post_tests_failure/action.yml @@ -22,21 +22,21 @@ runs: using: "composite" steps: - name: "Upload airflow logs" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: airflow-logs-${{env.JOB_ID}} path: './files/airflow_logs*' retention-days: 7 if-no-files-found: ignore - name: "Upload container logs" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: container-logs-${{env.JOB_ID}} path: "./files/container_logs*" retention-days: 7 if-no-files-found: ignore - name: "Upload other logs" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: container-logs-${{env.JOB_ID}} path: "./files/other_logs*" diff --git a/.github/actions/post_tests_success/action.yml b/.github/actions/post_tests_success/action.yml index 7298fadaf7cb5..4c41a9331ecb9 100644 --- a/.github/actions/post_tests_success/action.yml +++ b/.github/actions/post_tests_success/action.yml @@ -31,7 +31,7 @@ runs: using: "composite" steps: - name: "Upload artifact for warnings" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-warnings-${{ env.JOB_ID }} path: ./files/warnings-*.txt diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml index f83c78cb39ee2..249d81e0667ae 100644 --- a/.github/boring-cyborg.yml +++ b/.github/boring-cyborg.yml @@ -554,6 +554,15 @@ labelPRBasedOnFilePath: area:go-sdk: - go-sdk/**/* + area:java-sdk: + - java-sdk/**/* + + "AIP-108: Coordinator": + - task-sdk/src/airflow/sdk/coordinators/**/* + - task-sdk/src/airflow/sdk/execution_time/coordinator.py + - task-sdk/tests/task_sdk/coordinators/**/* + - task-sdk/tests/task_sdk/execution_time/test_coordinator.py + area:db-migrations: - airflow-core/src/airflow/migrations/versions/* @@ -578,6 +587,9 @@ labelPRBasedOnFilePath: area:docker-tests: - docker-tests/**/* + area:e2e-tests: + - airflow-e2e-tests/**/* + area:kubernetes-tests: - kubernetes-tests/**/* diff --git a/.github/skills/upgrade-fab-provider b/.github/skills/upgrade-fab-provider new file mode 120000 index 0000000000000..d7c96f92a70e3 --- /dev/null +++ b/.github/skills/upgrade-fab-provider @@ -0,0 +1 @@ +../../.agents/skills/upgrade-fab-provider \ No newline at end of file diff --git a/.github/workflows/additional-ci-image-checks.yml b/.github/workflows/additional-ci-image-checks.yml index f66a6627917b0..42b71e1f32bb4 100644 --- a/.github/workflows/additional-ci-image-checks.yml +++ b/.github/workflows/additional-ci-image-checks.yml @@ -28,18 +28,10 @@ on: # yamllint disable-line rule:truthy description: "Platform for the build - 'linux/amd64' or 'linux/arm64'" required: true type: string - python-versions: - description: "The list of python versions (stringified JSON array) to run the tests on." - required: true - type: string branch: description: "Branch used to run the CI jobs in (main/v*_*_test)." required: true type: string - constraints-branch: - description: "Branch used to get constraints from" - required: true - type: string default-python-version: description: "Which version of python should be used by default" required: true @@ -52,72 +44,19 @@ on: # yamllint disable-line rule:truthy description: "Whether to skip prek hooks (true/false)" required: true type: string - docker-cache: - description: "Docker cache specification to build the image (registry, local, disabled)." - required: true - type: string - disable-airflow-repo-cache: - description: "Disable airflow repo cache read from main." - required: true - type: string - canary-run: - description: "Whether this is a canary run (true/false)" - required: true - type: string latest-versions-only: description: "Whether to run only latest versions (true/false)" required: true type: string - include-success-outputs: - description: "Whether to include success outputs (true/false)" - required: true - type: string debug-resources: description: "Whether to debug resources (true/false)" required: true type: string - use-uv: - description: "Whether to use uv to build the image (true/false)" - required: true - type: string permissions: contents: read jobs: - # Push early BuildX cache to GitHub Registry in Apache repository, This cache does not wait for all the - # tests to complete - it is run very early in the build process for "main" merges in order to refresh - # cache using the current constraints. This will speed up cache refresh in cases when pyproject.toml - # changes or in case of Dockerfile changes. Failure in this step is not a problem (at most it will - # delay cache refresh. It does not attempt to upgrade to newer dependencies. - # We only push CI cache as PROD cache usually does not gain as much from fresh cache because - # it uses prepared airflow and provider distributions that invalidate the cache anyway most of the time - push-early-buildx-cache-to-github-registry: - name: Push Early Image Cache - uses: ./.github/workflows/push-image-cache.yml - permissions: - contents: read - # This write is only given here for `push` events from "apache/airflow" repo. It is not given for PRs - # from forks. This is to prevent malicious PRs from creating images in the "apache/airflow" repo. - packages: write - with: - runners: ${{ inputs.runners }} - cache-type: "Early" - include-prod-images: "false" - push-latest-images: "false" - platform: ${{ inputs.platform }} - python-versions: ${{ inputs.python-versions }} - branch: ${{ inputs.branch }} - constraints-branch: ${{ inputs.constraints-branch }} - use-uv: ${{ inputs.use-uv }} - include-success-outputs: ${{ inputs.include-success-outputs }} - docker-cache: ${{ inputs.docker-cache }} - disable-airflow-repo-cache: ${{ inputs.disable-airflow-repo-cache }} - if: > - inputs.canary-run == 'true' && - (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') - - # Check that after earlier cache push, breeze command will build quickly - # This build is a bit slow from in-the scratch builds, so we should run it only in - # regular PRs + # Check that the image builds quickly from the registry cache. This build is slow from + # scratch, so we only run it on regular PRs. check-that-image-builds-quickly: timeout-minutes: 25 name: Check that image builds quickly @@ -137,7 +76,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/additional-prod-image-tests.yml b/.github/workflows/additional-prod-image-tests.yml index bfb21345c4d20..bc9bf65a171be 100644 --- a/.github/workflows/additional-prod-image-tests.yml +++ b/.github/workflows/additional-prod-image-tests.yml @@ -143,7 +143,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -181,7 +181,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -212,7 +212,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -372,7 +372,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false diff --git a/.github/workflows/airflow-distributions-tests.yml b/.github/workflows/airflow-distributions-tests.yml index d6eb98fddbae3..0c24ff8cdc3e4 100644 --- a/.github/workflows/airflow-distributions-tests.yml +++ b/.github/workflows/airflow-distributions-tests.yml @@ -90,7 +90,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ matrix.python-version }}" diff --git a/.github/workflows/airflow-e2e-tests.yml b/.github/workflows/airflow-e2e-tests.yml index 3a87ea525f7b5..143d54edf4d48 100644 --- a/.github/workflows/airflow-e2e-tests.yml +++ b/.github/workflows/airflow-e2e-tests.yml @@ -100,7 +100,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false diff --git a/.github/workflows/asf-allowlist-check.yml b/.github/workflows/asf-allowlist-check.yml index 7a1d0b4d56f80..0c9d8697ac553 100644 --- a/.github/workflows/asf-allowlist-check.yml +++ b/.github/workflows/asf-allowlist-check.yml @@ -28,7 +28,7 @@ jobs: asf-allowlist-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: apache/infrastructure-actions/allowlist-check@4e9c961f587f72b170874b6f5cd4ac15f7f26eb8 # main + - uses: apache/infrastructure-actions/allowlist-check@0ff9972b5872e19c9f4555c9159c2fea4f794355 # main diff --git a/.github/workflows/backport-cli.yml b/.github/workflows/backport-cli.yml index 46fbe0cae6f57..504fa82b2a773 100644 --- a/.github/workflows/backport-cli.yml +++ b/.github/workflows/backport-cli.yml @@ -53,7 +53,7 @@ jobs: steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" id: checkout-for-backport - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: true fetch-depth: 0 diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 714aef1139ca4..f7967ef1a7142 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -87,7 +87,7 @@ jobs: - name: "Cleanup repo" shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Need to fetch all history for selective checks tests fetch-depth: 0 @@ -106,7 +106,7 @@ jobs: - name: "Cleanup repo" shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false @@ -115,7 +115,7 @@ jobs: - name: "Install SVN" run: sudo apt-get update && sudo apt-get install -y subversion - name: "Install Java (for Apache RAT)" - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: distribution: 'temurin' java-version: '17' @@ -134,7 +134,7 @@ jobs: runs-on: ${{ fromJSON(inputs.runners) }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 persist-credentials: false @@ -159,7 +159,7 @@ jobs: if: inputs.run-scripts-tests == 'true' steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 persist-credentials: false @@ -188,7 +188,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup pnpm @@ -197,13 +197,13 @@ jobs: version: 9 run_install: false - name: "Setup node" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 cache: 'pnpm' cache-dependency-path: 'airflow-core/src/airflow/**/pnpm-lock.yaml' - name: "Restore eslint cache (ui)" - uses: apache/infrastructure-actions/stash/restore@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/restore@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: airflow-core/src/airflow/ui/node_modules/ # yamllint disable-line rule:line-length @@ -214,7 +214,7 @@ jobs: env: FORCE_COLOR: 2 - name: "Save eslint cache (ui)" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: airflow-core/src/airflow/ui/node_modules/ key: cache-ui-node-modules-v1-${{ runner.os }}-${{ hashFiles('airflow/ui/**/pnpm-lock.yaml') }} @@ -222,7 +222,7 @@ jobs: retention-days: '2' if: steps.restore-eslint-cache-ui.outputs.stash-hit != 'true' - name: "Restore eslint cache (simple auth manager UI)" - uses: apache/infrastructure-actions/stash/restore@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/restore@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/node_modules/ key: > @@ -234,7 +234,7 @@ jobs: env: FORCE_COLOR: 2 - name: "Save eslint cache (ui)" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/node_modules/ key: > @@ -250,7 +250,7 @@ jobs: runs-on: ${{ fromJSON(inputs.runners) }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -271,7 +271,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -285,7 +285,7 @@ jobs: platform: ${{ inputs.platform }} save-cache: true - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -306,7 +306,7 @@ jobs: runs-on: ["windows-2025"] steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -327,7 +327,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -374,7 +374,7 @@ jobs: FORCE_COLOR: 1 steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install uv" diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml index a1e07e1f16c15..f8dca261ed466 100644 --- a/.github/workflows/ci-amd.yml +++ b/.github/workflows/ci-amd.yml @@ -99,6 +99,7 @@ jobs: include-success-outputs: ${{ steps.selective-checks.outputs.include-success-outputs }} individual-providers-test-types-list-as-strings-in-json: >- ${{ steps.selective-checks.outputs.individual-providers-test-types-list-as-strings-in-json }} + java-sdk-version: ${{ steps.selective-checks.outputs.java-sdk-version }} kubernetes-combos: ${{ steps.selective-checks.outputs.kubernetes-combos }} kubernetes-combos-list-as-string: >- ${{ steps.selective-checks.outputs.kubernetes-combos-list-as-string }} @@ -166,11 +167,11 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -284,19 +285,12 @@ jobs: with: runners: ${{ needs.build-info.outputs.runner-type }} platform: ${{ needs.build-info.outputs.platform }} - python-versions: ${{ needs.build-info.outputs.python-versions }} branch: ${{ needs.build-info.outputs.default-branch }} - constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} default-python-version: "${{ needs.build-info.outputs.default-python-version }}" upgrade-to-newer-dependencies: ${{ needs.build-info.outputs.upgrade-to-newer-dependencies }} skip-prek-hooks: ${{ needs.build-info.outputs.skip-prek-hooks }} - docker-cache: ${{ needs.build-info.outputs.docker-cache }} - disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} - canary-run: ${{ needs.build-info.outputs.canary-run }} latest-versions-only: ${{ needs.build-info.outputs.latest-versions-only }} - include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} - use-uv: ${{ needs.build-info.outputs.use-uv }} generate-constraints: name: "Generate constraints" @@ -314,6 +308,8 @@ jobs: generate-no-providers-constraints: ${{ needs.build-info.outputs.canary-run }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} use-uv: ${{ needs.build-info.outputs.use-uv }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} ci-image-checks: name: "CI image checks" @@ -363,7 +359,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ needs.build-info.outputs.default-python-version }}" @@ -405,7 +401,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ needs.build-info.outputs.default-python-version }}" @@ -898,6 +894,9 @@ jobs: use-uv: ${{ needs.build-info.outputs.use-uv }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} kubernetes-combos: ${{ needs.build-info.outputs.kubernetes-combos }} + java-sdk-version: ${{ needs.build-info.outputs.java-sdk-version }} + lang-sdk-kubernetes-combo: >- + ${{ needs.build-info.outputs.default-python-version }}-${{ needs.build-info.outputs.default-kubernetes-version }} if: > ( needs.build-info.outputs.run-kubernetes-tests == 'true' || needs.build-info.outputs.run-helm-tests == 'true') @@ -940,14 +939,14 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # keep this in sync with go.mod in go-sdk/ - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: 1.24 + go-version: 1.25 cache-dependency-path: go-sdk/go.sum # keep this in sync with go.mod in go-sdk/ - name: Setup Gotestsum @@ -977,11 +976,11 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup Java - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} @@ -1007,7 +1006,7 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -1110,7 +1109,7 @@ jobs: runs-on: ["ubuntu-22.04"] steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Get failing jobs" @@ -1151,7 +1150,7 @@ jobs: overwrite: true - name: "Notify Slack (new/changed failures)" if: steps.notification.outputs.action == 'notify_new' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1167,7 +1166,7 @@ jobs: # yamllint enable rule:line-length - name: "Notify Slack (still not fixed)" if: steps.notification.outputs.action == 'notify_reminder' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1183,7 +1182,7 @@ jobs: # yamllint enable rule:line-length - name: "Notify Slack (all tests passing)" if: steps.notification.outputs.action == 'notify_recovery' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1223,7 +1222,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Free up disk space" @@ -1235,7 +1234,7 @@ jobs: path: ./artifacts pattern: test-warnings-* - name: "Setup python" - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "${{ inputs.default-python-version }}" - name: "Summarize all warnings" diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml index 71847cc44b5c7..acb7cd8f4565a 100644 --- a/.github/workflows/ci-arm.yml +++ b/.github/workflows/ci-arm.yml @@ -92,6 +92,7 @@ jobs: include-success-outputs: ${{ steps.selective-checks.outputs.include-success-outputs }} individual-providers-test-types-list-as-strings-in-json: >- ${{ steps.selective-checks.outputs.individual-providers-test-types-list-as-strings-in-json }} + java-sdk-version: ${{ steps.selective-checks.outputs.java-sdk-version }} kubernetes-combos: ${{ steps.selective-checks.outputs.kubernetes-combos }} kubernetes-combos-list-as-string: >- ${{ steps.selective-checks.outputs.kubernetes-combos-list-as-string }} @@ -159,11 +160,11 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -277,19 +278,12 @@ jobs: with: runners: ${{ needs.build-info.outputs.runner-type }} platform: ${{ needs.build-info.outputs.platform }} - python-versions: ${{ needs.build-info.outputs.python-versions }} branch: ${{ needs.build-info.outputs.default-branch }} - constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} default-python-version: "${{ needs.build-info.outputs.default-python-version }}" upgrade-to-newer-dependencies: ${{ needs.build-info.outputs.upgrade-to-newer-dependencies }} skip-prek-hooks: ${{ needs.build-info.outputs.skip-prek-hooks }} - docker-cache: ${{ needs.build-info.outputs.docker-cache }} - disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} - canary-run: ${{ needs.build-info.outputs.canary-run }} latest-versions-only: ${{ needs.build-info.outputs.latest-versions-only }} - include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} - use-uv: ${{ needs.build-info.outputs.use-uv }} generate-constraints: name: "Generate constraints" @@ -307,6 +301,8 @@ jobs: generate-no-providers-constraints: ${{ needs.build-info.outputs.canary-run }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} use-uv: ${{ needs.build-info.outputs.use-uv }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} ci-image-checks: name: "CI image checks" @@ -356,7 +352,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ needs.build-info.outputs.default-python-version }}" @@ -398,7 +394,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ needs.build-info.outputs.default-python-version }}" @@ -891,6 +887,9 @@ jobs: use-uv: ${{ needs.build-info.outputs.use-uv }} debug-resources: ${{ needs.build-info.outputs.debug-resources }} kubernetes-combos: ${{ needs.build-info.outputs.kubernetes-combos }} + java-sdk-version: ${{ needs.build-info.outputs.java-sdk-version }} + lang-sdk-kubernetes-combo: >- + ${{ needs.build-info.outputs.default-python-version }}-${{ needs.build-info.outputs.default-kubernetes-version }} if: > ( needs.build-info.outputs.run-kubernetes-tests == 'true' || needs.build-info.outputs.run-helm-tests == 'true') @@ -933,14 +932,14 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # keep this in sync with go.mod in go-sdk/ - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: - go-version: 1.24 + go-version: 1.25 cache-dependency-path: go-sdk/go.sum # keep this in sync with go.mod in go-sdk/ - name: Setup Gotestsum @@ -970,11 +969,11 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup Java - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} @@ -1000,7 +999,7 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -1103,7 +1102,7 @@ jobs: runs-on: ["ubuntu-22.04"] steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Get failing jobs" @@ -1144,7 +1143,7 @@ jobs: overwrite: true - name: "Notify Slack (new/changed failures)" if: steps.notification.outputs.action == 'notify_new' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1160,7 +1159,7 @@ jobs: # yamllint enable rule:line-length - name: "Notify Slack (still not fixed)" if: steps.notification.outputs.action == 'notify_reminder' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1176,7 +1175,7 @@ jobs: # yamllint enable rule:line-length - name: "Notify Slack (all tests passing)" if: steps.notification.outputs.action == 'notify_recovery' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -1216,7 +1215,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Free up disk space" @@ -1228,7 +1227,7 @@ jobs: path: ./artifacts pattern: test-warnings-* - name: "Setup python" - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "${{ inputs.default-python-version }}" - name: "Summarize all warnings" diff --git a/.github/workflows/ci-duration-monitor.yml b/.github/workflows/ci-duration-monitor.yml index 2f3e1398d29ab..4e878002dd49c 100644 --- a/.github/workflows/ci-duration-monitor.yml +++ b/.github/workflows/ci-duration-monitor.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -49,12 +49,25 @@ jobs: # main coverage comes from the scheduled canary runs of the AMD workflow. WORKFLOW_NAME: "ci-amd.yml" BRANCH: "main" + # Only successful (green) canary runs feed the baseline — a failed or cancelled + # canary stops partway, so its truncated wall-clock and per-job durations would + # skew the trend downwards and mask real regressions. Set explicitly so the + # green-only guarantee is visible at the call site and can't be silently changed. + ONLY_SUCCESSFUL: "true" MAX_RUNS: "25" + # Compare the median of the last few nightly runs (not a single run) against the + # baseline so one unlucky run — slow PyPI, runner queue pressure, cold cache — does + # not trip the alert. With LATEST_RUNS=1 both sides were asymmetric (raw point vs + # median) and the alert fired most nights on whichever jobs happened to be slow. + LATEST_RUNS: "3" + # Network-bound jobs (constraint resolution, provider installs) legitimately swing + # tens of minutes run-to-run; require a larger sustained jump before flagging them. + JOB_MIN_ABS_INCREASE_MINUTES: "6" OUTPUT_FILE: "slack-message.json" - name: "Post duration alert to Slack" if: steps.analyze.outputs.has-regression == 'true' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/ci-image-build.yml b/.github/workflows/ci-image-build.yml index 7f1fa61fe609e..3f3bd77c265ad 100644 --- a/.github/workflows/ci-image-build.yml +++ b/.github/workflows/ci-image-build.yml @@ -29,6 +29,11 @@ on: # yamllint disable-line rule:truthy required: false default: "" type: string + checkout-ref: + description: "Commit-ish to checkout sources from (empty = workflow ref)." + required: false + default: "" + type: string pull-request-target: description: "Whether we are running this from pull-request-target workflow (true/false)" required: false @@ -118,8 +123,9 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout target branch" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + ref: ${{ inputs.checkout-ref }} persist-credentials: false - name: "Free up disk space" shell: bash @@ -131,7 +137,7 @@ jobs: - name: "Install Breeze" uses: ./.github/actions/breeze - name: "Restore ci-cache mount image ${{ inputs.platform }}:${{ env.PYTHON_MAJOR_MINOR_VERSION }}" - uses: apache/infrastructure-actions/stash/restore@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/restore@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: key: "ci-cache-mount-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}" path: "/tmp/" @@ -188,7 +194,7 @@ jobs: run: breeze ci-image save --platform "${PLATFORM}" --image-file-dir "/mnt" if: inputs.upload-image-artifact == 'true' - name: "Stash CI docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: key: ci-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }} path: "/mnt/ci-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar" @@ -203,7 +209,7 @@ jobs: --cache-file /tmp/ci-cache-mount-save-v3-${PYTHON_MAJOR_MINOR_VERSION}.tar.gz if: inputs.upload-mount-cache-artifact == 'true' - name: "Stash cache mount ${{ inputs.platform }}:${{ env.PYTHON_MAJOR_MINOR_VERSION }}" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: key: "ci-cache-mount-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}" path: "/tmp/ci-cache-mount-save-v3-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar.gz" diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index 5eba03f950cae..fa5038ceffa41 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -130,7 +130,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -183,7 +183,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -194,7 +194,7 @@ jobs: use-uv: ${{ inputs.use-uv }} make-mnt-writeable-and-cleanup: true - name: "Restore docs inventory cache" - uses: apache/infrastructure-actions/stash/restore@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/restore@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: ./generated/_inventory_cache/ key: cache-docs-inventory-v1 @@ -266,7 +266,7 @@ jobs: inputs.canary-run == 'true' && matrix.flag == '--docs-only' && steps.inventory-notification.outputs.action == 'notify_new' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -282,7 +282,7 @@ jobs: inputs.canary-run == 'true' && matrix.flag == '--docs-only' && steps.inventory-notification.outputs.action == 'notify_reminder' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -298,7 +298,7 @@ jobs: inputs.canary-run == 'true' && matrix.flag == '--docs-only' && steps.inventory-notification.outputs.action == 'notify_recovery' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -310,7 +310,7 @@ jobs: env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - name: "Save docs inventory cache" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: ./generated/_inventory_cache/ key: cache-docs-inventory-v1 @@ -351,7 +351,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -441,7 +441,7 @@ jobs: inputs.canary-run == 'true' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} @@ -476,12 +476,12 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: "apache/airflow-client-python" fetch-depth: 1 diff --git a/.github/workflows/ci-notification.yml b/.github/workflows/ci-notification.yml index c896a94a937b8..169b8fb3cff24 100644 --- a/.github/workflows/ci-notification.yml +++ b/.github/workflows/ci-notification.yml @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -79,7 +79,7 @@ jobs: - name: "Send Slack notification (new/changed failures)" if: steps.notification.outputs.action == 'notify_new' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -100,7 +100,7 @@ jobs: - name: "Send Slack notification (still not fixed)" if: steps.notification.outputs.action == 'notify_reminder' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -121,7 +121,7 @@ jobs: - name: "Send Slack notification (all passing)" if: steps.notification.outputs.action == 'notify_recovery' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 20dbac2c97e7d..df4e84924db2b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -110,25 +110,25 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup Java if: matrix.language == 'java' - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: distribution: 'temurin' java-version: '11' - name: Initialize CodeQL - uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: languages: ${{ matrix.language }} - name: Autobuild if: matrix.language != 'java' - uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/autobuild@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 - name: Build Java SDK if: matrix.language == 'java' @@ -136,7 +136,7 @@ jobs: run: ./gradlew classes testClasses - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: # Provide more context to the SARIF output (shows up in run.automationDetails.id field) category: "/language:${{matrix.language}}" diff --git a/.github/workflows/e2e-flaky-tests-report.yml b/.github/workflows/e2e-flaky-tests-report.yml index b4408985236ef..bc922671d4674 100644 --- a/.github/workflows/e2e-flaky-tests-report.yml +++ b/.github/workflows/e2e-flaky-tests-report.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -55,7 +55,7 @@ jobs: - name: "Post report to Slack" if: always() && steps.analyze.outcome == 'success' - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/finalize-tests.yml b/.github/workflows/finalize-tests.yml index e03d6f35e98fe..8165c981cb863 100644 --- a/.github/workflows/finalize-tests.yml +++ b/.github/workflows/finalize-tests.yml @@ -99,7 +99,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Needed to perform push action persist-credentials: false @@ -107,7 +107,7 @@ jobs: id: constraints-branch run: ./scripts/ci/constraints/ci_branch_constraints.sh >> ${GITHUB_OUTPUT} - name: Checkout ${{ steps.constraints-branch.outputs.branch }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: path: "constraints" ref: ${{ steps.constraints-branch.outputs.branch }} @@ -139,7 +139,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ matrix.python-version }}" diff --git a/.github/workflows/generate-constraints.yml b/.github/workflows/generate-constraints.yml index 55604039f7734..f8ff59109e94b 100644 --- a/.github/workflows/generate-constraints.yml +++ b/.github/workflows/generate-constraints.yml @@ -44,6 +44,24 @@ on: # yamllint disable-line rule:truthy description: "Whether to generate PyPI constraints (true/false)" required: true type: string + allow-pre-releases: + description: > + Whether the PyPI constraints may pin pre-release providers (true/false). Set when + constraints are cut for a release candidate, whose providers are on PyPI only as rc + versions. Scoped to apache-airflow-providers-* - no other package can resolve to a + pre-release. + required: false + default: "false" + type: string + pypi-providers-only: + description: > + Resolve against providers exactly as published on PyPI (true/false). Skips building the + provider distributions from sources and the source-providers constraints with them, so + nothing local can answer for a provider. Set when the constraints being produced are the + ones a release ships - see the comments on the steps this disables. + required: false + default: "false" + type: string debug-resources: description: "Whether to run in debug mode (true/false)" required: true @@ -52,6 +70,15 @@ on: # yamllint disable-line rule:truthy description: "Whether to use uvloop (true/false)" required: true type: string + checkout-ref: + description: "Commit-ish to checkout sources from (empty = workflow ref)." + required: false + default: "" + type: string + secrets: + SLACK_BOT_TOKEN: + description: "Slack bot token used to post provider-downgrade alerts (optional)." + required: false jobs: generate-constraints-matrix: permissions: @@ -76,9 +103,10 @@ jobs: - name: "Cleanup repo" shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: "Checkout ${{ inputs.checkout-ref || github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + ref: ${{ inputs.checkout-ref }} persist-credentials: false - name: "Install prek" uses: ./.github/actions/install-prek @@ -94,12 +122,15 @@ jobs: python: ${{ matrix.python-version }} use-uv: ${{ inputs.use-uv }} make-mnt-writeable-and-cleanup: true + # Resolves the providers from the sources in this checkout. Skipped for a release, which + # ships only the PyPI constraints and must not have a source tree answer for a provider. - name: "Source constraints" shell: bash run: > breeze release-management generate-constraints --airflow-constraints-mode constraints-source-providers --answer yes --python "${PYTHON_VERSION}" + if: inputs.pypi-providers-only != 'true' - name: "No providers constraints" shell: bash timeout-minutes: 25 @@ -108,12 +139,16 @@ jobs: --airflow-constraints-mode constraints-no-providers --answer yes --python "${PYTHON_VERSION}" if: inputs.generate-no-providers-constraints == 'true' + # Builds the providers from sources into the dist directory the PyPI resolution reads through + # `--find-links`, so a locally built wheel can answer for a provider and is then excluded from + # the constraints. That is wanted while developing a provider that is not on PyPI yet; it is the + # opposite of what a release wants, which is every provider pinned at its published version. - name: "Prepare updated provider distributions" shell: bash run: > breeze release-management prepare-provider-distributions --include-not-ready-providers --distribution-format wheel - if: inputs.generate-pypi-constraints == 'true' + if: inputs.generate-pypi-constraints == 'true' && inputs.pypi-providers-only != 'true' - name: "Prepare airflow distributions" shell: bash run: > @@ -127,10 +162,36 @@ jobs: - name: "PyPI constraints" shell: bash timeout-minutes: 25 + env: + # Deliberately not named ALLOW_PRE_RELEASES: that is the option's own envvar, and having + # both paths set it would make it unclear which one is in force. Empty on a normal run, + # so the unquoted expansion below contributes no argument at all. + PRE_RELEASE_FLAG: ${{ inputs.allow-pre-releases == 'true' && '--allow-pre-releases' || '' }} run: | breeze release-management generate-constraints --airflow-constraints-mode constraints \ - --answer yes --python "${PYTHON_VERSION}" + --answer yes --python "${PYTHON_VERSION}" ${PRE_RELEASE_FLAG} if: inputs.generate-pypi-constraints == 'true' + - name: "Check for provider downgrade alert" + id: downgrade-alert + if: always() && inputs.generate-pypi-constraints == 'true' + shell: bash + env: + PYTHON_VERSION: ${{ matrix.python-version }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + run: | + message_file="files/constraints-${PYTHON_VERSION}/provider-downgrade-slack-message.json" + if [[ -f "${message_file}" && -n "${SLACK_BOT_TOKEN}" ]]; then + echo "notify=true" >> "${GITHUB_OUTPUT}" + echo "message-file=${message_file}" >> "${GITHUB_OUTPUT}" + else + echo "notify=false" >> "${GITHUB_OUTPUT}" + fi + - name: "Post provider downgrade alert to Slack" + if: always() && steps.downgrade-alert.outputs.notify == 'true' + uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + with: + token: ${{ secrets.SLACK_BOT_TOKEN }} + payload-file-path: ${{ steps.downgrade-alert.outputs.message-file }} - name: "Upload constraint artifacts" uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: diff --git a/.github/workflows/helm-tests.yml b/.github/workflows/helm-tests.yml index 1f94a9a37fc56..01060f8fbfd47 100644 --- a/.github/workflows/helm-tests.yml +++ b/.github/workflows/helm-tests.yml @@ -76,7 +76,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -107,7 +107,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/integration-system-tests.yml b/.github/workflows/integration-system-tests.yml index 466de7b0d0c31..202d70cd9ef4b 100644 --- a/.github/workflows/integration-system-tests.yml +++ b/.github/workflows/integration-system-tests.yml @@ -98,7 +98,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -149,7 +149,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -194,7 +194,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" diff --git a/.github/workflows/k8s-tests.yml b/.github/workflows/k8s-tests.yml index 04f587edf9640..0a14493f07842 100644 --- a/.github/workflows/k8s-tests.yml +++ b/.github/workflows/k8s-tests.yml @@ -48,6 +48,14 @@ on: # yamllint disable-line rule:truthy description: "Whether to debug resources" required: true type: string + java-sdk-version: + description: "JDK version used to build the lang-SDK Java artifacts natively in CI" + required: true + type: string + lang-sdk-kubernetes-combo: + description: "Single Python-Kubernetes combo (-) for the dedicated lang-SDK job" + required: true + type: string permissions: contents: read jobs: @@ -81,7 +89,7 @@ jobs: echo "PYTHON_MAJOR_MINOR_VERSION=${KUBERNETES_COMBO}" | sed 's/-.*//' >> $GITHUB_ENV echo "KUBERNETES_VERSION=${KUBERNETES_COMBO}" | sed 's/=[^-]*-/=/' >> $GITHUB_ENV - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # env.PYTHON_MAJOR_MINOR_VERSION, env.KUBERNETES_VERSION are set in the previous @@ -96,6 +104,9 @@ jobs: make-mnt-writeable-and-cleanup: true id: breeze # preparing k8s environment with uv takes < 15 seconds with `uv` - there is no point in caching it. + # The lang-SDK coordinator system test is intentionally NOT run in this matrix. It has its own + # dedicated single-combo job (tests-kubernetes-lang-sdk below), so it no longer adds the ~6 minutes + # of Go/Java build + coordinator run to each of these system-test jobs. - name: "\ Run complete K8S tests ${{ matrix.executor }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}-\ ${{env.KUBERNETES_VERSION}}-${{ matrix.use-standard-naming }}" @@ -128,3 +139,110 @@ jobs: - name: "Delete clusters just in case they are left" run: breeze k8s delete-cluster --all if: always() + + # The Multi-Lang KubernetesExecutor coordinator system test builds a Go bundle and a Java jar and runs + # them as workers under KubernetesExecutor. It is executor/naming/version-independent, so instead of + # bolting it onto all six ``KubernetesExecutor``/``use-standard-naming == false`` system-test jobs above + # (which ran it redundantly and added ~6 minutes each), it runs once here on a single default combo and + # executes only the lang-SDK test (``-k test_lang_sdk_combined_dag_succeeds``) - not the full suite. + tests-kubernetes-lang-sdk: + timeout-minutes: 60 + name: "K8S Lang-SDK:${{ inputs.lang-sdk-kubernetes-combo }}" + runs-on: ${{ fromJSON(inputs.runners) }} + env: + DEBUG_RESOURCES: ${{ inputs.debug-resources }} + INCLUDE_SUCCESS_OUTPUTS: ${{ inputs.include-success-outputs }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_USERNAME: ${{ github.actor }} + VERBOSE: "true" + steps: + - name: "Cleanup repo" + shell: bash + run: sudo rm -rf ${GITHUB_WORKSPACE}/* + - name: "Prepare PYTHON_MAJOR_MINOR_VERSION and KUBERNETES_VERSION" + id: prepare-versions + env: + KUBERNETES_COMBO: ${{ inputs.lang-sdk-kubernetes-combo }} + run: | + echo "PYTHON_MAJOR_MINOR_VERSION=${KUBERNETES_COMBO}" | sed 's/-.*//' >> $GITHUB_ENV + echo "KUBERNETES_VERSION=${KUBERNETES_COMBO}" | sed 's/=[^-]*-/=/' >> $GITHUB_ENV + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + # env.PYTHON_MAJOR_MINOR_VERSION, env.KUBERNETES_VERSION are set in the previous + # step id: prepare-versions + - name: "Prepare breeze & PROD image: ${{ env.PYTHON_MAJOR_MINOR_VERSION }}" + uses: ./.github/actions/prepare_breeze_and_image + with: + platform: ${{ inputs.platform }} + image-type: "prod" + python: ${{ env.PYTHON_MAJOR_MINOR_VERSION }} + use-uv: ${{ inputs.use-uv }} + make-mnt-writeable-and-cleanup: true + id: breeze + # Provision the lang-SDK Go/Java toolchains on the host so breeze builds the artifacts natively + # (LANG_SDK_NATIVE_TOOLCHAIN=true) instead of in throwaway toolchain containers, skipping the image + # pulls and reusing the caches restored below. The module/build and Gradle caches are keyed + # explicitly (rather than via the setup-* built-in caching) so the key carries an ``-vN-`` salt: + # bump it to force-invalidate a poisoned cache without waiting for a dependency change to rotate it. + # keep go-version in sync with go-sdk/go.mod and the sibling Go SDK job in ci-amd.yml. + - name: "Setup Go for lang-SDK build" + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: 1.25 + cache: false + - name: "Cache lang-SDK Go module + build cache" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: lang-sdk-go-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('kubernetes-tests/lang_sdk/go_example/go.sum') }} # yamllint disable-line rule:line-length + restore-keys: | + lang-sdk-go-v1-${{ runner.os }}-${{ runner.arch }}- + - name: "Setup Java for lang-SDK build" + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 + with: + distribution: 'temurin' + java-version: ${{ inputs.java-sdk-version }} + - name: "Cache lang-SDK Gradle distribution + dependencies" + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: lang-sdk-gradle-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('java-sdk/**/*.gradle*', 'java-sdk/**/gradle-wrapper.properties', 'kubernetes-tests/lang_sdk/java_example/**/*.gradle*') }} # yamllint disable-line rule:line-length + restore-keys: | + lang-sdk-gradle-v1-${{ runner.os }}-${{ runner.arch }}- + # No --upgrade here: the redeploy/upgrade path is already exercised across the main matrix above; + # this job only needs a single deploy to validate the Multi-Lang coordinator, saving ~1.5 minutes. + - name: "Run lang-SDK K8S test ${{ inputs.lang-sdk-kubernetes-combo }}" + run: >- + breeze k8s run-complete-tests --no-copy-local-sources + -- -k test_lang_sdk_combined_dag_succeeds + env: + EXECUTOR: "KubernetesExecutor" + USE_STANDARD_NAMING: "false" + RUN_LANG_SDK_K8S_TESTS: "true" + LANG_SDK_NATIVE_TOOLCHAIN: "true" + VERBOSE: "false" + - name: "Print logs lang-sdk-${{ inputs.lang-sdk-kubernetes-combo }}" + run: | + for file in `find /tmp/kind_logs_*/ -type f` ; do + echo "::group::${file}" + cat $file + echo "::endgroup::" + done + if: failure() || cancelled() || inputs.include-success-outputs == 'true' + - name: "Upload KinD logs lang-sdk-${{ inputs.lang-sdk-kubernetes-combo }}" + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: "kind-logs-lang-sdk-${{ inputs.lang-sdk-kubernetes-combo }}" + path: /tmp/kind_logs_* + retention-days: '7' + if: failure() || cancelled() || inputs.include-success-outputs == 'true' + - name: "Delete clusters just in case they are left" + run: breeze k8s delete-cluster --all + if: always() diff --git a/.github/workflows/milestone-tag-assistant.yml b/.github/workflows/milestone-tag-assistant.yml index 27f7b2030f91e..3592bc5235c71 100644 --- a/.github/workflows/milestone-tag-assistant.yml +++ b/.github/workflows/milestone-tag-assistant.yml @@ -101,7 +101,7 @@ jobs: steps: - name: "Checkout repository" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Always checkout main to ensure Breeze with set-milestone command is available diff --git a/.github/workflows/notify-uv-lock-conflicts.yml b/.github/workflows/notify-uv-lock-conflicts.yml index b45ae572e5f8a..95dace0699680 100644 --- a/.github/workflows/notify-uv-lock-conflicts.yml +++ b/.github/workflows/notify-uv-lock-conflicts.yml @@ -33,7 +33,7 @@ jobs: timeout-minutes: 10 steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install uv" diff --git a/.github/workflows/prod-image-build.yml b/.github/workflows/prod-image-build.yml index a5a120ae127db..838b7f2eba975 100644 --- a/.github/workflows/prod-image-build.yml +++ b/.github/workflows/prod-image-build.yml @@ -125,7 +125,7 @@ jobs: run: sudo rm -rf ${GITHUB_WORKSPACE}/* if: inputs.upload-package-artifact == 'true' - name: "Checkout target branch" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Make /mnt writeable" @@ -220,7 +220,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout target branch" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Make /mnt writeable" @@ -284,7 +284,7 @@ jobs: breeze prod-image save --platform "${PLATFORM}" --image-file-dir "/mnt" if: inputs.upload-image-artifact == 'true' - name: "Stash PROD docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: key: prod-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }} path: "/mnt/prod-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar" diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index 739be11a17379..76c41adfed0b5 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -116,7 +116,7 @@ jobs: ]'), github.event.sender.login) steps: - name: "Checkout for wave provider derivation" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false ref: ${{ inputs.ref }} @@ -235,7 +235,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout current version first to clean-up stuff" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false path: current-version @@ -253,7 +253,7 @@ jobs: # registry buildx cache pushed by the last "main" Test workflow so that layer rebuilds # are avoided whenever the ref is close enough to main for the cache to apply. - name: "Checkout ${{ inputs.ref }} " - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false ref: ${{ inputs.ref }} @@ -303,7 +303,7 @@ jobs: -t "ghcr.io/apache/airflow/main/ci/python${PYTHON_MAJOR_MINOR_VERSION}:latest" --target main . -f Dockerfile.ci --platform linux/amd64 - name: "Restore docs inventory cache" - uses: apache/infrastructure-actions/stash/restore@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/restore@0ff9972b5872e19c9f4555c9159c2fea4f794355 with: path: ./generated/_inventory_cache/ key: cache-docs-inventory-v1 @@ -316,7 +316,7 @@ jobs: run: > breeze build-docs ${INCLUDE_DOCS} --docs-only ${FAIL_ON_INVENTORIES} - name: "Save docs inventory cache" - uses: apache/infrastructure-actions/stash/save@49df447b39b18354895520e0a63731b7cad7cbec + uses: apache/infrastructure-actions/stash/save@0ff9972b5872e19c9f4555c9159c2fea4f794355 if: steps.restore-docs-inventory-cache.outputs.stash-hit != 'true' with: path: ./generated/_inventory_cache/ @@ -362,7 +362,7 @@ jobs: built: ${{ steps.sdk-present.outputs.exists }} steps: - name: "Checkout ${{ inputs.ref }}" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false ref: ${{ inputs.ref }} @@ -427,7 +427,7 @@ jobs: # but it will build the CI image from the version of Airflow that is used to check out things # We also fetch the whole history to be able to prepare SBOM files - name: "Checkout current version with all history for SBOM" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false fetch-depth: 0 @@ -507,7 +507,7 @@ jobs: sudo /tmp/aws/install --update rm -rf /tmp/aws/ - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/push-image-cache.yml b/.github/workflows/push-image-cache.yml index 04e62eeb2b0f5..575eb546aecec 100644 --- a/.github/workflows/push-image-cache.yml +++ b/.github/workflows/push-image-cache.yml @@ -114,7 +114,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Free up disk space" @@ -184,7 +184,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Free up disk space" diff --git a/.github/workflows/recheck-old-bug-report.yml b/.github/workflows/recheck-old-bug-report.yml index a322f9b945da8..dcda435555320 100644 --- a/.github/workflows/recheck-old-bug-report.yml +++ b/.github/workflows/recheck-old-bug-report.yml @@ -28,7 +28,7 @@ jobs: recheck-old-bug-report: runs-on: ["ubuntu-22.04"] steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: only-issue-labels: 'kind:bug' stale-issue-label: 'Stale Bug Report' diff --git a/.github/workflows/refresh-constraints.yml b/.github/workflows/refresh-constraints.yml new file mode 100644 index 0000000000000..58295b6c092e0 --- /dev/null +++ b/.github/workflows/refresh-constraints.yml @@ -0,0 +1,72 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +--- +name: Refresh constraints +# Refreshes the pinned constraint files on demand, when waiting for the automatic path is not an +# option -- a `main` / `vX-Y-test` build that cannot be made green, or newly released providers +# that a release candidate has to pick up before it is promoted. +# +# All three constraint flavours are refreshed, not just the PyPI one: +# +# * `constraints-source-providers-X.Y.txt` -- providers resolved from this checkout's sources, +# which is what a contributor's Breeze environment and CI install from; +# * `constraints-no-providers-X.Y.txt` -- core dependencies alone, used to install Airflow +# without any provider pinned; +# * `constraints-X.Y.txt` -- providers as published on PyPI, which is what users install with. +# +# Refreshing only the PyPI flavour would leave CI and Breeze on the older pins, so the three +# would disagree about the same dependency. +# +# This does the same work as the automatic `uv.lock` push (whose workflow it calls), against the +# ref you name rather than the branch the push landed on. Run it from `main`: the workflow +# definition and `breeze` come from `main`, while the sources come from `ref`, so refreshing a +# release line needs no cherry-pick to `vX-Y-test` / `vX-Y-stable` first. The `constraints-X-Y` +# branch written to is derived from that ref's `branch_defaults.py`. +# +# See dev/MANUALLY_GENERATING_IMAGE_CACHE_AND_CONSTRAINTS.md. +on: # yamllint disable-line rule:truthy + workflow_dispatch: + inputs: + ref: + description: "Repo reference to refresh constraints from (e.g. v3-3-stable). Empty = this branch." + required: false + default: "" + type: string + upgrade-to-newer-dependencies: + description: "Upgrade deps to newest from PyPI" + required: false + type: boolean + default: true +permissions: + contents: read +concurrency: + # Two refreshes of the same ref would race each other onto the same `constraints-X-Y` branch. + group: refresh-constraints-${{ inputs.ref || github.ref }} + cancel-in-progress: false +jobs: + refresh-constraints: + name: "Refresh constraints" + uses: ./.github/workflows/update-constraints-on-push.yml + permissions: + contents: write + packages: write + with: + ref: ${{ inputs.ref }} + upgrade-to-newer-dependencies: ${{ inputs.upgrade-to-newer-dependencies }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/refresh-image-registry-cache.yml b/.github/workflows/refresh-image-registry-cache.yml new file mode 100644 index 0000000000000..23b3e6221dc6d --- /dev/null +++ b/.github/workflows/refresh-image-registry-cache.yml @@ -0,0 +1,145 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +--- +name: Refresh image registry cache +# Refreshes the CI image cache in the GitHub registry, in a run of its own. +# +# It has to be its own workflow rather than a job inside `ci-amd.yml` / `ci-arm.yml`, because a +# job cannot opt out of its run being cancelled, and those runs are cancelled by the next push. +# With no cache a branch builds cold (~20 minutes per Python version), which widens the window in +# which the next push cancels the run, which leaves the cache missing. `v3-3-test` sat in that +# loop -- its `linux/amd64` cache covered the default Python version alone, the single matrix +# entry that finished before the next push killed the other four seconds later. Being a separate +# workflow is what lets a manual run escape that (see the concurrency group below). +# +# Every Python version is refreshed in both trigger paths. That is what makes the cache useful: +# a version with no cache entry builds from scratch on every run, whichever way it got skipped. +on: # yamllint disable-line rule:truthy + workflow_dispatch: + inputs: + platform: + description: "Platform to refresh the cache for" + type: choice + options: + - "both" + - "linux/amd64" + - "linux/arm64" + default: "both" + push: + # Release-prep and providers branches only -- they are built on push, so the CI run that + # would have refreshed their cache is also the run that keeps being cancelled. `main` is not + # built on push; its cache is refreshed by the Push Image Cache job at the end of the + # scheduled canary, which runs to completion. + branches: + - v[0-9]+-[0-9]+-test + - providers-[a-z]+-?[a-z]*/v[0-9]+-[0-9]+ +permissions: + contents: read +concurrency: + # Push runs are never cancelled -- being cancelled by the next merge is the whole failure this + # workflow exists to escape, so a newer one queues behind the one in flight rather than + # replacing it. GitHub keeps at most one run pending per group, so the queue cannot grow. + # + # Manual runs are grouped separately, which is what keeps a merge from cancelling one, and they + # do supersede each other: firing the workflow again for the same branch says the run in flight + # is not the one you want. + group: refresh-image-registry-cache-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: ${{ github.event_name == 'workflow_dispatch' }} +jobs: + build-info: + name: "Build info" + # No outputs yet at this stage, so the runner has to be hard-coded to a public one. + runs-on: ["ubuntu-22.04"] + outputs: + default-branch: ${{ steps.selective-checks.outputs.default-branch }} + default-constraints-branch: ${{ steps.selective-checks.outputs.default-constraints-branch }} + disable-airflow-repo-cache: ${{ steps.selective-checks.outputs.disable-airflow-repo-cache }} + docker-cache: ${{ steps.selective-checks.outputs.docker-cache }} + include-success-outputs: ${{ steps.selective-checks.outputs.include-success-outputs }} + python-versions: ${{ steps.selective-checks.outputs.python-versions }} + use-uv: ${{ steps.selective-checks.outputs.force-pip == 'true' && 'false' || 'true' }} + steps: + - name: "Cleanup repo" + shell: bash + run: sudo rm -rf ${GITHUB_WORKSPACE}/* + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: "Install Breeze" + uses: ./.github/actions/breeze + - name: Selective checks + id: selective-checks + env: + # Forces every Python version. Selective checks narrows `python-versions` down to the + # default one on a push where only text files changed + # (`_should_run_all_tests_and_versions`), which would leave the rest of the versions + # with no cache -- the failure mode this workflow exists to prevent. + PR_LABELS: '["all versions"]' + COMMIT_REF: "${{ github.sha }}" + VERBOSE: "false" + run: breeze ci selective-check 2>> ${GITHUB_OUTPUT} + + refresh-ci-cache-amd: + name: "Refresh cache linux/amd64" + needs: [build-info] + uses: ./.github/workflows/push-image-cache.yml + permissions: + contents: read + # Only granted for `push` / `workflow_dispatch` on apache/airflow itself, never for forks. + packages: write + with: + runners: '["ubuntu-22.04"]' + platform: "linux/amd64" + cache-type: "Refresh" + # The PROD cache is built from distributions prepared earlier in a CI run, and a standalone + # refresh has no such artifact. The CI cache is also where the build time goes. + include-prod-images: "false" + # `latest` is what a build pulls when it has no cache at all. Moving it belongs to a canary + # run that has passed its tests, not to a cache refresh. + push-latest-images: "false" + python-versions: ${{ needs.build-info.outputs.python-versions }} + branch: ${{ needs.build-info.outputs.default-branch }} + constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + docker-cache: ${{ needs.build-info.outputs.docker-cache }} + disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} + if: github.event_name == 'push' || inputs.platform == 'both' || inputs.platform == 'linux/amd64' + + refresh-ci-cache-arm: + name: "Refresh cache linux/arm64" + needs: [build-info] + uses: ./.github/workflows/push-image-cache.yml + permissions: + contents: read + packages: write + with: + runners: '["ubuntu-22.04-arm"]' + platform: "linux/arm64" + cache-type: "Refresh" + include-prod-images: "false" + push-latest-images: "false" + python-versions: ${{ needs.build-info.outputs.python-versions }} + branch: ${{ needs.build-info.outputs.default-branch }} + constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} + use-uv: ${{ needs.build-info.outputs.use-uv }} + include-success-outputs: ${{ needs.build-info.outputs.include-success-outputs }} + docker-cache: ${{ needs.build-info.outputs.docker-cache }} + disable-airflow-repo-cache: ${{ needs.build-info.outputs.disable-airflow-repo-cache }} + if: github.event_name == 'push' || inputs.platform == 'both' || inputs.platform == 'linux/arm64' diff --git a/.github/workflows/registry-backfill.yml b/.github/workflows/registry-backfill.yml index 6bd6493a09ee7..ff387405f4836 100644 --- a/.github/workflows/registry-backfill.yml +++ b/.github/workflows/registry-backfill.yml @@ -126,7 +126,7 @@ jobs: packages: read steps: - name: "Checkout repository" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false fetch-depth: 0 @@ -162,7 +162,7 @@ jobs: rm -rf /tmp/aws/ - name: "Configure AWS credentials" - uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} @@ -222,7 +222,7 @@ jobs: version: 10 - name: "Setup Node.js" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 cache: 'pnpm' @@ -284,7 +284,7 @@ jobs: name: "Publish versions.json" steps: - name: "Checkout repository" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -304,7 +304,7 @@ jobs: rm -rf /tmp/aws/ - name: "Configure AWS credentials" - uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/registry-build.yml b/.github/workflows/registry-build.yml index 81847483ea448..13aa0135a0176 100644 --- a/.github/workflows/registry-build.yml +++ b/.github/workflows/registry-build.yml @@ -112,7 +112,7 @@ jobs: contents: read steps: - name: "Checkout repository" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Tags drive the phantom-version filter in extract_metadata.py @@ -138,7 +138,7 @@ jobs: rm -rf /tmp/aws/ - name: "Configure AWS credentials" - uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0 + uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} @@ -236,7 +236,7 @@ jobs: version: 10 - name: "Setup Node.js" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 cache: 'pnpm' diff --git a/.github/workflows/registry-tests.yml b/.github/workflows/registry-tests.yml index 7a0cb3c518eed..cb7c5cefe6bba 100644 --- a/.github/workflows/registry-tests.yml +++ b/.github/workflows/registry-tests.yml @@ -45,12 +45,12 @@ jobs: timeout-minutes: 5 steps: - name: "Checkout repository" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install uv" - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: python-version: "3.12" diff --git a/.github/workflows/release-constraints.yml b/.github/workflows/release-constraints.yml new file mode 100644 index 0000000000000..94506af6f016a --- /dev/null +++ b/.github/workflows/release-constraints.yml @@ -0,0 +1,255 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Resolves the constraints that a release ships, rather than tagging whatever the +# `constraints-X-Y` branch happened to hold when the release ran. +# +# The stage is derived from the version, so the two cannot be mismatched by hand: +# +# * a candidate (`3.1.3rc1`) resolves with pre-releases allowed - the providers of the wave +# being voted on exist on PyPI only as rc versions - and lands on a branch of its own, so a +# candidate never moves the branch every other build reads; +# * a final (`3.1.3`) resolves without them, against the providers now published as finals, and +# commits onto `constraints-X-Y` itself, which is what makes the released constraints the +# baseline everything downstream reads. +# +# A final therefore cannot be produced by retagging a candidate: a released version must never +# pin an rc. +--- +name: Release constraints +on: # yamllint disable-line rule:truthy + workflow_dispatch: + inputs: + version: + description: "Version the constraints belong to, e.g. 3.1.3rc1 or 3.1.3" + required: true + type: string + ref: + description: "Ref the constraints are resolved from, e.g. v3-1-stable or the release tag" + required: true + type: string +permissions: + contents: read +concurrency: + group: release-constraints-${{ inputs.version }} + cancel-in-progress: false +jobs: + build-info: + timeout-minutes: 10 + name: "Build info" + runs-on: ["ubuntu-22.04"] + if: contains(fromJSON('[ + "ashb", + "eladkal", + "ephraimbuddy", + "jedcunningham", + "kaxil", + "pierrejeambrun", + "potiuk", + "utkarsharma2", + "vatsrahul1001", + "vincbeck", + ]'), github.event.sender.login) + outputs: + python-versions: ${{ steps.selective-checks.outputs.python-versions }} + python-versions-list-as-string: ${{ steps.selective-checks.outputs.python-versions-list-as-string }} + default-branch: ${{ steps.selective-checks.outputs.default-branch }} + default-constraints-branch: ${{ steps.selective-checks.outputs.default-constraints-branch }} + constraints-branch: ${{ steps.stage.outputs.constraints-branch }} + target-branch: ${{ steps.stage.outputs.target-branch }} + allow-pre-releases: ${{ steps.stage.outputs.allow-pre-releases }} + steps: + - name: "Cleanup repo" + shell: bash + run: sudo rm -rf ${GITHUB_WORKSPACE}/* + - name: "Checkout ${{ inputs.ref }}" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ inputs.ref }} + fetch-depth: 2 + persist-credentials: false + - name: "Install Breeze" + uses: ./.github/actions/breeze + id: breeze + - name: "Save github context to file" + # See ci-amd.yml for the full rationale: avoids ARG_MAX on big PRs by writing the + # github context to a file, and the single-quoted heredoc makes the zizmor + # template-injection finding a false positive (no bash expansion happens inside it). + shell: bash + run: | # zizmor: ignore[template-injection] + cat > "${RUNNER_TEMP}/github_context.json" << '__GITHUB_CONTEXT_END__' + ${{ toJson(github) }} + __GITHUB_CONTEXT_END__ + - name: Selective checks + id: selective-checks + env: + PR_LABELS: "[]" + COMMIT_REF: "${{ inputs.ref }}" + VERBOSE: "false" + GITHUB_CONTEXT_INPUT: "${{ runner.temp }}/github_context.json" + run: breeze ci selective-check 2>> ${GITHUB_OUTPUT} + - name: "Derive the release stage from the version" + id: stage + shell: bash + env: + VERSION: ${{ inputs.version }} + run: | + if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(rc[0-9]+)?$ ]]; then + echo "'${VERSION}' is not a release version - expected X.Y.Z or X.Y.ZrcN." >&2 + exit 1 + fi + major="$(echo "${VERSION}" | cut -d. -f1)" + minor="$(echo "${VERSION}" | cut -d. -f2)" + constraints_branch="constraints-${major}-${minor}" + echo "constraints-branch=${constraints_branch}" >> "${GITHUB_OUTPUT}" + if [[ "${VERSION}" == *rc* ]]; then + echo "allow-pre-releases=true" >> "${GITHUB_OUTPUT}" + echo "target-branch=constraints-${VERSION}" >> "${GITHUB_OUTPUT}" + else + echo "allow-pre-releases=false" >> "${GITHUB_OUTPUT}" + echo "target-branch=${constraints_branch}" >> "${GITHUB_OUTPUT}" + fi + - name: "Parameters summary" + shell: bash + env: + VERSION: ${{ inputs.version }} + REF: ${{ inputs.ref }} + CONSTRAINTS_BRANCH: ${{ steps.stage.outputs.constraints-branch }} + TARGET_BRANCH: ${{ steps.stage.outputs.target-branch }} + ALLOW_PRE_RELEASES: ${{ steps.stage.outputs.allow-pre-releases }} + run: | + { + echo "## Release constraints" + echo "" + echo "| Parameter | Value |" + echo "|---|---|" + echo "| Version | \`${VERSION}\` |" + echo "| Resolved from ref | \`${REF}\` |" + echo "| Branched off | \`${CONSTRAINTS_BRANCH}\` |" + echo "| Committed to | \`${TARGET_BRANCH}\` |" + echo "| Pre-releases allowed | \`${ALLOW_PRE_RELEASES}\` |" + echo "| Tagged | \`constraints-${VERSION}\` |" + } | tee -a "${GITHUB_STEP_SUMMARY}" + + build-ci-images: + name: "Build CI images" + needs: [build-info] + uses: ./.github/workflows/ci-image-build.yml + permissions: + contents: read + packages: write + with: + runners: '["ubuntu-22.04"]' + platform: "linux/amd64" + push-image: "false" + upload-image-artifact: "true" + upload-mount-cache-artifact: "false" + python-versions: ${{ needs.build-info.outputs.python-versions }} + branch: ${{ needs.build-info.outputs.default-branch }} + constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} + checkout-ref: ${{ inputs.ref }} + use-uv: "true" + upgrade-to-newer-dependencies: "false" + docker-cache: "registry" + disable-airflow-repo-cache: "false" + + generate-constraints: + name: "Generate constraints" + needs: [build-info, build-ci-images] + uses: ./.github/workflows/generate-constraints.yml + with: + runners: '["ubuntu-22.04"]' + platform: "linux/amd64" + python-versions-list-as-string: ${{ needs.build-info.outputs.python-versions-list-as-string }} + python-versions: ${{ needs.build-info.outputs.python-versions }} + generate-pypi-constraints: "true" + # Only the PyPI constraints are what a release ships; the other modes serve CI, and + # regenerating them here would move them for reasons unrelated to the release. + generate-no-providers-constraints: "false" + # A release pins the providers as published on PyPI, so nothing is built from the sources + # here: a locally built provider wheel would answer the resolution and then be left out of + # the constraints, which is exactly the version the release needed pinned. + pypi-providers-only: "true" + allow-pre-releases: ${{ needs.build-info.outputs.allow-pre-releases }} + debug-resources: "false" + checkout-ref: ${{ inputs.ref }} + use-uv: "true" + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + + publish-constraints: + runs-on: ["ubuntu-22.04"] + timeout-minutes: 20 + name: "Publish and tag constraints" + needs: [build-info, generate-constraints] + permissions: + contents: write + packages: read + env: + VERSION: ${{ inputs.version }} + CONSTRAINTS_BRANCH: ${{ needs.build-info.outputs.constraints-branch }} + TARGET_BRANCH: ${{ needs.build-info.outputs.target-branch }} + steps: + - name: "Cleanup repo" + shell: bash + run: sudo rm -rf ${GITHUB_WORKSPACE}/* + - name: "Checkout ${{ inputs.ref }}" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ inputs.ref }} + persist-credentials: false + # Branched off the shared constraints branch in both cases; what differs is where the commit + # ends up, which the checkout below decides. + - name: "Checkout ${{ needs.build-info.outputs.constraints-branch }}" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: "constraints" + ref: ${{ needs.build-info.outputs.constraints-branch }} + persist-credentials: true + fetch-depth: 0 + - name: "Download constraints from the generate-constraints job" + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: constraints-* + path: ./files + - name: "Switch to ${{ needs.build-info.outputs.target-branch }}" + working-directory: "constraints" + shell: bash + run: git switch -c "${TARGET_BRANCH}" 2>/dev/null || git switch "${TARGET_BRANCH}" + - name: "Diff in constraints for Python: ${{ needs.build-info.outputs.python-versions-list-as-string }}" + run: ./scripts/ci/constraints/ci_diff_constraints.sh + - name: "Commit changed constraint files" + run: ./scripts/ci/constraints/ci_commit_constraints.sh + - name: "Push ${{ needs.build-info.outputs.target-branch }}" + working-directory: "constraints" + shell: bash + # Qualify as refs/heads/ -- for a release candidate the branch and the tag share a name + # (both constraints-), so a bare refspec is ambiguous ("matches more than one"). + run: git push origin "refs/heads/${TARGET_BRANCH}" + - name: "Tag constraints-${{ inputs.version }}" + working-directory: "constraints" + shell: bash + run: | + git tag -a "constraints-${VERSION}" -m "Constraints for Apache Airflow ${VERSION}" + git push origin "refs/tags/constraints-${VERSION}" + - name: "Summary" + shell: bash + run: | + { + echo "Constraints for \`${VERSION}\` are on \`${TARGET_BRANCH}\`," + echo "tagged \`constraints-${VERSION}\`." + } | tee -a "${GITHUB_STEP_SUMMARY}" diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml index 4973425b06c67..b228c4e5ec195 100644 --- a/.github/workflows/release_dockerhub_image.yml +++ b/.github/workflows/release_dockerhub_image.yml @@ -86,7 +86,7 @@ jobs: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/release_single_dockerhub_image.yml b/.github/workflows/release_single_dockerhub_image.yml index c3926659bbc6d..9099919daba67 100644 --- a/.github/workflows/release_single_dockerhub_image.yml +++ b/.github/workflows/release_single_dockerhub_image.yml @@ -77,7 +77,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" @@ -171,7 +171,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml index d1aa896615026..b0e108f503632 100644 --- a/.github/workflows/run-unit-tests.yml +++ b/.github/workflows/run-unit-tests.yml @@ -183,7 +183,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Make /mnt writeable" diff --git a/.github/workflows/scheduled-verify-release-calendar.yml b/.github/workflows/scheduled-verify-release-calendar.yml index 36fd1b938ddf8..ec08a2863a0b0 100644 --- a/.github/workflows/scheduled-verify-release-calendar.yml +++ b/.github/workflows/scheduled-verify-release-calendar.yml @@ -31,7 +31,7 @@ jobs: timeout-minutes: 10 steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install uv" @@ -50,7 +50,7 @@ jobs: # yamllint disable rule:line-length - name: "Notify Slack on failure" if: failure() - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 41d0ea52050a9..e2e7d2bd59986 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -30,7 +30,7 @@ jobs: runs-on: ["ubuntu-22.04"] steps: # Handle all PRs (45-day stale) and pending-response issues (14-day stale) - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: stale-pr-message: > This pull request has been automatically marked as stale because it has not had @@ -50,7 +50,7 @@ jobs: close-issue-message: > This issue has been closed because it has not received response from the issue author. # Handle PRs with pending-response label (7-day stale, faster response expected) - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: only-pr-labels: 'pending-response' days-before-pr-stale: 7 diff --git a/.github/workflows/test-providers.yml b/.github/workflows/test-providers.yml index d4dbe902a8d8e..4ce24af4c5b51 100644 --- a/.github/workflows/test-providers.yml +++ b/.github/workflows/test-providers.yml @@ -89,7 +89,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install prek" @@ -199,7 +199,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Install prek" diff --git a/.github/workflows/ui-e2e-tests.yml b/.github/workflows/ui-e2e-tests.yml index ee0e417d9632d..4699aab04f188 100644 --- a/.github/workflows/ui-e2e-tests.yml +++ b/.github/workflows/ui-e2e-tests.yml @@ -103,7 +103,7 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -126,7 +126,7 @@ jobs: version: 9 run_install: false - name: "Setup node" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 - name: "Compile UI assets (for image build fallback)" diff --git a/.github/workflows/update-constraints-on-push-stable.yml b/.github/workflows/update-constraints-on-push-stable.yml index 2ad9cbf85bc0a..aebe4bc9760a0 100644 --- a/.github/workflows/update-constraints-on-push-stable.yml +++ b/.github/workflows/update-constraints-on-push-stable.yml @@ -47,11 +47,11 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -111,6 +111,8 @@ jobs: generate-no-providers-constraints: "true" debug-resources: "false" use-uv: "true" + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} update-constraints: runs-on: ["ubuntu-22.04"] @@ -127,14 +129,14 @@ jobs: shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Set constraints branch name" id: constraints-branch run: ./scripts/ci/constraints/ci_branch_constraints.sh >> ${GITHUB_OUTPUT} - name: Checkout ${{ steps.constraints-branch.outputs.branch }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: path: "constraints" ref: ${{ steps.constraints-branch.outputs.branch }} @@ -164,7 +166,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} steps: - name: "Send Slack notification" - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/update-constraints-on-push.yml b/.github/workflows/update-constraints-on-push.yml index 16460bd89cbb0..c0fc95b3e16b6 100644 --- a/.github/workflows/update-constraints-on-push.yml +++ b/.github/workflows/update-constraints-on-push.yml @@ -16,7 +16,21 @@ # under the License. # --- -name: Update constraints on push for main (only when uv.lock changes) +name: Update constraints (on uv.lock push) +# This workflow refreshes the pinned constraint files stored in the +# `constraints-*` branches. It runs automatically whenever `uv.lock` changes on +# `main` or a `vX-Y-test` branch. The manual path lives in +# `refresh-constraints.yml`, which calls this workflow -- keeping the two triggers +# in separate workflows means a manual refresh is not filtered by `paths: uv.lock` +# and shows up in the Actions list under its own name. +# +# A manual run is always launched from `main` (so the workflow definition and +# `breeze` come from `main`), and the `ref` input selects the commit-ish +# (branch, tag or commit hash) whose sources the constraints are refreshed from. +# The `constraints-X-Y` branch to push to is derived from that ref's +# `dev/breeze/src/airflow_breeze/branch_defaults.py`, so no cherry-pick to the +# `vX-Y-test` / `vX-Y-stable` branch is needed. +# See dev/MANUALLY_GENERATING_IMAGE_CACHE_AND_CONSTRAINTS.md for details. on: # yamllint disable-line rule:truthy push: branches: @@ -24,11 +38,32 @@ on: # yamllint disable-line rule:truthy - v[0-9]+-[0-9]+-test paths: - 'uv.lock' + workflow_call: + inputs: + # `ref` is optional. Leave it empty to refresh constraints for the branch + # you run the workflow from (normally `main` -> `constraints-main`). Set a + # branch, tag or commit to refresh a specific line, e.g. + # `v3-3-stable` -> `constraints-3-3`. The target `constraints-X-Y` branch + # is derived from that ref's branch_defaults.py. + ref: + description: "Optional repo reference to build constraints (e.g. v3-3-stable)" + required: false + default: "" + type: string + upgrade-to-newer-dependencies: + description: "Upgrade deps to newest from PyPI" + required: false + type: boolean + default: true + secrets: + SLACK_BOT_TOKEN: + description: "Slack bot token used to post provider-downgrade alerts (optional)." + required: false permissions: contents: read concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.ref }} cancel-in-progress: true env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -39,6 +74,25 @@ jobs: build-info: name: "Build info" runs-on: ["ubuntu-22.04"] + # Automatic uv.lock-push runs are unrestricted; manual (workflow_dispatch) + # runs are limited to release managers (same allowlist as the prod image + # release workflow) because they push to the protected constraints-* branches. + if: >- + github.event_name != 'workflow_dispatch' || + contains(fromJSON('[ + "ashb", + "bugraoz93", + "eladkal", + "ephraimbuddy", + "jedcunningham", + "jscheffl", + "kaxil", + "pierrejeambrun", + "potiuk", + "utkarsharma2", + "vincbeck", + "vatsrahul1001", + ]'), github.event.sender.login) outputs: default-branch: ${{ steps.selective-checks.outputs.default-branch }} default-constraints-branch: ${{ steps.selective-checks.outputs.default-constraints-branch }} @@ -49,14 +103,10 @@ jobs: - name: "Cleanup repo" shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: "Checkout ${{ inputs.ref || github.ref }} ( ${{ inputs.ref || github.sha }} )" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - ref: ${{ github.sha }} + ref: ${{ inputs.ref || github.sha }} fetch-depth: 2 persist-credentials: false - name: "Install Breeze" @@ -75,10 +125,30 @@ jobs: id: selective-checks env: PR_LABELS: "[]" - COMMIT_REF: "${{ github.sha }}" + COMMIT_REF: "${{ inputs.ref || github.sha }}" VERBOSE: "false" GITHUB_CONTEXT_INPUT: "${{ runner.temp }}/github_context.json" run: breeze ci selective-check 2>> ${GITHUB_OUTPUT} + - name: "Parameters summary" + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + REF: ${{ inputs.ref }} + UPGRADE: ${{ inputs.upgrade-to-newer-dependencies }} + CONSTRAINTS_BRANCH: ${{ steps.selective-checks.outputs.default-constraints-branch }} + run: | + { + echo "## Update constraints" + echo "" + echo "| Parameter | Value |" + echo "|---|---|" + echo "| Triggered by | \`${EVENT_NAME}\` |" + if [[ "${EVENT_NAME}" == "workflow_dispatch" ]]; then + echo "| Refresh from ref | \`${REF}\` |" + echo "| Upgrade to newer dependencies | \`${UPGRADE}\` |" + fi + echo "| Target constraints branch | \`${CONSTRAINTS_BRANCH}\` |" + } | tee -a "${GITHUB_STEP_SUMMARY}" build-ci-images: name: "Build CI images" @@ -96,8 +166,11 @@ jobs: python-versions: ${{ needs.build-info.outputs.python-versions }} branch: ${{ needs.build-info.outputs.default-branch }} constraints-branch: ${{ needs.build-info.outputs.default-constraints-branch }} + checkout-ref: ${{ inputs.ref }} use-uv: "true" - upgrade-to-newer-dependencies: "false" + upgrade-to-newer-dependencies: >- + ${{ github.event_name == 'workflow_dispatch' + && inputs.upgrade-to-newer-dependencies && 'true' || 'false' }} docker-cache: "registry" disable-airflow-repo-cache: "false" @@ -113,7 +186,10 @@ jobs: generate-pypi-constraints: "true" generate-no-providers-constraints: "true" debug-resources: "false" + checkout-ref: ${{ inputs.ref }} use-uv: "true" + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} update-constraints: runs-on: ["ubuntu-22.04"] @@ -125,22 +201,20 @@ jobs: packages: read env: PYTHON_VERSIONS: ${{ needs.build-info.outputs.python-versions-list-as-string }} + CONSTRAINTS_BRANCH: ${{ needs.build-info.outputs.default-constraints-branch }} steps: - name: "Cleanup repo" shell: bash run: sudo rm -rf ${GITHUB_WORKSPACE}/* - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - name: "Set constraints branch name" - id: constraints-branch - run: ./scripts/ci/constraints/ci_branch_constraints.sh >> ${GITHUB_OUTPUT} - - name: Checkout ${{ steps.constraints-branch.outputs.branch }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Checkout ${{ env.CONSTRAINTS_BRANCH }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: path: "constraints" - ref: ${{ steps.constraints-branch.outputs.branch }} + ref: ${{ env.CONSTRAINTS_BRANCH }} persist-credentials: true fetch-depth: 0 - name: "Download constraints from the generate-constraints job" @@ -167,7 +241,7 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} steps: - name: "Send Slack notification" - uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 + uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/upgrade-check.yml b/.github/workflows/upgrade-check.yml index cd3dce4d4e510..eb9556f891951 100644 --- a/.github/workflows/upgrade-check.yml +++ b/.github/workflows/upgrade-check.yml @@ -51,7 +51,7 @@ jobs: -u 0:0 bash -c "rm -rf /workspace/*" - name: >- [${{ inputs.target-branch }}] Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.target-branch }} fetch-depth: 0 @@ -103,7 +103,7 @@ jobs: [${{ inputs.target-branch }}] Notify Slack on success if: success() && steps.find-pr.outputs.pr-url != '' uses: >- - slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c + slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} @@ -132,7 +132,7 @@ jobs: [${{ inputs.target-branch }}] Notify Slack on failure if: failure() uses: >- - slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c + slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.gitignore b/.gitignore index a0ccf9fd3de7f..791680eeae553 100644 --- a/.gitignore +++ b/.gitignore @@ -139,6 +139,7 @@ ENV/ !.claude/skills/aip-user-stories !.claude/skills/airflow-translations !.claude/skills/prepare-providers-documentation +!.claude/skills/upgrade-fab-provider !.claude/skills/magpie-setup # Kiro diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f3461ed417cd4..c8e78cacd3cfb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ minimum_prek_version: '0.3.4' default_language_version: python: python3 node: 22.19.0 - golang: 1.24.0 + golang: 1.25.0 exclude: ^.*/.*_vendor/ repos: - repo: meta @@ -269,6 +269,38 @@ repos: ^Dockerfile\.ci$ pass_filenames: false require_serial: true + - id: check-go-version-in-sync + name: Check Go toolchain version is consistent across build files + entry: ./scripts/ci/prek/check_go_version_in_sync.py + language: python + files: > + (?x) + ^go-sdk/go\.mod$| + ^kubernetes-tests/lang_sdk/go_example/go\.mod$| + ^\.github/workflows/ci-(arm|amd)\.yml$| + ^airflow-e2e-tests/tests/airflow_e2e_tests/constants\.py$| + ^dev/breeze/src/airflow_breeze/commands/kubernetes_commands\.py$| + ^go-sdk/\.pre-commit-config\.yaml$| + ^\.pre-commit-config\.yaml$ + pass_filenames: false + require_serial: true + - id: check-go-example-mod-tidy + name: Check lang-SDK Go example module is tidy against the Go SDK + entry: ./scripts/ci/prek/check_go_example_mod_tidy.py + # golang so prek provisions the toolchain the check needs: static checks run on a + # runner whose preinstalled toolchains are wiped to free disk space, and the SDK's + # own `go mod tidy` hook gets its Go the same way. + language: golang + # The example module keeps its own copy of the SDK's indirect requirements + # (it resolves the SDK through a `replace`), so a dependency moving in + # go-sdk/go.mod leaves it stale. Watching both modules' manifests is enough: + # any new requirement in the SDK necessarily lands in go-sdk/go.mod first. + files: > + (?x) + ^go-sdk/go\.(mod|sum)$| + ^kubernetes-tests/lang_sdk/go_example/go\.(mod|sum)$ + pass_filenames: false + require_serial: true - id: check-partition-mapper-defaults-in-sync name: Check partition-mapper core/SDK sync (FanOutMapper table + SegmentWindow/FixedKeyMapper) entry: ./scripts/ci/prek/check_partition_mapper_defaults_in_sync.py @@ -644,6 +676,23 @@ repos: language: python files: ^airflow-core/docs/installation/supported-versions\.rst$|^scripts/ci/prek/supported_versions\.py$|^README\.md$ pass_filenames: false + - id: generate-api-permissions-doc + name: Generate REST API permission reference documentation + entry: ./scripts/ci/prek/extract_permissions.py + language: python + files: > + (?x) + ^airflow-core/src/airflow/api_fastapi/core_api/routes/public/.*\.py$| + ^airflow-core/src/airflow/api_fastapi/core_api/security\.py$| + ^scripts/ci/prek/extract_permissions\.py$| + ^airflow-core/docs/security/api_permissions_ref\.rst$ + pass_filenames: false + - id: update-tested-versions + name: Update tested Python/DB/Kubernetes versions in docs + entry: ./scripts/ci/prek/update_tested_versions.py + language: python + files: ^airflow-core/docs/installation/prerequisites\.rst$|^README\.md$|^dev/breeze/src/airflow_breeze/global_constants\.py$|^scripts/ci/prek/update_tested_versions\.py$|^scripts/ci/prek/common_prek_utils\.py$ + pass_filenames: false - id: check-revision-heads-map name: Check that the REVISION_HEADS_MAP is up-to-date language: python @@ -1209,7 +1258,7 @@ repos: files: ^shared/.*|^scripts/ci/prek/check_shared_mypy_hooks\.py$ require_serial: true - id: check-migration-patterns - name: Check migration files for anti-patterns (MIG001/MIG002/MIG003) + name: Check migration files for anti-patterns and style (MIG001-MIG004) entry: ./scripts/ci/prek/check_migration_patterns.py language: python pass_filenames: true diff --git a/README.md b/README.md index 1ab5c182f5fd2..8f572bbfb4891 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,8 @@ Use Airflow to author workflows (Dags) that orchestrate tasks. The Airflow sched Airflow works best with workflows that are mostly static and slowly changing. When the Dag structure is similar from one run to the next, it clarifies the unit of work and continuity. Other similar projects include [Luigi](https://github.com/spotify/luigi), [Oozie](https://oozie.apache.org/) and [Azkaban](https://azkaban.github.io/). +Beyond traditional data pipelines, Airflow is widely used to orchestrate machine learning workflows — training, retraining, evaluation, and deployment — and increasingly to orchestrate agentic and LLM-based workloads, coordinating the steps of an AI pipeline (data prep, tool calls, model invocation, evaluation) rather than acting as the agent itself. This isn't a new direction: teams have run ML and AI workloads on Airflow for years, and the ecosystem of providers supporting these use cases (see the [AI & ML section of the Airflow registry](https://airflow.apache.org/registry/providers/?category=ai-ml)) continues to grow. + Airflow is commonly used to process data, but has the opinion that tasks should ideally be idempotent (i.e., results of the task will be the same, and will not create duplicated data in a destination system), and should not pass large quantities of data from one task to the next (though tasks can pass metadata using Airflow's [XCom feature](https://airflow.apache.org/docs/apache-airflow/stable/concepts/xcoms.html)). For high-volume, data-intensive tasks, a best practice is to delegate to external services specializing in that type of work. Airflow is not a streaming solution, but it is often used to process real-time data, pulling data off streams in batches. @@ -99,7 +101,7 @@ Airflow is not a streaming solution, but it is often used to process real-time d Apache Airflow is tested with: -| | Main version (dev) | Stable version (3.3.0) | Deprecate version (2.11.2) | +| | Main version (dev) | Stable version (3.3.1) | Deprecate version (2.11.2) | |------------|------------------------------------|-------------------------------------|------------------------------| | Python | 3.10, 3.11, 3.12, 3.13, 3.14 | 3.10, 3.11, 3.12, 3.13, 3.14 | 3.10, 3.11, 3.12 | | Platform | AMD64/ARM64 | AMD64/ARM64 | AMD64/ARM64(\*) | @@ -172,15 +174,15 @@ them to the appropriate format and workflow that your tool requires. ```bash -pip install 'apache-airflow==3.3.0' \ - --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-3.3.0/constraints-3.10.txt" +pip install 'apache-airflow==3.3.1' \ + --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-3.3.1/constraints-3.10.txt" ``` 2. Installing with extras (i.e., postgres, google) ```bash -pip install 'apache-airflow[postgres,google]==3.3.0' \ - --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-3.3.0/constraints-3.10.txt" +pip install 'apache-airflow[postgres,google]==3.3.1' \ + --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-3.3.1/constraints-3.10.txt" ``` For information on installing provider distributions, check @@ -294,7 +296,7 @@ Apache Airflow version life cycle: | Version | Current Patch/Minor | State | First Release | Limited Maintenance | EOL/Terminated | |-----------|-----------------------|-------------|-----------------|-----------------------|------------------| -| 3 | 3.3.0 | Maintenance | Apr 22, 2025 | TBD | TBD | +| 3 | 3.3.1 | Maintenance | Apr 22, 2025 | TBD | TBD | | 2 | 2.11.2 | EOL | Dec 17, 2020 | Oct 22, 2025 | Apr 22, 2026 | | 1.10 | 1.10.15 | EOL | Aug 27, 2018 | Dec 17, 2020 | June 17, 2021 | | 1.9 | 1.9.0 | EOL | Jan 03, 2018 | Aug 27, 2018 | Aug 27, 2018 | diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 37a81c2a21dfd..d2e00de3fed80 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -24,6 +24,237 @@ .. towncrier release notes start +Airflow 3.3.1 (2026-08-10) +-------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +pandas 3 changes how DataFrame XComs are stored and read back (#71169) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +pandas 3 exposes its public classes from the ``pandas`` namespace, so a DataFrame is qualified as +``pandas.DataFrame`` instead of ``pandas.core.frame.DataFrame``. XComs record that name alongside the +serialized value, so the name written into the metadata database depends on the pandas version of the +component that pushed the value. Airflow registers both names, and a DataFrame written by either +pandas version can be read by either -- no configuration change is needed, and existing XComs stay +readable. + +What you should do: + +* **Roll this Airflow version out to every component before pandas 3 reaches any of them** -- workers + in particular. A component that predates this change cannot read a DataFrame XCom written under + pandas 3, and fails the pull with: + + .. code-block:: text + + ImportError: pandas.DataFrame was not found in allow list for deserialization imports. + To allow it, add it to allowed_deserialization_classes in the configuration + + The message points at configuration, but the allow list is not the cause and changing it does not + help. The rows are not corrupt: they become readable again as soon as the reader is upgraded. + +* **Treat a downgrade as a one-way door for those XComs.** Rolling back to an Airflow version without + this change strands any DataFrame XCom written while on pandas 3, with the same error, until you + roll forward again. + +* **Review Dags that inspect the ``dtypes`` of a pulled DataFrame.** The pandas version of the *reader* + determines what a pulled DataFrame looks like, not the version that wrote it. Under pandas 3, a + column of strings comes back as ``str`` rather than ``object``, and its missing values + come back as ``nan`` rather than ``None``. Values are unchanged, but downstream code that branches + on ``dtype == "object"``, checks cells with ``is None``, or compares against a reference frame with + ``DataFrame.equals()`` can behave differently after the upgrade. + +Fix 2.x to 3.0+ upgrade failure when a custom Dag bundle is configured (#70994) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The ``0082_3_1_0_make_bundle_name_not_nullable`` migration assigned every legacy row +``bundle_name='dags-folder'``, so triggering a DagRun raised ``Requested bundle 'dags-folder' is +not configured.`` on any deployment that uses a bundle other than the default ``dags-folder``. +``DagFileProcessorManager`` now runs a one-shot, best-effort backfill at startup that routes each +affected Dag to the correct bundle based on its file path; unmatched Dags self-heal on the next +successful parse (or run ``airflow dags reserialize`` to force it immediately). + +Team scoped values of options registered as sensitive are now hidden (#71099) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Configuration options are registered as sensitive under their base section, so until now only the +base spelling of an option was masked. A team scoped override -- set in a ``[=
]`` +config file section, or through an ``AIRFLOW_____
__`` environment variable -- +was not recognized as the same option and was returned in full. + +Sensitivity is now decided after resolving the team scoped spelling back to the base option, so a +team scoped value is masked exactly as the base value already was. + +**Behaviour changes:** + +- ``AirflowConfigParser.as_dict(display_sensitive=False)``, ``GET /config``, + ``GET /config/section/{section}/option/{option}`` and ``airflow config list`` now return + ``< hidden >`` for a team scoped value of an option registered as sensitive. Deployments that + read a team's real value through any of these will now receive the mask; use + ``display_sensitive=True`` where a real value is required and appropriate. +- Team scoped ``_cmd`` and ``_secret`` entries are replaced with ``< hidden >`` in place, rather + than being resolved into their value and removed as they are in a base section. Resolving them + is not supported for a team, so the command string or secret path is no longer shown either. +- Non team configuration is unaffected, and ``display_sensitive=True`` continues to return real + values. + +Bug Fixes +^^^^^^^^^ + +- Fail deferred task instances whose saved state can't be resumed, instead of leaving them stuck (#71183) +- Fix task callbacks being skipped when ``TriggerDagRunOperator`` gets a 404 (#71083) +- Fix task state store rejecting keys that contain slashes (#70967) +- Fix the ``deadline_reference`` decorator's no-parentheses form (#70966) +- Fix Dag run duration stats crash on PostgreSQL 14+ (#70964) +- Deactivate legacy Dags with a NULL ``bundle_name`` during upgrade from 2.x to 3.x (#70662) +- Fix deadline alerts using an outdated Dag definition (#70965) +- Fix deadline alert crashes on dynamic or malformed intervals (#70625) +- Fix deadline alerts that have no fixed interval (#70659) +- Fix backfill permission checks running against the wrong backfill for some ID formats (#71090) +- Fix database lock contention and statement timeouts caused by slow asset listeners on large fan-outs (#71065) +- Fix errors loading a Dag callback whose module isn't importable on the current component (#71042) +- Reject reserved XCom serialization keys submitted as JSON string literals (#69462) +- API: Return a clear error instead of a 500 for an invalid trigger-Dag-run request (#70775) +- API: Return 503 when SQLite locks during backfill creation (#69659) +- API: Return 422 for an empty backfill window and stop leaving orphan rows (#69367) +- API: Return 410 instead of 500 when setting rendered fields for a stale task instance (#69529) +- Reject invalid partition keys in the create asset events API (#69581) +- Reject attaching partition keys to asset alias events (#69515) +- Reject mismatched rollup mapper and window pairings at Dag parse time (#69516) +- CLI: Reject inverted date windows in ``airflow partitions clear`` (#69547) +- Fix asset materialization dropping the partition date on partitioned Dag runs (#69339) +- UI: Fix partition progress returning errors or over-reporting for keys with slashes and duplicate rows (#69844) +- Honor catchup for historical asset events in asset-triggered Dags (#69224) +- Fix drifting data intervals for monthly/yearly schedules with catchup disabled (#69189) +- Fix asset watcher triggers failing to decode their arguments (#70750) +- Prevent Triggerer crashes by speeding up cleanup of unused triggers (#70668) +- Fix Triggerer CrashLoopBackOff when ``json_logs`` is enabled (#70669) +- Detect and surface task-worker communication deadlocks instead of hanging (#70744) +- Fix TaskInstance duration calculation with SQLite (#70734) +- Fix incorrect end date, duration, and map index in task try history for retried tasks (#69458) +- Stop skipping ``none_failed_min_one_success`` tasks in mapped task groups (#70318) +- Fix the scheduler firing ``on_failure_callback`` for heartbeat-timed-out retries (#69824) +- Respect retries for deferrable tasks that fail via a trigger-emitted ``TaskFailedEvent``, instead of always failing terminally (#71163) +- Prevent scheduler crash when process/thread are missing from the log format (#69787) +- Fix ``TaskInstance`` mark-success downstream default (#70143) +- Fix crash when tailing logs of a running task instance (#69521) +- API: Return a consistent error response instead of a 500 when a database error occurs (#70236) +- Fix Dag reparse authorization checking the wrong Dag (#70115) +- Don't deactivate Dag bundles owned by other Dag processors (#70017) +- Fix Dag bundle refresh using stale state (#70374) +- Skip stored credentials when a connection test overrides host or port (#70010) +- Fix cursor pagination dropping rows when sorting by a nullable column (#70739) +- API: Filter stale Dag tags from the public API (#70746) +- Fix Dag details active-runs count to exclude queued runs (#70511) +- Fix environment-variable config overrides being ignored for some provider config sections (#70732) +- CLI: Fix config ``update --option``/``--ignore-option`` never matching options (#70757) +- CLI: Fix ``TypeError`` in ``airflow db shell`` when the database name is missing (#70752) +- CLI: Send Airflow CLI logs to stderr for ``-o`` commands so structured output stays machine-readable (#70747) +- Reduce Dag processor log noise from per-Dag run lookups (#69514) +- Suppress noisy Alembic plugin setup logs (#70116) +- Silence internal HTTP 422 deprecation warnings in logs (#70745) +- Only resolve a team-namespaced environment secret for its own team (#70882) +- Fix a team-scoped secret lookup that could return another team's secret for a crafted key (#71041) +- Mask sensitive ``Variable`` values stored as JSON lists (#71069) +- Fix secrets recorded unmasked in the audit log for bulk ``Variable``/``Connection`` updates (#71043) +- Fix sensitive values nested inside lists, tuples, or sets not being masked in logs (#70189) +- UI: Fix secrets not masked in the Rendered Templates view with ``KubernetesPodOperator`` (#70756) +- Fix an open-redirect by rejecting malformed URLs in redirect validation (#70515) +- Fix npm vulnerabilities in the simple auth manager (#70753) +- Bump ``structlog>=26.1.0`` and ``croniter>=6.2.2`` to fix memory leaks (#70749) +- Fix task instance notes not being visible to state-change listeners (#70252) +- Call listeners for a running task instance when a Dag run state is manually set (#70286) +- Fix ``dag`` and ``note`` missing from Dag-run state-change listener events (#70245) +- Remove a Dag Run or Task Instance note when its content is cleared (#70735) +- Fix ``email_on_failure``/``email_on_retry`` task alerts silently ignoring a custom ``[email] email_backend`` and always routing through ``SmtpNotifier``; an ``email_backend`` that cannot be imported now errors loudly instead of silently falling back to SMTP (#70129) +- UI: Fix task states stuck stale when a run finishes quickly (#70397) +- UI: Fix Grid view scrollbar hiding the latest Dag run (#70555) +- UI: Fix grid/graph view topological sort for group-level and cross-group dependencies (#70591) +- UI: Fix ``Trigger Again`` showing empty config for the selected run (#70288) +- UI: Fix blank Assets dependency graph from missing Dag nodes (#70743) +- UI: Fix the collapse button overlapping details panel content (#70751) +- UI: Fix log line-number link highlighting (#69663) +- UI: Fix partition key display and input handling (#69974) +- UI: Fix Gantt tooltip showing the wrong end date on queued/scheduled bars (#70742) +- UI: Make the Dag pause toggle distinguishable in dark mode (#70748) + +Miscellaneous +^^^^^^^^^^^^^ + +- UI: Show a note indicator on Dag runs in the Grid view (#70834) +- UI: Show a saved-note indicator on task instances in the Grid view (#70829) +- Add partition date filters to the Dag run API (#70304) +- Add support for filtering Dags by any Dag run state (#70292) +- Allow filtering the Dags list by failed and success runs in any run-state filter (#70293) +- Add expand/collapse all for the Dag Run conf JSON in the Dag Runs list (#69777) +- Show the Dag Run conf column by default in the Dag Runs list (#69604) +- API: Allow keeping finished task states when clearing a Dag run (#69662) +- Export ``FanOutMapper`` and wait policies from ``airflow.partition_mappers`` (#69513) +- Add a ``task.execute`` OpenTelemetry span around task execution (#69359) +- Add a ``run_type`` tag to the ``dagrun.duration.failed`` metric (#70731) +- Improve error messages when a value's type cannot be serialized (for example, XCom values) (#70982) +- Highlight user-code frames in task log tracebacks (#70375) +- Optimize scheduling by avoiding duplicate trigger-rule upstream-count queries per pass (#70826) +- Hide the run-on-latest-version option for non-versioned bundles (#70702) +- Show the current page name in the browser tab title (#69656) +- UI: Show larger Dag run and task instance counts on the dashboard (#71008) +- UI: Refresh task details immediately when switching tasks (#71012) +- UI: Reset the task try when switching Graph tasks (#70817) +- UI: Add JSON validation and prettifying to the JSON editor (#70554) +- UI: Make the Dag pause toggle update immediately on click (#70741) +- UI: Improve Dag list rendering by deferring the pause confirmation dialog (#70025) +- UI: Align boolean controls in the Trigger Dag form (#70963) +- UI: Wrap long plugin source paths in the import-error dialog (#70737) +- UI: Allow multiple routes to show active nav buttons (#70200) +- UI: Make duration charts readable at a glance (#70197) +- UI: Improve Grid view performance when summaries stream in (#69958) +- UI: Improve Grid view responsiveness by avoiding a full re-render on hover (#69928) +- UI: Fix missing glyph icons in the code editor (#69422) +- UI: Complete missing Hebrew (``he``) translations (#70566) +- UI: Complete missing Arabic (``ar``) translations (#70510) +- UI: Complete the Polish (``pl``) translation (#70507) +- UI: Add missing Greek (``el``) translations (#70471) +- Optimize database queries when triggers submit asset events (#70738) +- Optimize core queries by removing redundant result de-duplication (#69918) +- Remove redundant database commits in API route handlers (#69620) +- Make ``ResumableJobMixin`` an abstract base class (subclasses must implement its methods) (#70810) +- UI: Add a keyboard shortcut help dialog (press ``?``) and clean up the graph/grid view (#69978) + +Doc Only Changes +^^^^^^^^^^^^^^^^ + +- Document the effect of state-store cleanup in ``ResumableJobMixin`` (#70792) +- Document ``jwt_secret``/``_secret`` and ``LocalFilesystemBackend`` config support (#70730) +- Clarify the ``logging_config_class`` contract and document ``REMOTE_TASK_LOG`` (#70592) +- Clarify ``AssetAlias`` usage (#71087) +- Clarify the ``AssetPartitionDagRun`` provisional-run docstring (#70104) +- Clarify custom-time parameterized timetable logic (#69387) +- Document native template rendering type coercion (#69389) +- Update multi-node executor guidance (#69388) +- Add a custom metrics section to the metrics docs (#70778) +- Add Task SDK, Go and Java SDK execution architecture diagrams (#70100) +- Add a docker-stack docs example for the venv scene (#69112) +- Link the pkg.go.dev API reference from the Go SDK docs (#69440) +- Link the published Java SDK API reference from the Java SDK docs (#69448) +- Add a real example of ``CronDataIntervalTimetable`` and ``DeltaDataIntervalTimetable`` (#70434) +- Fix incorrect code samples in the Deadline Alerts docs (#70786) +- Fix reversed-direction examples in the ``FanOutMapper`` docs (#69511) +- Fix documentation misusing previous/next for task relationships (#69570) +- Fix partition-label casing (#69470) +- Fix stale Airflow 2.0 references in ``dev/README.md`` (#70107) +- Fix a Sphinx build error (#70761) +- Update the description on "What is Airflow" (#71068) +- Update local OTel Collector and Prometheus versions to support exponential histograms (#69056) +- Simplify the API docs on pattern search (#70509) +- Standardize Alembic migration descriptions and add a style lint (#70262) +- UI: Complete Spanish UI translations (#70196) +- Update French (``fr``) UI translations to 100% coverage (#70387) +- Add missing Dutch (``nl``) translations (#70004) +- Add missing Simplified Chinese (``zh-CN``) UI translations (#70417, #70418, #70419) +- Fill the Taiwanese Mandarin (``zh-TW``) translation gaps (#70195, #70379, #69707) +- Add missing Korean (``ko``) translations and backport from main (#70807, #70832) + Airflow 3.3.0 (2026-07-06) -------------------------- @@ -4015,6 +4246,33 @@ thank everyone who helped shape this release through design discussions, code co community feedback. For full details, migration guidance, and upgrade best practices, refer to the official Upgrade Guide and join the conversation on the Airflow dev and user mailing lists. +Airflow 2.11.2 (2026-03-11) +--------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Bug Fixes +""""""""" + +- Fix Task Instances list view rendering raw HTML instead of clickable links for Dag Id, Task Id, and Run Id columns. (#62533) +- In 2.11.1 by mistake ``core.use_historical_filename_templates`` was read by Airflow instead of ``logging.use_historical_filename_templates``. The ``core`` option is deprecated in Airflow 2.11.2. Both options are removed in Airflow 3 as historical templates are supported and does not cause low-severity security issue in Airflow 3. (#62647) +- gracefully handle 404 from worker log server for historical retry attempts (#63002) +- task_instance_mutation_hook receives a TI with run_id set (#62999) +- fix missing logs in UI for tasks in ``UP_FOR_RETRY`` and ``UP_FOR_RESCHEDULE`` states (#54547) (#62877) +- Fixing 500 error on webserver after upgrading to FAB provider 1.5.4 (#62412) +- Lazily import fs and package_index hook in providers manager #52117 (#62356) + +Updated dependencies +"""""""""""""""""""" + +- Upgrade airflow UI to latest reasonable dependencies. (#63158) +- Bump the core-ui-package-updates group across 1 directory with 87 updates (#61091) +- bump filelock (#62952) +- Limit Celery Provider to not install 3.17.0 as it breaks airflow 2.11 (#63046) +- Bump the pip-dependency-updates group across 3 directories with 5 updates (#62808) +- Upgrade to latest released build dependencies (#62613) + Airflow 2.11.1 (2026-02-20) --------------------------- diff --git a/airflow-core/docs/administration-and-deployment/logging-monitoring/advanced-logging-configuration.rst b/airflow-core/docs/administration-and-deployment/logging-monitoring/advanced-logging-configuration.rst index fa34e74f3140b..629cb5065513e 100644 --- a/airflow-core/docs/administration-and-deployment/logging-monitoring/advanced-logging-configuration.rst +++ b/airflow-core/docs/administration-and-deployment/logging-monitoring/advanced-logging-configuration.rst @@ -46,13 +46,14 @@ that Python objects log to loggers that follow naming convention of ``. You can read more about standard python logging classes (Loggers, Handlers, Formatters) in the `Python logging documentation `_. -Create a custom logging class ------------------------------ +Create a custom logging config +------------------------------ Configuring your logging classes can be done via the ``logging_config_class`` option in ``airflow.cfg`` file. -This configuration should specify the import path to a configuration compatible with -:func:`logging.config.dictConfig`. If your file is a standard import location, then you should set a -:envvar:`PYTHONPATH` environment variable. +Despite the option name the value is a dotted import path to a ``dict`` that satisfies +:func:`logging.config.dictConfig` — not a Python class. The ``_class`` suffix is +historical and kept for backwards compatibility. If your file is a standard import +location, then you should set a :envvar:`PYTHONPATH` environment variable. Follow the steps below to enable custom logging config class: @@ -102,6 +103,48 @@ See :doc:`../modules_management` for details on how Python and Airflow manage mo You can override the way both standard logs of the components and "task" logs are handled. +Custom logging configs and remote logging +----------------------------------------- + +When ``[logging] remote_logging = True`` and you point ``logging_config_class`` +at your own module, define two module-level attributes in that module: + +* ``REMOTE_TASK_LOG`` — an instance of + :class:`~airflow.logging.remote.RemoteLogIO` (or + :class:`~airflow.logging.remote.RemoteLogStreamIO`) that uploads task logs + and reads them back for the UI. +* ``DEFAULT_REMOTE_CONN_ID`` — default Airflow connection id used when + ``[logging] remote_log_conn_id`` is unset. + +If ``REMOTE_TASK_LOG`` is missing, Airflow emits one ``WARNING`` at startup +and the UI cannot read task logs back from the remote backend. + + .. code-block:: python + + # ~/airflow/config/log_config.py + from airflow.logging.remote import RemoteLogIO + + + class MyRemoteLogIO: + @property + def processors(self): + return () + + def upload(self, path, ti): ... # upload local log file at ``path`` to your backend + + def read(self, relative_path, ti): ... # return (source_info, log_messages) for the UI + + + REMOTE_TASK_LOG: RemoteLogIO | None = MyRemoteLogIO() + DEFAULT_REMOTE_CONN_ID: str | None = "my_remote_conn" + +.. note:: + + Define ``REMOTE_TASK_LOG`` in your own module rather than re-exporting it + from ``airflow.config_templates.airflow_local_settings``, which is planned + for deprecation. + + Custom logger for Operators, Hooks and Tasks -------------------------------------------- diff --git a/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst b/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst index 49f37ab18207f..af0fa6e300b70 100644 --- a/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst +++ b/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst @@ -115,11 +115,49 @@ You need to configure the SSL certificate and key within the OpenTelemetry colle cert_file: "/path/to/cert/cert.crt" key_file: "/path/to/key/key.pem" +Histogram Metrics and Backend Requirements +------------------------------------------ + +Airflow's timing metrics (``timing()`` / ``timer()``) are emitted as OpenTelemetry +histograms aggregated with +`exponential bucket histograms `_, +so bucket boundaries adapt automatically to the observed range and you do not have to +hand-tune explicit buckets for metrics that span very different scales (milliseconds to +hours). + +To ingest these correctly end-to-end, the metrics backend you connect to must support +OpenTelemetry exponential histograms and (for Prometheus) their conversion to native +histograms: + +* **OpenTelemetry Collector** — use ``opentelemetry-collector-contrib`` version 0.115.0 + or above. Older versions do not translate OTLP exponential histograms into Prometheus + native histograms. +* **Prometheus** — native histograms must be enabled explicitly, and how you do that + depends on the Prometheus version: + + * **2.40 to 3.8** — start Prometheus with the ``--enable-feature=native-histograms`` + flag. + * **3.8 and above** — set ``scrape_native_histograms: true`` in the scrape + configuration (this option was added in 3.8, and from 3.9 the feature flag is a + no-op so the config setting is required): + + .. code-block:: yaml + + global: + scrape_native_histograms: true + +If the backend does not support native histograms, exponential-histogram data points may +be dropped or rendered incorrectly. A reference stack (Collector, Prometheus, and Grafana) +wired up for local development is available via ``breeze start-airflow --integration otel``; +see the contributor docs for details. + Allow/Block Lists ----------------- If you want to avoid sending all the available metrics, you can configure an allow list or block list -of prefixes to send or block only the metrics that start with the elements of the list: +to send or block only certain metrics. Each list is a comma-separated set of regular expressions +matched anywhere in the metric name (anchor a pattern with ``^`` to match a prefix). If both lists +are set, the block list is ignored: .. code-block:: ini @@ -145,6 +183,73 @@ to the stat name if necessary, and returns the transformed stat name. The functi return stat_name.lower()[:32] +Custom Metrics +-------------- + +You can emit your own metrics from inside a task, plugin, or custom operator through +the same stats client Airflow uses internally. In Airflow 3 the recommended import +path is ``airflow.sdk.observability``: + +.. code-block:: python + + from airflow.sdk.observability import stats + + stats.incr("my_service.processed") + stats.decr("my_service.in_flight") + stats.gauge("my_service.queue_depth", 42) + stats.timing("my_service.batch_ms", 1234) + + with stats.timer("my_service.batch"): + ... + +.. versionadded:: 3.3.0 + The module-level ``stats`` functions (``stats.incr()``, ``stats.gauge()``, and so on). + +On earlier versions, use the ``Stats`` class instead: +``from airflow.sdk.observability.stats import Stats``, then ``Stats.incr(...)``. + +``incr``, ``decr``, ``gauge``, ``timing`` and ``timer`` also accept an optional +``tags`` mapping for dimensional metrics on backends that support them: + +.. code-block:: python + + stats.incr("my_service.requests", tags={"endpoint": "checkout"}) + +``incr`` and ``decr`` also accept ``count`` and ``rate``, and ``gauge`` accepts +``rate`` and ``delta``, following the `StatsD data types +`__. + +.. note:: + + Tag support depends on the backend. The classic StatsD protocol has no concept of tags. + + * **OpenTelemetry** (``otel_on``) sends tags as native attributes. + * **StatsD** (``statsd_on``) drops the ``tags`` mapping by default. To turn tags into labels, + enable a tagged wire format, either ``statsd_influxdb_enabled = True`` (InfluxDB + ``name,key=value``) or ``statsd_datadog_enabled = True`` (DogStatsD ``|#key:value``). The + Prometheus ``statsd_exporter`` reads the tags from either format and turns them into labels. + These flags only change how tags are written on the wire. You can also embed the values in the + metric name and map those name segments back to labels with ``statsd_exporter`` mapping rules. + +.. note:: + + Metric names must be 250 characters or fewer and may only contain the characters + ``a-z``, ``A-Z``, ``0-9``, ``_``, ``.``, ``-`` and ``/``. An invalid name is logged + and the metric is not emitted. + +.. note:: + + These metrics are silently dropped unless a backend is enabled (see `Setup - StatsD`_ + or `Setup - OpenTelemetry`_). + +.. note:: + + If your custom metrics do not appear, check ``[metrics] metrics_allow_list`` and + ``[metrics] metrics_block_list`` (see `Allow/Block Lists`_). When + ``metrics_allow_list`` is set, only metrics matching it are emitted, so a custom + metric that is not listed is silently dropped. + + Other Configuration Options --------------------------- diff --git a/airflow-core/docs/administration-and-deployment/production-deployment.rst b/airflow-core/docs/administration-and-deployment/production-deployment.rst index e88b94d94ba8b..8e1258bb9da49 100644 --- a/airflow-core/docs/administration-and-deployment/production-deployment.rst +++ b/airflow-core/docs/administration-and-deployment/production-deployment.rst @@ -57,8 +57,13 @@ Multi-Node Cluster ================== Airflow uses :class:`~airflow.executors.local_executor.LocalExecutor` by default. For a multi-node setup, -you should use the :doc:`Kubernetes executor ` or -the :doc:`Celery executor `. +choose a remote executor, or a multi-executor configuration, that matches where tasks should run. +Common choices include the :doc:`Celery executor `, +the :doc:`Kubernetes executor `, +Amazon provider executors such as :doc:`Batch ` +or :doc:`ECS `, and the +:doc:`Edge executor `. See the +:ref:`executor comparison ` for the current list and trade-offs. Once you have configured the executor, it is necessary to make sure that every node in the cluster contains diff --git a/airflow-core/docs/authoring-and-scheduling/assets.rst b/airflow-core/docs/authoring-and-scheduling/assets.rst index b5561392587db..8a3db2b507875 100644 --- a/airflow-core/docs/authoring-and-scheduling/assets.rst +++ b/airflow-core/docs/authoring-and-scheduling/assets.rst @@ -328,12 +328,18 @@ The shorthand for this is ``@asset.multi``: Dynamic data events emitting and asset creation through AssetAlias ----------------------------------------------------------------------- -An asset alias can be used to emit asset events of assets with association to the aliases. Downstreams can depend on resolved asset. This feature allows you to define complex dependencies for Dag executions based on asset updates. +Use ``AssetAlias`` when a task must declare an asset dependency before the Asset's fixed attributes +(like URI or name) are available. The alias is listed in ``outlets`` as a stable name, and the task +resolves it at runtime by adding one or more concrete ``Asset`` objects through ``outlet_events`` or +yielded ``Metadata``. Downstream Dags can depend on the alias, and Airflow triggers them when events +are emitted for the resolved assets. How to use AssetAlias ~~~~~~~~~~~~~~~~~~~~~~~ -``AssetAlias`` has one single argument ``name`` that uniquely identifies the asset. The task must first declare the alias as an outlet, and use ``outlet_events`` or yield ``Metadata`` to add events to it. +``AssetAlias`` has one single argument ``name`` that uniquely identifies the alias. The task must +first declare the alias as an outlet, and then use ``outlet_events`` or yield ``Metadata`` during +execution to associate the alias with the concrete assets it produced. The following example creates an asset event against the S3 URI ``f"s3://bucket/my-task"`` with optional extra information ``extra``. If the asset does not exist, Airflow will dynamically create it and log a warning message. diff --git a/airflow-core/docs/authoring-and-scheduling/dynamic-task-mapping.rst b/airflow-core/docs/authoring-and-scheduling/dynamic-task-mapping.rst index d9dfec21fe80e..d3a3f9cfa1d64 100644 --- a/airflow-core/docs/authoring-and-scheduling/dynamic-task-mapping.rst +++ b/airflow-core/docs/authoring-and-scheduling/dynamic-task-mapping.rst @@ -23,7 +23,7 @@ Dynamic Task Mapping Dynamic Task Mapping allows a way for a workflow to create a number of tasks at runtime based upon current data, rather than the Dag author having to know in advance how many tasks would be needed. -This is similar to defining your tasks in a for loop, but instead of having the DAG file fetch the data and do that itself, the scheduler can do this based on the output of a previous task. +This is similar to defining your tasks in a for loop, but instead of having the DAG file fetch the data and do that itself, the scheduler can do this based on the output of an upstream task. Unlike a Python for-loop executed at DAG parse time, dynamic task mapping defers task creation until runtime, allowing the scheduler to determine the exact number of task instances based on upstream task outputs. Right before a mapped task is executed the scheduler will create *n* copies of the task, one for each input. @@ -120,7 +120,7 @@ The ``make_list`` task runs as a normal task and must return a list or dict (see Repeated mapping ---------------- -The result of one mapped task can also be used as input to the next mapped task. +The result of one mapped task can also be used as input to the downstream mapped task. .. code-block:: python diff --git a/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst b/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst index 722bd7549e5a3..158fff4ddeb2f 100644 --- a/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst +++ b/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst @@ -37,6 +37,12 @@ the bundle: one runnable file to ship, with no separate manifest or archive. The :local: :depth: 2 +API reference +------------- + +The generated API reference for the Go SDK module, and the list of its released versions, is available on +`pkg.go.dev `__. + Prerequisites ------------- diff --git a/airflow-core/docs/authoring-and-scheduling/language-sdks/java.rst b/airflow-core/docs/authoring-and-scheduling/language-sdks/java.rst index 55a80f9967fce..422b6a3985ef0 100644 --- a/airflow-core/docs/authoring-and-scheduling/language-sdks/java.rst +++ b/airflow-core/docs/authoring-and-scheduling/language-sdks/java.rst @@ -30,6 +30,12 @@ scheduling remain in Python; individual tasks delegate to a JVM subprocess that :local: :depth: 2 +API reference +------------- + +The generated API reference for the Java SDK is published with the Airflow documentation at +`Java SDK API Reference `__. + Prerequisites ------------- @@ -226,9 +232,7 @@ Register tasks manually in a ``BundleBuilder``: } } -See the Java SDK's published JavaDoc for more details. - -.. TODO: (AIP-108) Put a link here once we publish the JavaDoc. +See the `Java SDK API Reference `__ for more details. .. _java-sdk/logging: diff --git a/airflow-core/docs/authoring-and-scheduling/timetable.rst b/airflow-core/docs/authoring-and-scheduling/timetable.rst index b19cc80211392..8724330057efb 100644 --- a/airflow-core/docs/authoring-and-scheduling/timetable.rst +++ b/airflow-core/docs/authoring-and-scheduling/timetable.rst @@ -197,7 +197,7 @@ DeltaDataIntervalTimetable ^^^^^^^^^^^^^^^^^^^^^^^^^^ A timetable that schedules data intervals with a time delta. You can select it by providing a -:class:`datetime.timedelta` or ``dateutil.relativedelta.relativedelta`` to the ``schedule`` parameter of a Dag. +:class:`DeltaDataIntervalTimetable` to the ``schedule`` parameter of a Dag. This timetable focuses on the data interval value and does not necessarily align execution dates with arbitrary bounds, such as the start of day or of hour. @@ -206,7 +206,12 @@ arbitrary bounds, such as the start of day or of hour. .. code-block:: python - @dag(schedule=datetime.timedelta(minutes=30)) + from datetime import timedelta + + from airflow.sdk import dag, DeltaDataIntervalTimetable + + + @dag(schedule=DeltaDataIntervalTimetable(timedelta(minutes=30))) def example_dag(): pass @@ -216,17 +221,18 @@ CronDataIntervalTimetable ^^^^^^^^^^^^^^^^^^^^^^^^^ A timetable that accepts a cron expression, creates data intervals according to the interval between each cron -trigger points, and triggers a Dag run at the end of each data interval. +trigger points, and triggers a Dag run at the end of each data interval. You can select it by providing a +:class:`CronDataIntervalTimetable` to the ``schedule`` parameter of a Dag. .. seealso:: `Differences between "trigger" and "data interval" timetables`_ .. seealso:: `Differences between the cron and delta data interval timetables`_ -Select this timetable by providing a valid cron expression as a string to the ``schedule`` -parameter of a Dag, as described in the :doc:`../core-concepts/dags` documentation. - .. code-block:: python - @dag(schedule="0 1 * * 3") # At 01:00 on Wednesday. + from airflow.sdk import dag, CronDataIntervalTimetable + + + @dag(schedule=CronDataIntervalTimetable("0 1 * * 3")) # At 01:00 on Wednesday. def example_dag(): pass diff --git a/airflow-core/docs/best-practices.rst b/airflow-core/docs/best-practices.rst index eb7306b041b69..724398c9f8277 100644 --- a/airflow-core/docs/best-practices.rst +++ b/airflow-core/docs/best-practices.rst @@ -83,7 +83,7 @@ Communication -------------- Airflow executes tasks of a Dag on different servers in case you are using :doc:`Kubernetes executor ` or :doc:`Celery executor `. -Therefore, you should not store any file or config in the local filesystem as the next task is likely to run on a different server without access to it — for example, a task that downloads the data file that the next task processes. +Therefore, you should not store any file or config in the local filesystem as the downstream task is likely to run on a different server without access to it — for example, a task that downloads the data file that the downstream task processes. In the case of :class:`Local executor `, storing a file on disk can make retries harder e.g., your task requires a config file that is deleted by another task in Dag. @@ -815,7 +815,7 @@ Self-Checks ------------ You can also implement checks in a Dag to make sure the tasks are producing the results as expected. -As an example, if you have a task that pushes data to S3, you can implement a check in the next task. For example, the check could +As an example, if you have a task that pushes data to S3, you can implement a check in the downstream task. For example, the check could make sure that the partition is created in S3 and perform some simple checks to determine if the data is correct. @@ -852,7 +852,7 @@ You can use environment variables to parameterize the Dag. Mocking variables and connections ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When you write tests for code that uses variables or a connection, you must ensure that they exist when you run the tests. The obvious solution is to save these objects to the database so they can be read while your code is executing. However, reading and writing objects to the database are burdened with additional time overhead. In order to speed up the test execution, it is worth simulating the existence of these objects without saving them to the database. For this, you can create environment variables with mocking :any:`os.environ` using :meth:`unittest.mock.patch.dict`. +When you write tests for code that uses variables or a connection, you must ensure that they exist when you run the tests. The obvious solution is to save these objects to the database so they can be read while your code is executing. However, reading and writing objects to the database are burdened with additional time overhead. In order to speed up the test execution, it is worth simulating the existence of these objects without saving them to the database. For this, you can create environment variables with mocking :data:`os.environ` using :meth:`unittest.mock.patch.dict`. For variable, use :envvar:`AIRFLOW_VAR_{KEY}`. diff --git a/airflow-core/docs/core-concepts/operators.rst b/airflow-core/docs/core-concepts/operators.rst index ac460183c2f7a..6bcf4a3c7140a 100644 --- a/airflow-core/docs/core-concepts/operators.rst +++ b/airflow-core/docs/core-concepts/operators.rst @@ -303,6 +303,13 @@ Alternatively, Jinja can also be instructed to render a native Python object. Th python_callable=transform, ) +.. note:: + + ``NativeEnvironment`` renders values according to Python literal rules. This is useful when a template + should produce a list, dict, number, or boolean, but it also means a string that looks like a number, + such as ``"42"``, can be rendered as the integer ``42``. Keep the default string rendering, use a + callable template field, or add explicit quoting if the task needs the value to stay a string. + .. _concepts:reserved-keywords: diff --git a/airflow-core/docs/core-concepts/overview.rst b/airflow-core/docs/core-concepts/overview.rst index ab12b6afdfd6f..1f2b1ad8a11bf 100644 --- a/airflow-core/docs/core-concepts/overview.rst +++ b/airflow-core/docs/core-concepts/overview.rst @@ -192,6 +192,91 @@ code is never executed in the context of the *scheduler*. bundle version when dispatching each task. If needed, the cadence of sync and scan of the *Dag bundle* can be configured. +Task execution architecture +--------------------------- + +The diagrams above show how Airflow's components are *deployed*. The diagrams below instead show what happens +*inside a worker when a task actually runs* — how the Task SDK, the Supervisor and Coordinator processes, and +the language runtimes work together: which processes are involved, and the classes and protocols they use to +communicate. + +.. _overview-task-sdk-execution-architecture: + +Python Task SDK execution +......................... + +When a *worker* actually runs a task, it does not run the user's code directly. Instead it starts a +lightweight **Supervisor** that runs in its own **native operating-system process** and +*forks* a second native process in which the **Task SDK** runtime (``task_runner``) executes the user code. +The two processes talk over a socket, and the Supervisor is the only side that ever holds the short-lived +task JWT or talks to the *Execution API* — the user's code never sees the token and never touches the +database. + +The same runtime can also run *in-process* (a single Python process, no fork, no sockets, no HTTP) for +``dag.test()`` and local runs. The diagram below contrasts the two paths and marks where each Python process +lives: + +.. image:: ../img/diagram_task_sdk_execution_architecture.png + +The message flow of a supervised run — startup, running the user code, proxied Connection/Variable/XCom +lookups, heartbeats, and reporting the final state — is shown below as a sequence diagram, with each process +on its own lifeline. The **Supervisor** sits in the middle, so the Task ↔ Supervisor request/response +round-trip (the task asks for a Connection/Variable/XCom and gets the answer back) reads as arrows going back +and forth between neighboring lifelines. Each arrow is numbered, colored by its sender, and labeled with the +message class or protocol used: + +.. image:: ../img/diagram_task_sdk_execution_sequence.png + +.. _overview-non-python-language-sdks: + +Non-Python language SDKs (Go and Java) +...................................... + +The Task Execution Interface (TEI) introduced in AIP-72 is language-agnostic, so a task can also be written in +a **compiled, non-Python language**. A Python Dag still declares the task with ``@task.stub(queue=...)`` (so +Python and non-Python tasks can be mixed in one Dag), but the actual work is delegated to the matching runtime. +There are currently **two different integration styles** — the Go SDK runs a standalone worker, while the Java +SDK plugs into the existing Python Supervisor. + +.. _overview-go-sdk-architecture: + +**Go SDK — standalone edge worker.** The `Go Task SDK +`_ has **no Python Supervisor and no msgpack +stdin socket**. A long-running, compiled **edge worker** (``airflow-go-edge-worker``) *pulls* work from the +**Edge Executor API**, launches the user's compiled Dag bundle as a **go-plugin (gRPC) subprocess**, and +invokes the task over gRPC. The task then uses the **native TEI client** to reach the **Execution API** +directly over HTTPS — so, unlike the Python task, it holds the task JWT itself: + +.. image:: ../img/diagram_native_language_sdk_architecture.png + +.. _overview-java-sdk-architecture: + +**Java (JVM) SDK — Coordinator plugged into the Supervisor.** The `Java Task SDK +`_ takes the opposite approach: it *reuses* the +existing Python Supervisor through a new **Coordinator** layer. ``CoordinatorManager`` resolves the task's +``queue`` to a ``BaseCoordinator`` — ``JavaCoordinator`` for the ``java`` queue, or the built-in +``_PythonCoordinator`` otherwise. ``JavaCoordinator`` opens two loopback-TCP servers, spawns a **JVM bundle +process** with ``subprocess.Popen``, and drives it with ``_JavaActivitySubprocess`` (a subclass of the shared +``ActivitySubprocess``). The JVM connects *back* over TCP and speaks the **same msgpack protocol** as a Python +task, so the Python side heartbeats, manages state, and **proxies every Execution-API call** — meaning the JVM +task, like a Python task, never holds the task JWT itself: + +.. image:: ../img/diagram_java_sdk_execution_architecture.png + +The end-to-end workflow of a Java task — from ``@task.stub`` through the coordinator, the JVM subprocess, the +proxied Connection/Variable/XCom lookups, and reporting the final state — is shown below as a sequence diagram. +As above, the **Supervisor** is the central lifeline, so the JVM ↔ Supervisor round-trip over loopback TCP is +drawn as arrows going back and forth to its neighbours: + +.. image:: ../img/diagram_java_sdk_execution_sequence.png + +.. note:: + + Both the Go and Java SDKs are **experimental** and under active development. See the `Go Task SDK + documentation `_ and the `Java Task SDK + documentation `_ for current status, + quick-starts, and known limitations. + .. _overview:workloads: Workloads diff --git a/airflow-core/docs/core-concepts/params.rst b/airflow-core/docs/core-concepts/params.rst index ac5df462fac98..2f70611e88c29 100644 --- a/airflow-core/docs/core-concepts/params.rst +++ b/airflow-core/docs/core-concepts/params.rst @@ -145,6 +145,11 @@ This way, the :class:`~airflow.sdk.definitions.param.Param`'s type is respected ), ) +Because ``render_template_as_native_obj=True`` uses Jinja's native rendering, values that look like +Python literals can also be converted. For example, a string value of ``"42"`` may be rendered as the +integer ``42``. Leave native rendering disabled, use a callable template field, or quote the value +explicitly when the task must receive a string. + Another way to access your param is via a task's ``context`` kwarg. .. code-block:: diff --git a/airflow-core/docs/howto/deadline-alerts.rst b/airflow-core/docs/howto/deadline-alerts.rst index 8e729516fefcb..ac07047f34587 100644 --- a/airflow-core/docs/howto/deadline-alerts.rst +++ b/airflow-core/docs/howto/deadline-alerts.rst @@ -420,6 +420,10 @@ references for specific integrations like calendars or other data sources. To do a class that inherits from BaseDeadlineReference, add the ``@deadline_reference`` decorator, and implement an ``_evaluate_with()`` method. +The decorator may be used with or without parentheses. Used bare, or with empty parentheses, the +reference is evaluated when a new Dag run is created; pass a ``DeadlineReference.TYPES`` value to +choose a different time. + **Creating a Custom Reference** @@ -447,17 +451,19 @@ implement an ``_evaluate_with()`` method. class MyQueuedReference(BaseDeadlineReference): """A custom reference evaluated when Dag runs are queued.""" - required_kwargs = {"custom_param"} + # Ask for the Dag run context values supplied by Airflow; see notes below. + required_kwargs = {"dag_id", "run_id"} def _evaluate_with(self, *, session: Session, **kwargs) -> datetime: - custom_value = kwargs["custom_param"] - # Use custom_value in your calculation + dag_id = kwargs["dag_id"] + run_id = kwargs["run_id"] + # Use dag_id and run_id in your calculation return your_datetime **Using a Custom Reference in a Dag** -Once registered [see notes below], use your custom references in Dag definitions like any other reference: +Once registered, use your custom references in Dag definitions like any other reference: .. code-block:: python @@ -467,7 +473,7 @@ Once registered [see notes below], use your custom references in Dag definitions with DAG( dag_id="custom_reference_example", deadline=DeadlineAlert( - reference=DeadlineReference.MyCustomDecoratedReference(), + reference=DeadlineReference.MyCustomDecoratedReference, interval=timedelta(hours=2), callback=AsyncCallback(my_callback), ), @@ -520,7 +526,13 @@ followed by a more urgent escalation if the Dag is still running. **Important Notes:** * **Timezone Awareness**: Always return timezone-aware datetime objects. +* **No-argument Construction**: Custom references are instantiated during registration, so they must be + constructible with no arguments. If your reference takes parameters, decorate it with ``@dataclass`` + and give every field a default value. * **Plugin Placement**: One convenient place for custom references is in the plugins directory. * **API Server Restart**: Restart the Airflow API Server after adding or modifying custom references. -* **Required Parameters**: Use ``required_kwargs`` to specify parameters your reference needs. +* **Required Parameters**: ``required_kwargs`` declares which Dag run context values Airflow should + forward to ``_evaluate_with()``. Only ``dag_id`` and ``run_id`` are available; declaring anything + else raises a ``ValueError`` when the deadline is evaluated. To configure a reference itself, give + it constructor fields or read from an Airflow Variable. * **Database Access**: Use the ``session`` parameter for Airflow database queries if needed. diff --git a/airflow-core/docs/howto/dynamic-dag-generation.rst b/airflow-core/docs/howto/dynamic-dag-generation.rst index 407ea8e05b673..78c89db6ca849 100644 --- a/airflow-core/docs/howto/dynamic-dag-generation.rst +++ b/airflow-core/docs/howto/dynamic-dag-generation.rst @@ -22,7 +22,7 @@ Dynamic Dag Generation This document describes creation of Dags that have a structure generated dynamically, but where the number of tasks in the Dag does not change between Dag Runs. If you want to implement a Dag where number of Tasks (or -Task Groups as of Airflow 2.6) can change based on the output/result of previous tasks, see +Task Groups as of Airflow 2.6) can change based on the output/result of upstream tasks, see :doc:`/authoring-and-scheduling/dynamic-task-mapping`. .. note:: Consistent sequence of generating tasks and task groups diff --git a/airflow-core/docs/howto/set-config.rst b/airflow-core/docs/howto/set-config.rst index c35df0f4c894b..31c6b5362518b 100644 --- a/airflow-core/docs/howto/set-config.rst +++ b/airflow-core/docs/howto/set-config.rst @@ -106,6 +106,7 @@ The following config options support this ``_cmd`` and ``_secret`` version: * ``password`` in ``[atlas]`` section * ``smtp_password`` in ``[smtp]`` section * ``secret_key`` in ``[api]`` section +* ``jwt_secret`` in ``[api_auth]`` section The ``_cmd`` config options can also be set using a corresponding environment variable the same way the usual config options can. For example: diff --git a/airflow-core/docs/howto/timetable.rst b/airflow-core/docs/howto/timetable.rst index 90308ca42e52e..0fc6fa9ea5651 100644 --- a/airflow-core/docs/howto/timetable.rst +++ b/airflow-core/docs/howto/timetable.rst @@ -238,6 +238,13 @@ purpose, we'd want to do something like: run_after=DateTime.combine(end.date(), self._schedule_at).replace(tzinfo=UTC), ) +If you adapt the first-run logic from ``AfterWorkdayTimetable`` for a custom +``schedule_at`` value, compare the candidate time with ``self._schedule_at``. +The midnight-specific check in the earlier example is only correct when runs +are scheduled at ``00:00``. For example, an earliest time of ``06:00`` should +still allow an ``08:00`` same-day run, while an earliest time of ``09:00`` should +move to the next workday. + However, since the timetable is a part of the Dag, we need to tell Airflow how to serialize it with the context we provide in ``__init__``. This is done by implementing two additional methods on our timetable class: diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_architecture.md5sum b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.md5sum new file mode 100644 index 0000000000000..377507bd88454 --- /dev/null +++ b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.md5sum @@ -0,0 +1 @@ +061e71105ed4ce16e740a942073b7ace diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_architecture.png b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.png new file mode 100644 index 0000000000000..8fa1e5e6255b6 Binary files /dev/null and b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.png differ diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_architecture.py b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.py new file mode 100644 index 0000000000000..25be42106221a --- /dev/null +++ b/airflow-core/docs/img/diagram_java_sdk_execution_architecture.py @@ -0,0 +1,287 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "rich>=13.6.0", +# "graphviz>=0.20.1", +# ] +# /// +""" +Architecture diagram for the Java (JVM) Task SDK. + +Unlike the Go SDK (a standalone edge worker), the Java SDK plugs into the *same* +Python Supervisor via a new **Coordinator** layer: + +* ``CoordinatorManager`` resolves the task's ``queue`` to a ``BaseCoordinator`` + (``JavaCoordinator`` for the ``java`` queue, ``_PythonCoordinator`` otherwise); +* ``JavaCoordinator.execute_task()`` opens two loopback-TCP servers, spawns a JVM + bundle process with ``subprocess.Popen``, and drives it with + ``_JavaActivitySubprocess`` — a subclass of the shared ``ActivitySubprocess``; +* the JVM process connects *back* over TCP and speaks the same msgpack protocol as + a Python task, so the Python side heartbeats, proxies every Execution-API call, + and manages state. The JVM task therefore **never holds the task JWT**. + +Rendered with graphviz directly so labels sit inside sized shapes: 3-D box = +native OS process, rounded box = an object inside a process, component = a server +app, cylinder = the database, note = a caption. +""" + +from __future__ import annotations + +from pathlib import Path + +import graphviz +from rich.console import Console + +MY_DIR = Path(__file__).parent +MY_FILENAME = Path(__file__).with_suffix("").name + +console = Console(width=400, color_system="standard") + +# (fill, border) per role — consistent with the other Task SDK diagrams. +COORD = ("#ede7f6", "#5e35b1") # Coordinator layer (Python, deep purple) +SUP = ("#e3f2fd", "#1565c0") # Supervisor / ActivitySubprocess + Client (blue) +JVM = ("#fbe9e7", "#d84315") # JVM SDK runtime (deep orange) +USER = ("#e8f5e9", "#2e7d32") # user task code (green) +API = ("#fdecea", "#c62828") # Execution API (red) +NEUTRAL = ("#eceff1", "#455a64") # database +NOTE = ("#fffde7", "#f9a825") # caption + + +def _label(title: str, sub: str | None = None) -> str: + html = f"<{title}" + if sub: + html += f'
{sub}' + return html + ">" + + +def _node(g, node_id: str, title: str, sub: str, *, shape: str, theme: tuple[str, str]) -> None: + fill, border = theme + style = "filled" if shape in ("box3d", "cylinder", "component", "note") else "rounded,filled" + g.node( + node_id, + label=_label(title, sub), + shape=shape, + style=style, + fillcolor=fill, + color=border, + penwidth="2", + margin="0.18,0.12", + ) + + +def generate_java_sdk_execution_architecture_diagram(): + image_file = MY_DIR / f"{MY_FILENAME}.png" + console.print(f"[bright_blue]Generating architecture image {image_file}") + + g = graphviz.Digraph("java_sdk_execution_architecture") + g.attr( + rankdir="TB", + splines="spline", + nodesep="0.6", + ranksep="0.9", + pad="0.5", + bgcolor="white", + fontname="Helvetica", + newrank="true", + compound="true", + ) + g.attr("node", fontname="Helvetica", fontsize="13", fontcolor="#102027") + g.attr("edge", fontname="Helvetica", fontsize="10", penwidth="1.8", color="#546e7a") + + # ------------------------------------------------------------------ # + # Worker host — native OS processes. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_host") as host: + host.attr( + label="Worker host — native OS processes", + labelloc="t", + style="rounded,filled", + fillcolor="#f7f7fb", + color="#90a4ae", + penwidth="1.5", + fontsize="16", + fontname="Helvetica-Bold", + margin="18", + ) + + with host.subgraph(name="cluster_sup") as sup: + sup.attr( + label="Supervisor process · native OS process (Python)", + labelloc="t", + style="rounded,filled", + fillcolor="#eef0fb", + color=SUP[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + sup, + "coord_mgr", + "CoordinatorManager.for_queue()", + "resolves the task queue → a coordinator via
[sdk] queue_to_coordinator / [sdk] coordinators", + shape="box", + theme=COORD, + ) + _node( + sup, + "java_coord", + "JavaCoordinator (BaseCoordinator)", + "execute_task(client): open two loopback-TCP
servers, subprocess.Popen(java -jar bundle)", + shape="box", + theme=COORD, + ) + _node( + sup, + "supervisor", + "_JavaActivitySubprocess", + "subclass of the shared ActivitySubprocess
heartbeat · proxy every API call · manage state", + shape="box3d", + theme=SUP, + ) + _node( + sup, + "client", + "Client", + "authenticated Execution API client
holds the short-lived task JWT", + shape="box", + theme=SUP, + ) + sup.edge( + "coord_mgr", "java_coord", style="dotted", color=COORD[1], arrowhead="vee", label="picks" + ) + sup.edge( + "java_coord", "supervisor", style="dotted", color=SUP[1], arrowhead="vee", label="drives" + ) + sup.edge("supervisor", "client", style="dotted", color=SUP[1], arrowhead="none") + + with host.subgraph(name="cluster_jvm") as jvm: + jvm.attr( + label="JVM bundle subprocess · native OS process (JVM) · runs USER CODE", + labelloc="t", + style="rounded,filled", + fillcolor="#fdefe9", + color=JVM[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + jvm, + "server", + "Server.serve(bundle)", + "bundle JAR entry point (Main-Class)
Kotlin runtime · connects back over TCP", + shape="box3d", + theme=JVM, + ) + _node( + jvm, + "task", + "Task.execute(Context, Client)", + "your Java / Kotlin task [user code]
Context = static run data · Client = API accessors", + shape="box3d", + theme=USER, + ) + _node( + jvm, + "comm", + "CoordinatorComm / Frame", + "msgpack framing (Kotlin)", + shape="box", + theme=JVM, + ) + jvm.edge("server", "task", style="dotted", color=JVM[1], arrowhead="vee", label="invokes") + jvm.edge("task", "comm", style="dotted", color=JVM[1], arrowhead="none") + + # Loopback-TCP comms between the two native OS processes (JVM connects back). + g.edge( + "comm", + "supervisor", + label="msgpack frames over loopback TCP (127.0.0.1)\nJVM connects back · ToSupervisor / ToTask", + color=JVM[1], + fontcolor=JVM[1], + dir="both", + penwidth="2.2", + ) + g.edge( + "comm", + "supervisor", + label="structured logs\n(second TCP channel)", + color=JVM[1], + fontcolor="#a1674f", + style="dashed", + ) + + # ------------------------------------------------------------------ # + # API server — separate process / host. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_server") as server: + server.attr( + label="API server · separate process / host", + labelloc="t", + style="rounded,filled", + fillcolor="#fdeeec", + color=API[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + server, + "execution_api", + "Execution API", + "FastAPI · TEI / AIP-72", + shape="component", + theme=API, + ) + _node(server, "metadata_db", "Metadata DB", "", shape="cylinder", theme=NEUTRAL) + server.edge("execution_api", "metadata_db", style="dotted", color=API[1], dir="both") + + g.edge( + "client", + "execution_api", + label="HTTPS + task JWT\n(proxied for the JVM task)", + color=API[1], + fontcolor=API[1], + penwidth="2.2", + ) + + # Contrast caption. + _node( + g, + "note", + "How it differs", + "vs Python task: same Supervisor, but a JVM subprocess over loopback TCP
" + "instead of a forked Python process over a UNIX socketpair
" + "vs Go SDK: the JVM task does not hold the JWT and does not call the
" + "Execution API directly — the Python Supervisor proxies every call", + shape="note", + theme=NOTE, + ) + g.edge("supervisor", "note", style="invis") + + g.render(outfile=str(image_file), format="png", cleanup=True) + console.print(f"[green]Generated architecture image {image_file}") + + +if __name__ == "__main__": + generate_java_sdk_execution_architecture_diagram() diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_sequence.md5sum b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.md5sum new file mode 100644 index 0000000000000..590d397530f46 --- /dev/null +++ b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.md5sum @@ -0,0 +1 @@ +5c927fe1f455ae4fc5bf77ebf7fc7ae7 diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_sequence.png b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.png new file mode 100644 index 0000000000000..71cd2ebbc4ae0 Binary files /dev/null and b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.png differ diff --git a/airflow-core/docs/img/diagram_java_sdk_execution_sequence.py b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.py new file mode 100644 index 0000000000000..3c9d4ae96587c --- /dev/null +++ b/airflow-core/docs/img/diagram_java_sdk_execution_sequence.py @@ -0,0 +1,327 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "rich>=13.6.0", +# "graphviz>=0.20.1", +# ] +# /// +""" +UML-style sequence diagram for a Java (JVM) task run. + +Each participant gets its own vertical lifeline; messages are horizontal arrows +between lifelines, read top to bottom. The **Supervisor** (Python) sits in the +middle so the JVM <-> Supervisor round-trip (the JVM asks for a +Connection/Variable/XCom over loopback TCP and gets the answer back) and the +Supervisor <-> Execution API round-trip are both drawn as adjacent request/ +response pairs. The JVM task never talks to the Execution API — the Supervisor +proxies every call, so the JVM never holds the task JWT. + +Arrows are colored by sender: + +* teal — Scheduler +* purple — Coordinator layer (CoordinatorManager / JavaCoordinator) +* blue — Supervisor (_JavaActivitySubprocess) → JVM / Execution API +* orange — JVM SDK runtime / user code → Supervisor (over loopback TCP) +* red — Execution API → Supervisor (responses) + +Graphviz has no native sequence-diagram shape, so lifelines are drawn as dashed +vertical edges through invisible way-points, one row per message, with each +message as a ``constraint=false`` horizontal edge on that row. +""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any + +import graphviz +from rich.console import Console + +MY_DIR = Path(__file__).parent +MY_FILENAME = Path(__file__).with_suffix("").name + +console = Console(width=400, color_system="standard") + +# (fill, border) per participant — consistent with the other Task SDK diagrams. +SCHED = ("#e0f2f1", "#00695c") # scheduler (teal) +COORD = ("#ede7f6", "#5e35b1") # coordinator layer (purple) +SUP = ("#e3f2fd", "#1565c0") # supervisor (blue) +JVM = ("#fbe9e7", "#d84315") # JVM runtime + user code (orange) +API = ("#fdecea", "#c62828") # execution API (red) + +SCHED_C, COORD_C, SUP_C, JVM_C, API_C = SCHED[1], COORD[1], SUP[1], JVM[1], API[1] + +LIFELINE = "#b0bec5" + +# Participants, left to right. Supervisor is central so both round-trips are +# drawn between neighboring lifelines. +PARTICIPANTS = [ + ("sched", "Scheduler", "creates the ExecuteTask workload", SCHED), + ("jvm", "JVM subprocess", "Server · Task · user code", JVM), + ("sup", "Supervisor (Python)", "Coordinator · _JavaActivitySubprocess", SUP), + ("api", "Execution API", "FastAPI · TEI / AIP-72", API), +] + +# Each step is one row. A "msg" is an arrow between two lifelines; a "self" is an +# activation box on a single lifeline (local processing, no message). +STEPS: list[dict[str, Any]] = [ + { + "kind": "msg", + "from": "sched", + "to": "sup", + "color": SCHED_C, + "label": 'ExecuteTask workload\n(carries queue="java")', + }, + { + "kind": "self", + "actor": "sup", + "theme": COORD, + "text": 'CoordinatorManager.for_queue("java") → JavaCoordinator\nopen two loopback-TCP servers', + }, + { + "kind": "msg", + "from": "sup", + "to": "jvm", + "color": COORD_C, + "label": "subprocess.Popen(java -jar bundle)\n(spawn the JVM)", + }, + { + "kind": "msg", + "from": "jvm", + "to": "sup", + "color": JVM_C, + "label": "TCP connect back\n(comm + logs channels)", + }, + {"kind": "msg", "from": "sup", "to": "api", "color": SUP_C, "label": "PATCH .../run\n(TI started)"}, + { + "kind": "msg", + "from": "api", + "to": "sup", + "color": API_C, + "style": "dashed", + "label": "TIRunContext\n(+ heartbeat every ~N s)", + }, + { + "kind": "msg", + "from": "sup", + "to": "jvm", + "color": SUP_C, + "label": "StartupDetails (msgpack over TCP)\n→ build Context", + }, + {"kind": "self", "actor": "jvm", "theme": JVM, "text": "Task.execute(Context, Client) [USER CODE]"}, + { + "kind": "msg", + "from": "jvm", + "to": "sup", + "color": JVM_C, + "label": "getConnection / getVariable / getXCom / setXCom\n(_RequestFrame, msgpack over TCP)", + }, + { + "kind": "msg", + "from": "sup", + "to": "api", + "color": SUP_C, + "label": "GET connection / variable / xcom\n(HTTPS + task JWT)", + }, + {"kind": "msg", "from": "api", "to": "sup", "color": API_C, "style": "dashed", "label": "result"}, + { + "kind": "msg", + "from": "sup", + "to": "jvm", + "color": SUP_C, + "label": "*Result (msgpack over TCP)\nabove 4 messages repeat per lookup", + }, + { + "kind": "msg", + "from": "jvm", + "to": "sup", + "color": JVM_C, + "label": "final state (success / failed / up-for-retry)\nmsgpack over TCP", + }, + {"kind": "msg", "from": "sup", "to": "api", "color": SUP_C, "label": "PATCH .../state\n(+ upload logs)"}, + { + "kind": "msg", + "from": "sup", + "to": "sched", + "color": SCHED_C, + "style": "dashed", + "label": "JVM process exits →\nexecute_task() returns the exit code", + }, +] + + +def _label(title: str, sub: str | None = None) -> str: + html = f"<{title}" + if sub: + safe = sub.replace("\n", "
") + html += f'
{safe}' + return html + ">" + + +def _header(g, pid: str, title: str, sub: str, theme: tuple[str, str]) -> None: + fill, border = theme + g.node( + f"{pid}__h", + label=_label(title, sub), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.24,0.14", + ) + + +def _activation(g, node_id: str, num: int, text: str, theme: tuple[str, str]) -> None: + fill, border = theme + g.node( + node_id, + label=_label(f"{num}", text), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.2,0.12", + ) + + +def _waypoint(g, node_id: str) -> None: + g.node(node_id, shape="point", width="0.02", color=LIFELINE) + + +def _edge_label(num: int, text: str) -> str: + # Pad the description on every side: blank lines above and below keep it clear + # of the arrow line, and leading/trailing spaces on each line keep it clear of + # the lifelines on the left and right. + lines = f"{num} · {text}".split("\n") + padded = "\n".join(f" {line} " for line in lines) + return f" \n{padded}\n " + + +def _build_sequence(g) -> None: + ids = [p[0] for p in PARTICIPANTS] + + # --- participant headers, ordered left-to-right on the top rank ---------- # + with g.subgraph() as top: + top.attr(rank="same") + for pid, title, sub, theme in PARTICIPANTS: + _header(top, pid, title, sub, theme) + for a, b in zip(ids, ids[1:]): + g.edge(f"{a}__h", f"{b}__h", style="invis") + + # --- one rank per step; way-points on every lifeline, box on the actor --- # + for i, step in enumerate(STEPS): + with g.subgraph() as row: + row.attr(rank="same") + for pid, _, _, theme in PARTICIPANTS: + nid = f"{pid}__{i}" + if step["kind"] == "self" and step["actor"] == pid: + _activation(row, nid, i + 1, step["text"], step.get("theme", theme)) + else: + _waypoint(row, nid) + + # --- dashed vertical lifelines through the way-points -------------------- # + for pid, *_ in PARTICIPANTS: + chain = [f"{pid}__h"] + [f"{pid}__{i}" for i in range(len(STEPS))] + for a, b in zip(chain, chain[1:]): + g.edge(a, b, style="dashed", arrowhead="none", color=LIFELINE, penwidth="1.3") + + # --- message arrows (horizontal, do not constrain ranking) --------------- # + for i, step in enumerate(STEPS): + if step["kind"] != "msg": + continue + g.edge( + f"{step['from']}__{i}", + f"{step['to']}__{i}", + xlabel=_edge_label(i + 1, step["label"]), + color=step["color"], + fontcolor=step["color"], + style=step.get("style", "solid"), + arrowhead="vee", + penwidth="2", + constraint="false", + ) + + _legend(g) + + +def _legend(g) -> None: + entries = [ + ("lg_sched", "Scheduler → Supervisor", SCHED), + ("lg_coord", "Coordinator layer (CoordinatorManager / JavaCoordinator)", COORD), + ("lg_sup", "Supervisor → JVM / Execution API", SUP), + ("lg_jvm", "JVM (user code) → Supervisor (loopback TCP)", JVM), + ("lg_api", "Execution API → Supervisor (response)", API), + ] + with g.subgraph(name="cluster_legend") as legend: + legend.attr( + label="Arrow color = sender · steps 9–12 repeat per Connection / Variable / XCom lookup", + labelloc="t", + style="rounded,filled", + fillcolor="#fafafa", + color="#b0bec5", + fontsize="12", + fontname="Helvetica-Bold", + margin="12", + ) + for nid, text, theme in entries: + fill, border = theme + legend.node( + nid, + label=_label(text), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.2,0.1", + ) + for a, b in zip([e[0] for e in entries], [e[0] for e in entries][1:]): + legend.edge(a, b, style="invis") + # Anchor the legend below the diagram, on the left. + g.edge(f"sched__{len(STEPS) - 1}", "lg_sched", style="invis") + + +def generate_java_sdk_execution_sequence_diagram(): + image_file = MY_DIR / f"{MY_FILENAME}.png" + console.print(f"[bright_blue]Generating sequence image {image_file}") + + g = graphviz.Digraph("java_sdk_execution_sequence") + g.attr( + rankdir="TB", + splines="line", + forcelabels="true", + nodesep="1.3", + ranksep="1.2", + pad="0.5", + bgcolor="white", + fontname="Helvetica", + ) + g.attr("node", fontname="Helvetica", fontsize="13", fontcolor="#102027") + g.attr("edge", fontname="Helvetica", fontsize="10", penwidth="2", color="#546e7a") + + _build_sequence(g) + + g.render(outfile=str(image_file), format="png", cleanup=True) + console.print(f"[green]Generated sequence image {image_file}") + + +if __name__ == "__main__": + generate_java_sdk_execution_sequence_diagram() diff --git a/airflow-core/docs/img/diagram_native_language_sdk_architecture.md5sum b/airflow-core/docs/img/diagram_native_language_sdk_architecture.md5sum new file mode 100644 index 0000000000000..8149286f36321 --- /dev/null +++ b/airflow-core/docs/img/diagram_native_language_sdk_architecture.md5sum @@ -0,0 +1 @@ +d7f0c11f0b175a82b2bded558ebfa0f1 diff --git a/airflow-core/docs/img/diagram_native_language_sdk_architecture.png b/airflow-core/docs/img/diagram_native_language_sdk_architecture.png new file mode 100644 index 0000000000000..b7e0a71e06db5 Binary files /dev/null and b/airflow-core/docs/img/diagram_native_language_sdk_architecture.png differ diff --git a/airflow-core/docs/img/diagram_native_language_sdk_architecture.py b/airflow-core/docs/img/diagram_native_language_sdk_architecture.py new file mode 100644 index 0000000000000..9f802620ed324 --- /dev/null +++ b/airflow-core/docs/img/diagram_native_language_sdk_architecture.py @@ -0,0 +1,258 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "rich>=13.6.0", +# "graphviz>=0.20.1", +# ] +# /// +""" +Architecture diagram for a native-language (compiled) Task SDK. + +The Go SDK (``go-sdk/``) is the first implementation; the same shape applies to +any future compiled-language SDK (e.g. Java). Unlike the Python Task SDK there is +**no Python Supervisor and no msgpack stdin socket**: + +* a long-running compiled **edge worker** (``airflow-go-edge-worker``) *pulls* + work from the **Edge Executor API** over HTTP; +* it launches the user's compiled **Dag bundle** as a **go-plugin (gRPC) + subprocess** and invokes the task over gRPC; and +* the task uses the **native Task Execution Interface client** (AIP-72) to reach + the **Execution API** directly over HTTPS — so, unlike the Python task, it holds + the task JWT itself. + +Rendered with graphviz directly so every label sits inside a sized shape: +3-D box = native OS process, rounded box = an object inside a process, +component = a server app, cylinder = the database, note = a caption. +""" + +from __future__ import annotations + +from pathlib import Path + +import graphviz +from rich.console import Console + +MY_DIR = Path(__file__).parent +MY_FILENAME = Path(__file__).with_suffix("").name + +console = Console(width=400, color_system="standard") + +# Soft palette: (fill, border) per role. Kept consistent with the Python Task SDK +# diagrams: user code = green, Execution API = red, DB = grey. +GO = ("#e0f7fa", "#00838f") # compiled edge worker / native clients (Go cyan) +USER = ("#e8f5e9", "#2e7d32") # user task code +EDGE = ("#fff3e0", "#ef6c00") # Edge Executor API (amber) +API = ("#fdecea", "#c62828") # Execution API (red) +NEUTRAL = ("#eceff1", "#455a64") # database +NOTE = ("#fffde7", "#f9a825") # caption + + +def _label(title: str, sub: str | None = None) -> str: + html = f"<{title}" + if sub: + html += f'
{sub}' + return html + ">" + + +def _node(g, node_id: str, title: str, sub: str, *, shape: str, theme: tuple[str, str]) -> None: + fill, border = theme + style = "filled" if shape in ("box3d", "cylinder", "component", "note") else "rounded,filled" + g.node( + node_id, + label=_label(title, sub), + shape=shape, + style=style, + fillcolor=fill, + color=border, + penwidth="2", + margin="0.18,0.12", + ) + + +def generate_native_language_sdk_architecture_diagram(): + image_file = MY_DIR / f"{MY_FILENAME}.png" + console.print(f"[bright_blue]Generating architecture image {image_file}") + + g = graphviz.Digraph("native_language_sdk_architecture") + g.attr( + rankdir="TB", + splines="spline", + nodesep="0.6", + ranksep="0.9", + pad="0.5", + bgcolor="white", + fontname="Helvetica", + newrank="true", + compound="true", + ) + g.attr("node", fontname="Helvetica", fontsize="13", fontcolor="#102027") + g.attr("edge", fontname="Helvetica", fontsize="10", penwidth="1.8", color="#546e7a") + + # ------------------------------------------------------------------ # + # Worker host — compiled native OS processes, no Python runtime. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_host") as host: + host.attr( + label="Worker host — native OS processes (compiled binary · no Python runtime)", + labelloc="t", + style="rounded,filled", + fillcolor="#f4fdff", + color="#90a4ae", + penwidth="1.5", + fontsize="16", + fontname="Helvetica-Bold", + margin="18", + ) + + with host.subgraph(name="cluster_worker") as worker: + worker.attr( + label="Edge-worker process · long-running compiled binary", + labelloc="t", + style="rounded,filled", + fillcolor="#e7fbff", + color=GO[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + worker, + "worker", + "airflow-go-edge-worker", + "register · heartbeat · fetch workloads
report task state · spawn bundle plugins", + shape="box3d", + theme=GO, + ) + _node( + worker, + "edge_client", + "edgeapi.Client", + "Edge Executor API client", + shape="box", + theme=GO, + ) + worker.edge("worker", "edge_client", style="dotted", color=GO[1], arrowhead="none") + + with host.subgraph(name="cluster_bundle") as bundle: + bundle.attr( + label="Dag bundle plugin process · go-plugin (gRPC) subprocess · runs USER CODE", + labelloc="t", + style="rounded,filled", + fillcolor="#edf7ee", + color=USER[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + bundle, + "gotask", + "Go task function", + "your compiled task code, registered in the bundle
holds the task JWT", + shape="box3d", + theme=USER, + ) + _node( + bundle, + "tei_client", + "sdk client → pkg/api", + "native Task Execution Interface client (AIP-72)
" + "VariableClient · ConnectionClient · XComClient", + shape="box", + theme=GO, + ) + bundle.edge("gotask", "tei_client", style="dotted", color=GO[1], arrowhead="none") + + # Worker launches the bundle plugin and invokes the task over gRPC. + g.edge( + "worker", + "gotask", + label="go-plugin gRPC\nExecute(ExecuteTaskWorkload)", + color=GO[1], + fontcolor=GO[1], + penwidth="2.2", + ) + + # ------------------------------------------------------------------ # + # Airflow API server — separate process / host. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_server") as server: + server.attr( + label="Airflow API server · separate process / host", + labelloc="t", + style="rounded,filled", + fillcolor="#fdf6ec", + color="#b0846a", + penwidth="1.5", + fontsize="14", + fontname="Helvetica-Bold", + margin="16", + ) + _node(server, "edge_api", "Edge Executor API", "(edge provider)", shape="component", theme=EDGE) + _node( + server, + "execution_api", + "Execution API", + "FastAPI · TEI / AIP-72", + shape="component", + theme=API, + ) + _node(server, "metadata_db", "Metadata DB", "", shape="cylinder", theme=NEUTRAL) + server.edge("edge_api", "metadata_db", style="dotted", color=EDGE[1], dir="both") + server.edge("execution_api", "metadata_db", style="dotted", color=API[1], dir="both") + + g.edge( + "edge_client", + "edge_api", + label="HTTP + Edge API JWT\nregister · heartbeat · poll for\nworkloads · report state", + color=EDGE[1], + fontcolor=EDGE[1], + penwidth="2.2", + ) + g.edge( + "tei_client", + "execution_api", + label="HTTPS + task JWT\nVariables · Connections · XComs · state", + color=API[1], + fontcolor=API[1], + penwidth="2.2", + ) + + # Contrast caption. + _node( + g, + "note", + "Contrast with the Python Task SDK", + "no Python Supervisor · no msgpack stdin socket
" + "work is pulled via the Edge API (not pushed by an executor)
" + "the task runs as a compiled gRPC plugin and calls the
" + "Execution API directly — so it holds the JWT itself", + shape="note", + theme=NOTE, + ) + g.edge("worker", "note", style="invis") + + g.render(outfile=str(image_file), format="png", cleanup=True) + console.print(f"[green]Generated architecture image {image_file}") + + +if __name__ == "__main__": + generate_native_language_sdk_architecture_diagram() diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_architecture.md5sum b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.md5sum new file mode 100644 index 0000000000000..b647a5229b359 --- /dev/null +++ b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.md5sum @@ -0,0 +1 @@ +a197a4d28941db9bff348c56c54acaa5 diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_architecture.png b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.png new file mode 100644 index 0000000000000..7550e570489c7 Binary files /dev/null and b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.png differ diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_architecture.py b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.py new file mode 100644 index 0000000000000..bdaa62d71b1d4 --- /dev/null +++ b/airflow-core/docs/img/diagram_task_sdk_execution_architecture.py @@ -0,0 +1,291 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "rich>=13.6.0", +# "graphviz>=0.20.1", +# ] +# /// +""" +Architecture diagram for Task SDK execution. + +Contrasts the two ways a task is run: + +* the *supervised* path used in production, where the Supervisor ("Coordinator") + and the Task each run in their own **native OS process** (Python interpreter) + and talk over a socket, with the Supervisor proxying the remote Execution API; and +* the *native / in-process* path (``dag.test()`` and local runs), where the whole + thing runs **inside a single Python process** with in-memory queues instead of + sockets and an in-memory Execution API instead of HTTP. + +Rendered with graphviz directly (rather than the ``diagrams`` library) so every +label sits *inside* a sized shape — nothing overlaps, and each kind of thing gets +its own shape: 3-D box = native OS process, rounded box = an object inside a +process, component = an ASGI/FastAPI app, cylinder = the database. +""" + +from __future__ import annotations + +from pathlib import Path + +import graphviz +from rich.console import Console + +MY_DIR = Path(__file__).parent +MY_FILENAME = Path(__file__).with_suffix("").name + +console = Console(width=400, color_system="standard") + +# Soft, modern palette: (fill, border) per role. +TASK = ("#e8f5e9", "#2e7d32") # Task SDK / user code +SUP = ("#e3f2fd", "#1565c0") # Supervisor ("Coordinator") +API = ("#fdecea", "#c62828") # Execution API +NATIVE = ("#f3e5f5", "#7b1fa2") # in-process "native" path +NEUTRAL = ("#eceff1", "#455a64") # database + + +def _label(title: str, sub: str | None = None) -> str: + """Build an HTML-like label: bold title over a smaller, dimmer subtitle.""" + html = f"<{title}" + if sub: + html += f'
{sub}' + return html + ">" + + +def _node(g, node_id: str, title: str, sub: str, *, shape: str, theme: tuple[str, str]) -> None: + fill, border = theme + style = "filled" if shape in ("box3d", "cylinder", "component") else "rounded,filled" + g.node( + node_id, + label=_label(title, sub), + shape=shape, + style=style, + fillcolor=fill, + color=border, + penwidth="2", + margin="0.18,0.12", + ) + + +def generate_task_sdk_execution_architecture_diagram(): + image_file = MY_DIR / f"{MY_FILENAME}.png" + console.print(f"[bright_blue]Generating architecture image {image_file}") + + g = graphviz.Digraph("task_sdk_execution_architecture") + g.attr( + rankdir="TB", + splines="spline", + nodesep="0.6", + ranksep="0.9", + pad="0.5", + bgcolor="white", + fontname="Helvetica", + newrank="true", + compound="true", + ) + g.attr("node", fontname="Helvetica", fontsize="13", fontcolor="#102027") + g.attr("edge", fontname="Helvetica", fontsize="10", penwidth="1.8", color="#546e7a") + + # ------------------------------------------------------------------ # + # Production / supervised path — several native OS processes. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_prod") as prod: + prod.attr( + label="Production (supervised) path — one worker slot = several native OS processes", + labelloc="t", + style="rounded,filled", + fillcolor="#f7fbff", + color="#90a4ae", + penwidth="1.5", + fontsize="16", + fontname="Helvetica-Bold", + margin="18", + ) + + with prod.subgraph(name="cluster_task") as task: + task.attr( + label="Task process · forked native OS process (Python) · runs USER CODE", + labelloc="t", + style="rounded,filled", + fillcolor="#edf7ee", + color=TASK[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + task, + "task_runner", + "task_runner.run()", + "RuntimeTaskInstance
→ Operator.execute() [user code]
never sees the JWT · no DB access", + shape="box3d", + theme=TASK, + ) + _node( + task, + "comms", + "SUPERVISOR_COMMS", + "CommsDecoder", + shape="box", + theme=TASK, + ) + task.edge("task_runner", "comms", style="dotted", color=TASK[1], arrowhead="none") + + with prod.subgraph(name="cluster_sup") as sup: + sup.attr( + label="Supervisor process · native OS process (Python)", + labelloc="t", + style="rounded,filled", + fillcolor="#eaf3fc", + color=SUP[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node( + sup, + "supervisor", + "ActivitySubprocess", + "Supervisor (WatchedSubprocess base)
forks + watches the task, heartbeats," + "
forwards logs, proxies every API call", + shape="box3d", + theme=SUP, + ) + _node( + sup, + "client", + "Client", + "Execution API HTTP client
holds the short-lived task JWT", + shape="box", + theme=SUP, + ) + sup.edge("supervisor", "client", style="dotted", color=SUP[1], arrowhead="none") + + # Socket comms between the two native OS processes. + g.edge( + "comms", + "supervisor", + label="length-prefixed msgpack frames\nover the stdin socket\nToSupervisor ▸ ◂ ToTask", + color=TASK[1], + fontcolor=TASK[1], + dir="both", + penwidth="2.2", + ) + g.edge( + "comms", + "supervisor", + label="log records\n(line-based JSON, logs socket)", + color=TASK[1], + fontcolor="#5d8a60", + style="dashed", + ) + + # ------------------------------------------------------------------ # + # API server — separate process / host. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_api") as api: + api.attr( + label="API server · separate process / host", + labelloc="t", + style="rounded,filled", + fillcolor="#fdeeec", + color=API[1], + penwidth="1.5", + fontsize="13", + fontname="Helvetica-Bold", + margin="14", + ) + _node(api, "execution_api", "Execution API", "(FastAPI)", shape="component", theme=API) + _node(api, "metadata_db", "Metadata DB", "", shape="cylinder", theme=NEUTRAL) + api.edge("execution_api", "metadata_db", style="dotted", color=API[1], dir="both") + + g.edge( + "client", + "execution_api", + label="HTTPS + task JWT\n(over the network)", + color=API[1], + fontcolor=API[1], + penwidth="2.2", + ) + + # ------------------------------------------------------------------ # + # Native / in-process path — one Python process, no fork, no sockets. + # ------------------------------------------------------------------ # + with g.subgraph(name="cluster_native") as nat: + nat.attr( + label="Native (in-process) path — dag.test() / local run" + " · ONE Python process · no fork · no sockets · no HTTP", + labelloc="t", + style="rounded,filled", + fillcolor="#faf3fc", + color=NATIVE[1], + penwidth="1.5", + fontsize="16", + fontname="Helvetica-Bold", + margin="18", + ) + _node( + nat, + "in_runner", + "task_runner.run()", + "→ Operator.execute() [user code]
same Task SDK runtime", + shape="box3d", + theme=NATIVE, + ) + _node( + nat, + "in_comms", + "InProcessSupervisorComms", + "in-memory deques, not sockets", + shape="box", + theme=NATIVE, + ) + _node(nat, "in_sup", "InProcessTestSupervisor", "(ActivitySubprocess)", shape="box3d", theme=NATIVE) + _node( + nat, + "in_api", + "InProcessExecutionAPI", + "in-memory ASGI app · no network", + shape="component", + theme=NATIVE, + ) + nat.edge( + "in_runner", + "in_comms", + label="ToTask / ToSupervisor messages\nvia deque.append / popleft", + color=NATIVE[1], + fontcolor=NATIVE[1], + dir="both", + ) + nat.edge("in_comms", "in_sup", label="direct in-process call", color=NATIVE[1], fontcolor=NATIVE[1]) + nat.edge( + "in_sup", + "in_api", + label="in-process ASGI request\n(no socket, no JWT)", + color=NATIVE[1], + fontcolor=NATIVE[1], + ) + + g.render(outfile=str(image_file), format="png", cleanup=True) + console.print(f"[green]Generated architecture image {image_file}") + + +if __name__ == "__main__": + generate_task_sdk_execution_architecture_diagram() diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_sequence.md5sum b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.md5sum new file mode 100644 index 0000000000000..db39bb21d054a --- /dev/null +++ b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.md5sum @@ -0,0 +1 @@ +c6071c060cf352f65dfaf1240aaa0755 diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_sequence.png b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.png new file mode 100644 index 0000000000000..8f0f11ec7081d Binary files /dev/null and b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.png differ diff --git a/airflow-core/docs/img/diagram_task_sdk_execution_sequence.py b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.py new file mode 100644 index 0000000000000..a3470121d081c --- /dev/null +++ b/airflow-core/docs/img/diagram_task_sdk_execution_sequence.py @@ -0,0 +1,313 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "rich>=13.6.0", +# "graphviz>=0.20.1", +# ] +# /// +""" +UML-style sequence diagram for a supervised Task SDK task run. + +Each participant gets its own vertical lifeline; messages are horizontal arrows +between lifelines, read top to bottom. The **Supervisor** sits in the middle so +the Task <-> Supervisor round-trip (the task asks for a Connection/Variable/XCom +and gets the answer back) and the Supervisor <-> Execution API round-trip are +both drawn as adjacent request/response pairs. + +Arrows are colored by sender: + +* blue — Supervisor ("Coordinator") → Task / Execution API +* green — Task (task_runner, user code) → Supervisor +* red — Execution API (FastAPI on the API server) → Supervisor (responses) +* amber — Executor (start / end of the run) + +Graphviz has no native sequence-diagram shape, so lifelines are drawn as dashed +vertical edges through invisible way-points, one row per message, with each +message as a ``constraint=false`` horizontal edge on that row. +""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any + +import graphviz +from rich.console import Console + +MY_DIR = Path(__file__).parent +MY_FILENAME = Path(__file__).with_suffix("").name + +console = Console(width=400, color_system="standard") + +# (fill, border) per participant — consistent with the other Task SDK diagrams. +EXEC = ("#fff3e0", "#ef6c00") # executor / terminal (amber) +TASK = ("#e8f5e9", "#2e7d32") # task_runner + user code (green) +SUP = ("#e3f2fd", "#1565c0") # supervisor (blue) +API = ("#fdecea", "#c62828") # execution API (red) + +EXEC_C, TASK_C, SUP_C, API_C = EXEC[1], TASK[1], SUP[1], API[1] + +LIFELINE = "#b0bec5" + +# Participants, left to right. Supervisor is central so both round-trips are +# drawn between neighboring lifelines. +PARTICIPANTS = [ + ("exec", "Executor", "supervise_task()", EXEC), + ("task", "Task", "task_runner · user code", TASK), + ("sup", "Supervisor", "ActivitySubprocess", SUP), + ("api", "Execution API", "FastAPI · TEI / AIP-72", API), +] + +# Each step is one row. A "msg" is an arrow between two lifelines; a "self" is an +# activation box on a single lifeline (local processing, no message). +STEPS: list[dict[str, Any]] = [ + { + "kind": "msg", + "from": "exec", + "to": "sup", + "color": EXEC_C, + "label": "supervise_task()\nvia BaseExecutor.run_workload", + }, + { + "kind": "self", + "actor": "sup", + "theme": SUP, + "text": "ActivitySubprocess.start()\nfork the task process, open the sockets", + }, + {"kind": "msg", "from": "sup", "to": "api", "color": SUP_C, "label": "PATCH .../run\n(TI started)"}, + { + "kind": "msg", + "from": "api", + "to": "sup", + "color": API_C, + "style": "dashed", + "label": "TIRunContext\n(+ heartbeat every ~N s)", + }, + { + "kind": "msg", + "from": "sup", + "to": "task", + "color": SUP_C, + "label": "StartupDetails\n(_ResponseFrame, msgpack —\nthe one un-prompted message)", + }, + { + "kind": "self", + "actor": "task", + "theme": TASK, + "text": "parse() → RuntimeTaskInstance\nrun() → Operator.execute() [USER CODE]", + }, + { + "kind": "msg", + "from": "task", + "to": "sup", + "color": TASK_C, + "label": "GetConnection / GetVariable / GetXCom\n(_RequestFrame, msgpack over socket)", + }, + { + "kind": "msg", + "from": "sup", + "to": "api", + "color": SUP_C, + "label": "GET connection / variable / xcom\n(HTTPS + task JWT)", + }, + {"kind": "msg", "from": "api", "to": "sup", "color": API_C, "style": "dashed", "label": "result"}, + { + "kind": "msg", + "from": "sup", + "to": "task", + "color": SUP_C, + "label": "*Result (_ResponseFrame, msgpack)\nabove 4 messages repeat per lookup", + }, + { + "kind": "msg", + "from": "task", + "to": "sup", + "color": TASK_C, + "label": "SucceedTask / DeferTask / RetryTask\n(final state, msgpack over socket)", + }, + {"kind": "msg", "from": "sup", "to": "api", "color": SUP_C, "label": "PATCH .../state\n(+ upload logs)"}, + { + "kind": "msg", + "from": "sup", + "to": "exec", + "color": EXEC_C, + "style": "dashed", + "label": "task process exits →\nsupervise_task() returns the exit code", + }, +] + + +def _label(title: str, sub: str | None = None) -> str: + html = f"<{title}" + if sub: + safe = sub.replace("\n", "
") + html += f'
{safe}' + return html + ">" + + +def _header(g, pid: str, title: str, sub: str, theme: tuple[str, str]) -> None: + fill, border = theme + g.node( + f"{pid}__h", + label=_label(title, sub), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.24,0.14", + ) + + +def _activation(g, node_id: str, num: int, text: str, theme: tuple[str, str]) -> None: + fill, border = theme + g.node( + node_id, + label=_label(f"{num}", text), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.2,0.12", + ) + + +def _waypoint(g, node_id: str) -> None: + g.node(node_id, shape="point", width="0.02", color=LIFELINE) + + +def _edge_label(num: int, text: str) -> str: + # Pad the description on every side: blank lines above and below keep it clear + # of the arrow line, and leading/trailing spaces on each line keep it clear of + # the lifelines on the left and right. + lines = f"{num} · {text}".split("\n") + padded = "\n".join(f" {line} " for line in lines) + return f" \n{padded}\n " + + +def _build_sequence(g) -> None: + ids = [p[0] for p in PARTICIPANTS] + + # --- participant headers, ordered left-to-right on the top rank ---------- # + with g.subgraph() as top: + top.attr(rank="same") + for pid, title, sub, theme in PARTICIPANTS: + _header(top, pid, title, sub, theme) + for a, b in zip(ids, ids[1:]): + g.edge(f"{a}__h", f"{b}__h", style="invis") + + # --- one rank per step; way-points on every lifeline, box on the actor --- # + for i, step in enumerate(STEPS): + with g.subgraph() as row: + row.attr(rank="same") + for pid, _, _, theme in PARTICIPANTS: + nid = f"{pid}__{i}" + if step["kind"] == "self" and step["actor"] == pid: + _activation(row, nid, i + 1, step["text"], step.get("theme", theme)) + else: + _waypoint(row, nid) + + # --- dashed vertical lifelines through the way-points -------------------- # + for pid, *_ in PARTICIPANTS: + chain = [f"{pid}__h"] + [f"{pid}__{i}" for i in range(len(STEPS))] + for a, b in zip(chain, chain[1:]): + g.edge(a, b, style="dashed", arrowhead="none", color=LIFELINE, penwidth="1.3") + + # --- message arrows (horizontal, do not constrain ranking) --------------- # + for i, step in enumerate(STEPS): + if step["kind"] != "msg": + continue + g.edge( + f"{step['from']}__{i}", + f"{step['to']}__{i}", + xlabel=_edge_label(i + 1, step["label"]), + color=step["color"], + fontcolor=step["color"], + style=step.get("style", "solid"), + arrowhead="vee", + penwidth="2", + constraint="false", + ) + + _legend(g) + + +def _legend(g) -> None: + entries = [ + ("lg_sup", "Supervisor → Task / Execution API", SUP), + ("lg_task", "Task (user code) → Supervisor", TASK), + ("lg_api", "Execution API → Supervisor (response)", API), + ("lg_exec", "Executor (start / end of the run)", EXEC), + ] + with g.subgraph(name="cluster_legend") as legend: + legend.attr( + label="Arrow color = sender · steps 7–10 repeat per Connection / Variable / XCom lookup", + labelloc="t", + style="rounded,filled", + fillcolor="#fafafa", + color="#b0bec5", + fontsize="12", + fontname="Helvetica-Bold", + margin="12", + ) + for nid, text, theme in entries: + fill, border = theme + legend.node( + nid, + label=_label(text), + shape="box", + style="rounded,filled", + fillcolor=fill, + color=border, + penwidth="2", + margin="0.2,0.1", + ) + for a, b in zip([e[0] for e in entries], [e[0] for e in entries][1:]): + legend.edge(a, b, style="invis") + # Anchor the legend below the diagram, on the left. + g.edge(f"exec__{len(STEPS) - 1}", "lg_sup", style="invis") + + +def generate_task_sdk_execution_sequence_diagram(): + image_file = MY_DIR / f"{MY_FILENAME}.png" + console.print(f"[bright_blue]Generating sequence image {image_file}") + + g = graphviz.Digraph("task_sdk_execution_sequence") + g.attr( + rankdir="TB", + splines="line", + forcelabels="true", + nodesep="1.3", + ranksep="1.2", + pad="0.5", + bgcolor="white", + fontname="Helvetica", + ) + g.attr("node", fontname="Helvetica", fontsize="13", fontcolor="#102027") + g.attr("edge", fontname="Helvetica", fontsize="10", penwidth="2", color="#546e7a") + + _build_sequence(g) + + g.render(outfile=str(image_file), format="png", cleanup=True) + console.print(f"[green]Generated sequence image {image_file}") + + +if __name__ == "__main__": + generate_task_sdk_execution_sequence_diagram() diff --git a/airflow-core/docs/index.rst b/airflow-core/docs/index.rst index 4280171e42dc9..879ccb50e0871 100644 --- a/airflow-core/docs/index.rst +++ b/airflow-core/docs/index.rst @@ -19,8 +19,10 @@ What is Airflow®? ========================================= `Apache Airflow® `_ is an open-source platform for developing, scheduling, -and monitoring batch-oriented workflows. Airflow's extensible Python framework enables you to build workflows -connecting with virtually any technology. A web-based UI helps you visualize, manage, and debug your workflows. +and monitoring workflows, such as traditional time based or event-triggered batch-oriented data pipelines, machine learning, model training, +and agentic or LLM-based workloads. Airflow's extensible Python framework enables you to build workflows +connecting with virtually any technology, with a growing set of providers for orchestrating AI and agentic +tools alongside the rest of your pipeline. A web-based UI helps you visualize, manage, and debug your workflows. You can run Airflow in a variety of configurations — from a single process on your laptop to a distributed system capable of handling massive workloads. diff --git a/airflow-core/docs/installation/prerequisites.rst b/airflow-core/docs/installation/prerequisites.rst index 190dd39755509..b92ae330e6789 100644 --- a/airflow-core/docs/installation/prerequisites.rst +++ b/airflow-core/docs/installation/prerequisites.rst @@ -20,6 +20,8 @@ Prerequisites Airflow® is tested with: + .. Beginning of the auto-generated tested versions + * Python: 3.10, 3.11, 3.12, 3.13, 3.14 * Databases: @@ -30,6 +32,8 @@ Airflow® is tested with: * Kubernetes: 1.30, 1.31, 1.32, 1.33, 1.34, 1.35 + .. End of the auto-generated tested versions + While we recommend a minimum of 4GB of memory for Airflow, the actual requirements heavily depend on your chosen deployment. .. warning:: diff --git a/airflow-core/docs/installation/supported-versions.rst b/airflow-core/docs/installation/supported-versions.rst index f41890a78bdba..2c43585ac841e 100644 --- a/airflow-core/docs/installation/supported-versions.rst +++ b/airflow-core/docs/installation/supported-versions.rst @@ -29,7 +29,7 @@ Apache Airflow® version life cycle: ========= ===================== =========== =============== ===================== ================ Version Current Patch/Minor State First Release Limited Maintenance EOL/Terminated ========= ===================== =========== =============== ===================== ================ -3 3.3.0 Maintenance Apr 22, 2025 TBD TBD +3 3.3.1 Maintenance Apr 22, 2025 TBD TBD 2 2.11.2 EOL Dec 17, 2020 Oct 22, 2025 Apr 22, 2026 1.10 1.10.15 EOL Aug 27, 2018 Dec 17, 2020 June 17, 2021 1.9 1.9.0 EOL Jan 03, 2018 Aug 27, 2018 Aug 27, 2018 diff --git a/airflow-core/docs/migrations-ref.rst b/airflow-core/docs/migrations-ref.rst index d2cfde623523f..a639a18809a0e 100644 --- a/airflow-core/docs/migrations-ref.rst +++ b/airflow-core/docs/migrations-ref.rst @@ -92,7 +92,7 @@ Here's the list of all the Database Migrations that are executed via when you ru | ``55297ae24532`` | ``e79fc784f145`` | ``3.2.0`` | Add required fields to enable UI integrations for the | | | | | Deadline Alerts feature. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``e79fc784f145`` | ``0b112f49112d`` | ``3.2.0`` | add timetable_type to dag table for filtering. | +| ``e79fc784f145`` | ``0b112f49112d`` | ``3.2.0`` | Add timetable_type to dag table for filtering. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``0b112f49112d`` | ``c47f2e1ab9d4`` | ``3.2.0`` | Add exceeds max runs flag to dag model. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -120,7 +120,7 @@ Here's the list of all the Database Migrations that are executed via when you ru | ``ab6dc0c82d0e`` | ``15d84ca19038`` | ``3.2.0`` | Change ``serialized_dag`` data column to JSONB for | | | | | PostgreSQL. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``15d84ca19038`` | ``509b94a1042d`` | ``3.2.0`` | replace asset_trigger table with asset_watcher. | +| ``15d84ca19038`` | ``509b94a1042d`` | ``3.2.0`` | Replace asset_trigger table with asset_watcher. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``509b94a1042d`` | ``82dbd68e6171`` | ``3.1.8`` | Change ``signed_url_template`` from VARCHAR(200) to TEXT. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -129,7 +129,7 @@ Here's the list of all the Database Migrations that are executed via when you ru | ``cc92b33c6709`` | ``eaf332f43c7c`` | ``3.1.0`` | Add backward compatibility for serialized DAG format v3 to | | | | | v2. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``eaf332f43c7c`` | ``a3c7f2b18d4e`` | ``3.1.0`` | add last_parse_duration to dag model. | +| ``eaf332f43c7c`` | ``a3c7f2b18d4e`` | ``3.1.0`` | Add last_parse_duration to dag model. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``a3c7f2b18d4e`` | ``7582ea3f3dd5`` | ``3.1.0`` | Add tables to store teams and associations with dag bundles. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -185,15 +185,15 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``7645189f3479`` | ``e00344393f31`` | ``3.0.0`` | Add try_id to TI and TIH. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``e00344393f31`` | ``6a9e7a527a88`` | ``3.0.0`` | remove external_trigger field. | +| ``e00344393f31`` | ``6a9e7a527a88`` | ``3.0.0`` | Remove external_trigger field. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``6a9e7a527a88`` | ``33b04e4bfa19`` | ``3.0.0`` | Add DagRun run_after. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``33b04e4bfa19`` | ``8ea135928435`` | ``3.0.0`` | add new task_instance field scheduled_dttm. | +| ``33b04e4bfa19`` | ``8ea135928435`` | ``3.0.0`` | Add new task_instance field scheduled_dttm. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``8ea135928435`` | ``e39a26ac59f6`` | ``3.0.0`` | Add relative fileloc column. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``e39a26ac59f6`` | ``38770795785f`` | ``3.0.0`` | remove pickled data from dagrun table. | +| ``e39a26ac59f6`` | ``38770795785f`` | ``3.0.0`` | Remove pickled data from dagrun table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``38770795785f`` | ``5c9c0231baa2`` | ``3.0.0`` | Add asset reference models. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -201,7 +201,7 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``237cef8dfea1`` | ``038dc8bc6284`` | ``3.0.0`` | Add deadline alerts table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``038dc8bc6284`` | ``e229247a6cb1`` | ``3.0.0`` | update trigger_timeout column in task_instance table to UTC. | +| ``038dc8bc6284`` | ``e229247a6cb1`` | ``3.0.0`` | Update trigger_timeout column in task_instance table to UTC. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``e229247a6cb1`` | ``eed27faa34e3`` | ``3.0.0`` | Add DagBundleModel. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -209,7 +209,7 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``9fc3fc5de720`` | ``2b47dc6bc8df`` | ``3.0.0`` | Add references between assets and triggers. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``2b47dc6bc8df`` | ``d03e4a635aa3`` | ``3.0.0`` | add dag versioning. | +| ``2b47dc6bc8df`` | ``d03e4a635aa3`` | ``3.0.0`` | Add dag versioning. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``d03e4a635aa3`` | ``d8cd3297971e`` | ``3.0.0`` | Drop DAG pickling. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -217,7 +217,7 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``5f57a45b8433`` | ``486ac7936b78`` | ``3.0.0`` | Drop task_fail table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``486ac7936b78`` | ``d59cbbef95eb`` | ``3.0.0`` | remove scheduler_lock column. | +| ``486ac7936b78`` | ``d59cbbef95eb`` | ``3.0.0`` | Remove scheduler_lock column. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``d59cbbef95eb`` | ``05234396c6fc`` | ``3.0.0`` | Add UUID primary key to ``task_instance`` table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -266,9 +266,9 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``d482b7261ff9`` | ``c4602ba06b4b`` | ``2.10.0`` | Add task_instance_history. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``c4602ba06b4b`` | ``677fdbb7fc54`` | ``2.10.0`` | Added DagPriorityParsingRequest table. | +| ``c4602ba06b4b`` | ``677fdbb7fc54`` | ``2.10.0`` | Add DagPriorityParsingRequest table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``677fdbb7fc54`` | ``0fd0c178cbe8`` | ``2.10.0`` | add new executor field to db. | +| ``677fdbb7fc54`` | ``0fd0c178cbe8`` | ``2.10.0`` | Add new executor field to db. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``0fd0c178cbe8`` | ``686269002441`` | ``2.10.0`` | Add indexes on dag_id column in referencing tables. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ @@ -277,17 +277,17 @@ Here's the list of all the Database Migrations that are executed via when you ru | ``bff083ad727d`` | ``1949afb29106`` | ``2.9.2`` | Remove ``idx_last_scheduling_decision`` index on | | | | | last_scheduling_decision in dag_run table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``1949afb29106`` | ``ee1467d4aa35`` | ``2.9.0`` | update trigger kwargs type and encrypt. | +| ``1949afb29106`` | ``ee1467d4aa35`` | ``2.9.0`` | Update trigger kwargs type and encrypt. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``ee1467d4aa35`` | ``b4078ac230a1`` | ``2.9.0`` | add display name for dag and task instance. | +| ``ee1467d4aa35`` | ``b4078ac230a1`` | ``2.9.0`` | Add display name for dag and task instance. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``b4078ac230a1`` | ``8e1c784a4fc7`` | ``2.9.0`` | Change value column type to longblob in xcom table for | | | | | mysql. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``8e1c784a4fc7`` | ``ab34f260b71c`` | ``2.9.0`` | Adding max_consecutive_failed_dag_runs column to dag_model | +| ``8e1c784a4fc7`` | ``ab34f260b71c`` | ``2.9.0`` | Add max_consecutive_failed_dag_runs column to dag_model | | | | | table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``ab34f260b71c`` | ``d75389605139`` | ``2.9.0`` | add dataset_expression in DagModel. | +| ``ab34f260b71c`` | ``d75389605139`` | ``2.9.0`` | Add dataset_expression in DagModel. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``d75389605139`` | ``1fd565369930`` | ``2.9.0`` | Add run_id to (Audit) log table and increase event name | | | | | length. | @@ -302,9 +302,9 @@ Here's the list of all the Database Migrations that are executed via when you ru +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``f7bf2a57d0a6`` | ``375a816bbbf4`` | ``2.8.0`` | Add owner_display_name to (Audit) Log table. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``375a816bbbf4`` | ``405de8318b3a`` | ``2.8.0`` | add new field 'clear_number' to dagrun. | +| ``375a816bbbf4`` | ``405de8318b3a`` | ``2.8.0`` | Add new field 'clear_number' to dagrun. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ -| ``405de8318b3a`` | ``788397e78828`` | ``2.7.0`` | add include_deferred column to pool. | +| ``405de8318b3a`` | ``788397e78828`` | ``2.7.0`` | Add include_deferred column to pool. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ | ``788397e78828`` | ``937cbd173ca1`` | ``2.7.0`` | Add custom_operator_name column. | +-------------------------+------------------+-------------------+--------------------------------------------------------------+ diff --git a/airflow-core/docs/security/api_permissions_ref.rst b/airflow-core/docs/security/api_permissions_ref.rst new file mode 100644 index 0000000000000..11097ad5a422e --- /dev/null +++ b/airflow-core/docs/security/api_permissions_ref.rst @@ -0,0 +1,576 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. THIS FILE IS AUTO-GENERATED. DO NOT EDIT MANUALLY. + Regenerate with: python scripts/ci/prek/extract_permissions.py + Trigger: prek run generate-api-permissions-doc --all-files + +API Endpoint Permission Reference +================================== + +This page lists the required permission for every endpoint in the stable +Airflow REST API (``/api/v2``). It is generated automatically from the +source code so it stays up to date as endpoints are added or changed. + +.. seealso:: + + :doc:`/security/api` — for authentication instructions (JWT tokens). + +.. note:: + + Permissions are enforced by the configured **auth manager**. The + :class:`~airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager` + interface defines the contract; individual auth manager implementations + (e.g. the Simple Auth Manager, or the FAB provider) translate these + resource/method tuples into their own role/permission models. + +.. list-table:: Stable REST API endpoint permissions + :header-rows: 1 + :widths: 7 50 20 13 + + * - Method + - Endpoint path + - Resource + - Required permission + * - ``GET`` + - ``/api/v2/assets`` + - ``Asset`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets`` + - ``AssetAlias`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets/aliases`` + - ``AssetAlias`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets/aliases/{asset_alias_id}`` + - ``AssetAlias`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets/events`` + - ``Asset`` + - ``GET`` + * - ``POST`` + - ``/api/v2/assets/events`` + - ``Asset`` + - ``POST`` + * - ``GET`` + - ``/api/v2/assets/{asset_id}`` + - ``Asset`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets/{asset_id}`` + - ``AssetAlias`` + - ``GET`` + * - ``POST`` + - ``/api/v2/assets/{asset_id}/materialize`` + - ``Asset`` + - ``POST`` + * - ``DELETE`` + - ``/api/v2/assets/{asset_id}/queuedEvents`` + - ``Asset`` + - ``DELETE`` + * - ``DELETE`` + - ``/api/v2/assets/{asset_id}/queuedEvents`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/assets/{asset_id}/queuedEvents`` + - ``Asset`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/assets/{asset_id}/state-store`` + - ``Asset`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/assets/{asset_id}/state-store`` + - ``Asset`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/assets/{asset_id}/state-store/{key:path}`` + - ``Asset`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/assets/{asset_id}/state-store/{key:path}`` + - ``Asset`` + - ``GET`` + * - ``PUT`` + - ``/api/v2/assets/{asset_id}/state-store/{key:path}`` + - ``Asset`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/auth/login`` + - ``Public`` + - ``No Airflow permission required`` + * - ``GET`` + - ``/api/v2/auth/logout`` + - ``Public`` + - ``No Airflow permission required`` + * - ``GET`` + - ``/api/v2/backfills`` + - ``DAG.RUN`` + - ``GET`` + * - ``POST`` + - ``/api/v2/backfills`` + - ``DAG.RUN`` + - ``POST`` + * - ``PUT`` + - ``/api/v2/backfills`` + - ``DAG.RUN`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/config`` + - ``Configuration`` + - ``GET`` + * - ``GET`` + - ``/api/v2/config/section/{section}/option/{option}`` + - ``Configuration`` + - ``GET`` + * - ``GET`` + - ``/api/v2/connections`` + - ``Connection`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/connections`` + - ``Connection`` + - ``multi`` + * - ``POST`` + - ``/api/v2/connections`` + - ``Connection`` + - ``POST`` + * - ``POST`` + - ``/api/v2/connections/defaults`` + - ``Connection`` + - ``POST`` + * - ``GET`` + - ``/api/v2/connections/enqueue-test`` + - ``Public`` + - ``No Airflow permission required`` + * - ``POST`` + - ``/api/v2/connections/enqueue-test`` + - ``Public`` + - ``No Airflow permission required`` + * - ``POST`` + - ``/api/v2/connections/test`` + - ``Connection`` + - ``POST`` + * - ``DELETE`` + - ``/api/v2/connections/{connection_id}`` + - ``Connection`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/connections/{connection_id}`` + - ``Connection`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/connections/{connection_id}`` + - ``Connection`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dagSources/{dag_id}`` + - ``DAG.CODE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dagStats`` + - ``DAG.RUN`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dagTags`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dagWarnings`` + - ``DAG.WARNING`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags`` + - ``DAG`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags`` + - ``DAG`` + - ``PUT`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}`` + - ``DAG`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}`` + - ``DAG`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}`` + - ``DAG`` + - ``PUT`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/assets/queuedEvents`` + - ``Asset`` + - ``DELETE`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/assets/queuedEvents`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/assets/queuedEvents`` + - ``Asset`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/assets/queuedEvents`` + - ``DAG`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/assets/{asset_id}/queuedEvents`` + - ``Asset`` + - ``DELETE`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/assets/{asset_id}/queuedEvents`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/assets/{asset_id}/queuedEvents`` + - ``Asset`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/assets/{asset_id}/queuedEvents`` + - ``DAG`` + - ``GET`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/clearDagRuns`` + - ``DAG.RUN`` + - ``multi`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/clearPartitions`` + - ``DAG.RUN`` + - ``PUT`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/clearTaskInstances`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns`` + - ``DAG.RUN`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns`` + - ``DAG.RUN`` + - ``multi`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/dagRuns`` + - ``DAG.RUN`` + - ``POST`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/dagRuns/list`` + - ``DAG.RUN`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}`` + - ``DAG.RUN`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}`` + - ``DAG.RUN`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}`` + - ``DAG.RUN`` + - ``PUT`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/clear`` + - ``DAG.RUN`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails`` + - ``DAG.HITL_DETAIL`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskGroupInstances/{group_id}`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskGroupInstances/{group_id}/dry_run`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/list`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}`` + - ``DAG.TASK_INSTANCE`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/dependencies`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/dry_run`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/externalLogUrl/{try_number}`` + - ``DAG.TASK_LOGS`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/links`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/listMapped`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/logs/{try_number}`` + - ``DAG.TASK_LOGS`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store`` + - ``DAG.TASK_INSTANCE`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store/{key:path}`` + - ``DAG.TASK_INSTANCE`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store/{key:path}`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store/{key:path}`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``PUT`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/state-store/{key:path}`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/tries`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/tries/{task_try_number}`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries`` + - ``DAG.XCOM`` + - ``GET`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries`` + - ``DAG.XCOM`` + - ``POST`` + * - ``DELETE`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries/{xcom_key:path}`` + - ``DAG.XCOM`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries/{xcom_key:path}`` + - ``DAG.XCOM`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries/{xcom_key:path}`` + - ``DAG.XCOM`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/dependencies`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/dry_run`` + - ``DAG.TASK_INSTANCE`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails`` + - ``DAG.HITL_DETAIL`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails`` + - ``DAG.HITL_DETAIL`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails/tries/{try_number}`` + - ``DAG.HITL_DETAIL`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/tries`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/tries/{task_try_number}`` + - ``DAG.TASK_INSTANCE`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/upstreamAssetEvents`` + - ``Asset`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/upstreamAssetEvents`` + - ``DAG.RUN`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/wait`` + - ``DAG.RUN`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagVersions`` + - ``DAG.VERSION`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/dagVersions/{version_number}`` + - ``DAG.VERSION`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/details`` + - ``DAG`` + - ``GET`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/favorite`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/tasks`` + - ``DAG.TASK`` + - ``GET`` + * - ``GET`` + - ``/api/v2/dags/{dag_id}/tasks/{task_id}`` + - ``DAG.TASK`` + - ``GET`` + * - ``POST`` + - ``/api/v2/dags/{dag_id}/unfavorite`` + - ``DAG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/eventLogs`` + - ``DAG.AUDIT_LOG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/eventLogs/{event_log_id}`` + - ``DAG.AUDIT_LOG`` + - ``GET`` + * - ``GET`` + - ``/api/v2/importErrors`` + - ``View.IMPORT_ERRORS`` + - ``IMPORT_ERRORS`` + * - ``GET`` + - ``/api/v2/importErrors/{import_error_id}`` + - ``View.IMPORT_ERRORS`` + - ``IMPORT_ERRORS`` + * - ``GET`` + - ``/api/v2/jobs`` + - ``View.JOBS`` + - ``JOBS`` + * - ``GET`` + - ``/api/v2/monitor/health`` + - ``Public`` + - ``No Airflow permission required`` + * - ``PUT`` + - ``/api/v2/parseDagFile/{file_token}`` + - ``DAG`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/plugins`` + - ``View.PLUGINS`` + - ``PLUGINS`` + * - ``GET`` + - ``/api/v2/plugins/importErrors`` + - ``View.PLUGINS`` + - ``PLUGINS`` + * - ``GET`` + - ``/api/v2/pools`` + - ``Pool`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/pools`` + - ``Pool`` + - ``multi`` + * - ``POST`` + - ``/api/v2/pools`` + - ``Pool`` + - ``POST`` + * - ``DELETE`` + - ``/api/v2/pools/{pool_name:path}`` + - ``Pool`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/pools/{pool_name:path}`` + - ``Pool`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/pools/{pool_name:path}`` + - ``Pool`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/providers`` + - ``View.PROVIDERS`` + - ``PROVIDERS`` + * - ``GET`` + - ``/api/v2/variables`` + - ``Variable`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/variables`` + - ``Variable`` + - ``multi`` + * - ``POST`` + - ``/api/v2/variables`` + - ``Variable`` + - ``POST`` + * - ``DELETE`` + - ``/api/v2/variables/{variable_key:path}`` + - ``Variable`` + - ``DELETE`` + * - ``GET`` + - ``/api/v2/variables/{variable_key:path}`` + - ``Variable`` + - ``GET`` + * - ``PATCH`` + - ``/api/v2/variables/{variable_key:path}`` + - ``Variable`` + - ``PUT`` + * - ``GET`` + - ``/api/v2/version`` + - ``Public`` + - ``No Airflow permission required`` diff --git a/airflow-core/docs/security/secrets/secrets-backend/local-filesystem-secrets-backend.rst b/airflow-core/docs/security/secrets/secrets-backend/local-filesystem-secrets-backend.rst index aaa71daf20af6..3b5228be88dae 100644 --- a/airflow-core/docs/security/secrets/secrets-backend/local-filesystem-secrets-backend.rst +++ b/airflow-core/docs/security/secrets/secrets-backend/local-filesystem-secrets-backend.rst @@ -35,6 +35,7 @@ Available parameters to ``backend_kwargs``: * ``variables_file_path``: File location with variables data. * ``connections_file_path``: File location with connections data. +* ``configs_file_path``: File location with configurations data. Here is a sample configuration: @@ -42,7 +43,7 @@ Here is a sample configuration: [secrets] backend = airflow.secrets.local_filesystem.LocalFilesystemBackend - backend_kwargs = {"variables_file_path": "/files/var.json", "connections_file_path": "/files/conn.json"} + backend_kwargs = {"variables_file_path": "/files/var.json", "connections_file_path": "/files/conn.json", "configs_file_path": "/files/config.json"} ``JSON``, ``YAML`` and ``.env`` files are supported. All parameters are optional. If the file path is not passed, the backend returns an empty collection. @@ -143,3 +144,47 @@ describe the variable value. The following is a sample file. VAR_A=some_value var_B=different_value + +Storing and Retrieving Configurations +""""""""""""""""""""""""""""""""""""" + +If you have set ``configs_file_path`` as ``/files/my_config.json``, then the backend will read the +file ``/files/my_config.json`` when it retrieves config options that are specified with appended ``_secret``. + +The file can be defined in ``JSON``, ``YAML`` or ``env`` format. + +The JSON file must contain an object where the key contains config option ``_secret`` version value and the value +contains config option value. The following are sample config options and a sample JSON file for these config options. +Config options: + + .. code-block:: ini + + [database] + sql_alchemy_conn_secret = value_specified_in_database_sql_alchemy_conn_secret + [core] + fernet_key_secret = value_specified_in_core_fernet_key_secret + +JSON file: + + .. code-block:: json + + { + "value_specified_in_database_sql_alchemy_conn_secret": "sql_alchemy_conn_actual_value", + "value_specified_in_core_fernet_key_secret": "fernet_key_actual_value" + } + +The YAML file structure is similar to that of JSON, with key containing config option ``_secret`` version value +and the value containing config option value. The following is a sample YAML file for the above config options example. + + .. code-block:: yaml + + value_specified_in_database_sql_alchemy_conn_secret: sql_alchemy_conn_actual_value + value_specified_in_core_fernet_key_secret: fernet_key_actual_value + +You can also define config options using a ``.env`` file. Then the key is the config option ``_secret`` version value, +and the value should be the config option value. The following is a sample file for the above config options example. + + .. code-block:: text + + value_specified_in_database_sql_alchemy_conn_secret=sql_alchemy_conn_actual_value + value_specified_in_core_fernet_key_secret=fernet_key_actual_value diff --git a/airflow-core/docs/tutorial/objectstorage.rst b/airflow-core/docs/tutorial/objectstorage.rst index 0b8a890138fa9..36038a298182c 100644 --- a/airflow-core/docs/tutorial/objectstorage.rst +++ b/airflow-core/docs/tutorial/objectstorage.rst @@ -109,7 +109,7 @@ Here's what's happening: - Using ``ObjectStoragePath``, we write the data directly to cloud storage as Parquet This is a classic TaskFlow pattern. The object key changes each day, allowing us to run this daily and build a dataset -over time. We return the final object path to be used in the next task. +over time. We return the final object path to be used in the downstream task. Why this is cool: No boto3, no GCS client setup, no credentials juggling. Just simple file semantics that work across storage backends. @@ -133,7 +133,7 @@ A few key things to note: - We use ``path.fs`` to grab the right filesystem object and register it with DuckDB - Finally, we query the Parquet file using SQL and return a pandas DataFrame -Notice that the function doesn't recreate the path manually -- it gets the full path from the previous task using Xcom. +Notice that the function doesn't recreate the path manually -- it gets the full path from the upstream task using Xcom. This makes the task portable and decoupled from earlier logic. Bringing It All Together diff --git a/airflow-core/docs/tutorial/taskflow.rst b/airflow-core/docs/tutorial/taskflow.rst index 44187d7f4b8db..68cf89da61bbd 100644 --- a/airflow-core/docs/tutorial/taskflow.rst +++ b/airflow-core/docs/tutorial/taskflow.rst @@ -84,7 +84,7 @@ that Airflow can schedule and run. Here's the ``extract`` task: | -The function's return value is passed to the next task — no manual use of ``XComs`` required. Under the hood, TaskFlow +The function's return value is passed to the downstream task — no manual use of ``XComs`` required. Under the hood, TaskFlow uses ``XComs`` to manage data passing automatically, abstracting away the complexity of manual XCom management from the previous methods. You'll define ``transform`` and ``load`` tasks using the same pattern. diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index 1a068ac63ca32..3621eb412529a 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -64,18 +64,16 @@ classifiers = [ ] # Version is defined in src/airflow/__init__.py and it is automatically synchronized by prek hook -version = "3.3.0" +version = "3.3.1" dependencies = [ "a2wsgi>=1.10.8", "cachetools>=6.0.0", # aiosqlite 0.22.0 has a problem with hanging pytest sessions and we excluded it # See https://github.com/omnilib/aiosqlite/issues/369 - # It seems that while our test issues are fixed in 0.22.1, sqlalchemy 2 itself - # is not compatible with it and leaves thread hanging This is already fixed in main of sqlalchemy - # But not released yet - and we will likely have to add >=2.0.46+ for sqlalchemy when released to - # protect against it https://github.com/sqlalchemy/sqlalchemy/issues/13039 - "aiosqlite>=0.20.0,<0.22.0", + # The thread hanging issue under SQLAlchemy 2 (sqlalchemy#13039) is resolved in + # SQLAlchemy 2.0.46+. Since our SQLAlchemy floor is >=2.0.48, we can safely allow 0.22.1+. + "aiosqlite>=0.20.0,!=0.22.0", # Alembic is important to handle our migrations in predictable and performant way. It is developed # together with SQLAlchemy. Our experience with Alembic is that it very stable in minor version # The 1.13.0 of alembic marked some migration code as SQLAlchemy 2+ only so we limit it to 1.13.1 @@ -87,7 +85,7 @@ dependencies = [ "cadwyn>=6.1.1", "colorlog>=6.8.2", "cron-descriptor>=1.2.24", - "croniter>=2.0.2", + "croniter>=6.2.2", # Cryptography could be upgraded to 46.0.5, but it does not have overlap with earlier versions # Of Airflow which were limited to <46.0.0 also earlier provider versions will not be compatible with newer # airflow if we do not have overlapping version. We could set minimum version to 46.0.0 when we drop @@ -145,7 +143,7 @@ dependencies = [ "rich-argparse>=1.0.0", "rich>=13.6.0", "setproctitle>=1.3.3", - "sqlalchemy[asyncio]>=2.0.48", + "sqlalchemy[asyncio]>=2.0.50", "svcs>=25.1.0", "tabulate>=0.9.0", "tenacity>=8.3.0", @@ -153,7 +151,7 @@ dependencies = [ "typing-extensions>=4.14.1", "universal-pathlib>=0.3.8", "uuid6>=2024.7.10", - "apache-airflow-task-sdk==1.3.0", + "apache-airflow-task-sdk==1.3.1", # pre-installed providers "apache-airflow-providers-common-compat>=1.7.4", "apache-airflow-providers-common-io>=1.6.3", @@ -163,7 +161,7 @@ dependencies = [ # Start of shared logging dependencies "msgspec>=0.19.0", "pygtrie>=2.5.0", - "structlog>=25.4.0", + "structlog>=26.1.0", # End of shared logging dependencies # Start of shared configuration dependencies "pyyaml>=6.0.3", diff --git a/airflow-core/src/airflow/__init__.py b/airflow-core/src/airflow/__init__.py index 67e7de6080ea6..996068431566c 100644 --- a/airflow-core/src/airflow/__init__.py +++ b/airflow-core/src/airflow/__init__.py @@ -25,7 +25,7 @@ # lib.) This is required by some IDEs to resolve the import paths. __path__ = __import__("pkgutil").extend_path(__path__, __name__) -__version__ = "3.3.0" +__version__ = "3.3.1" import os diff --git a/airflow-core/src/airflow/__main__.py b/airflow-core/src/airflow/__main__.py index c11d3b5afe923..c49146b629875 100644 --- a/airflow-core/src/airflow/__main__.py +++ b/airflow-core/src/airflow/__main__.py @@ -35,6 +35,7 @@ # any possible import cycles with settings downstream. from airflow import configuration from airflow.cli import cli_parser +from airflow.cli.utils import redirect_stdout_log_handlers_to_stderr def main(): @@ -45,6 +46,11 @@ def main(): parser = cli_parser.get_parser() argcomplete.autocomplete(parser) args = parser.parse_args() + # Commands that accept ``-o`` produce structured output on stdout; route any + # console log handler currently writing to stdout to stderr so log lines do + # not corrupt that output (e.g. ``airflow ... -o json | jq``). + if hasattr(args, "output"): + redirect_stdout_log_handlers_to_stderr() if args.subcommand not in ["lazy_loaded", "version"]: # Here we ensure that the default configuration is written if needed before running any command # that might need it. This used to be done during configuration initialization but having it diff --git a/airflow-core/src/airflow/api/common/mark_tasks.py b/airflow-core/src/airflow/api/common/mark_tasks.py index 7004156ef2423..9a07e1c9b6304 100644 --- a/airflow-core/src/airflow/api/common/mark_tasks.py +++ b/airflow-core/src/airflow/api/common/mark_tasks.py @@ -215,87 +215,37 @@ def _set_dag_run_state(dag_id: str, run_id: str, state: DagRunState, session: SA session.merge(dag_run) -@provide_session -def set_dag_run_state_to_success( - *, - dag: SerializedDAG, - run_id: str | None = None, - commit: bool = False, - session: SASession = NEW_SESSION, -) -> list[TaskInstance]: - """ - Set the dag run's state to success. - - Set for a specific logical date and its task instances to success. - - :param dag: the Dag of which to alter state - :param run_id: the run_id to start looking from - :param commit: commit Dag and tasks to be altered to the database - :param session: database session - :return: If commit is true, list of tasks that have been updated, - otherwise list of tasks that will be updated - :raises: ValueError if dag or logical_date is invalid - """ - if not dag: - return [] - if not run_id: - raise ValueError(f"Invalid dag_run_id: {run_id}") - - tasks = dag.tasks - - # Mark all task instances of the dag run to success - except for unfinished teardown as they need to complete work. - teardown_tasks = [task for task in tasks if task.is_teardown] - unfinished_teardown_task_ids = set( - session.scalars( - select(TaskInstance.task_id).where( - TaskInstance.dag_id == dag.dag_id, - TaskInstance.run_id == run_id, - TaskInstance.task_id.in_(task.task_id for task in teardown_tasks), - or_(TaskInstance.state.is_(None), TaskInstance.state.in_(State.unfinished)), - ) - ) - ) - - # Mark the dag run to success if there are no unfinished teardown tasks. - if commit and len(unfinished_teardown_task_ids) == 0: - _set_dag_run_state(dag.dag_id, run_id, DagRunState.SUCCESS, session) - - tasks_to_mark_success = [task for task in tasks if not task.is_teardown] + [ - task for task in teardown_tasks if task.task_id not in unfinished_teardown_task_ids - ] - for task in tasks_to_mark_success: - task.dag = dag - return set_state( - tasks=tasks_to_mark_success, - run_id=run_id, - state=TaskInstanceState.SUCCESS, - commit=commit, - session=session, - ) - - -@provide_session -def set_dag_run_state_to_failed( +def _set_dag_run_terminal_state( *, dag: SerializedDAG, - run_id: str | None = None, - commit: bool = False, - session: SASession = NEW_SESSION, -) -> list[TaskInstance]: + run_id: str | None, + run_state: DagRunState, + ti_state: TaskInstanceState, + commit: bool, + session: SASession, +) -> tuple[list[TaskInstance], list[TaskInstance]]: """ - Set the dag run's state to failed. + Set the dag run's state to the given terminal state. - Set for a specific logical date and its task instances to failed. + Running task instances are set to ``ti_state`` and non-finished ones to + SKIPPED; finished task instances keep their state. Teardown tasks are left + untouched so they can complete their work. :param dag: the Dag of which to alter state :param run_id: the Dag run_id to start looking from + :param run_state: terminal state to set on the dag run + :param ti_state: state to set on running task instances :param commit: commit Dag and tasks to be altered to the database :param session: database session - :return: If commit is true, list of tasks that have been updated, - otherwise list of tasks that will be updated + :return: ``(all_updated_tis, killed_tis)`` where ``all_updated_tis`` is the + combined list of pending (now SKIPPED) and running (now ``ti_state``) TIs, + and ``killed_tis`` contains only the non-teardown TIs that were in an active + running state and were forcefully terminated (teardown TIs are intentionally + left running so they can finish their own cleanup, and must not receive a + terminal listener event here). """ if not dag: - return [] + return [], [] if not run_id: raise ValueError(f"Invalid dag_run_id: {run_id}") @@ -318,9 +268,10 @@ def set_dag_run_state_to_failed( ) ).all() ) - # Do not kill teardown tasks task_ids_of_running_tis = {ti.task_id for ti in running_tis if not dag.task_dict[ti.task_id].is_teardown} + # Keep task instances that were killed with no cleanup capability (all running minus teardown ones). + killed_tis = [ti for ti in running_tis if ti.task_id in task_ids_of_running_tis] def _set_running_task(task: Operator) -> Operator: task.dag = dag @@ -352,14 +303,90 @@ def _set_running_task(task: Operator) -> Operator: for ti in pending_normal_tis: ti.set_state(TaskInstanceState.SKIPPED) - # Mark the dag run to failed if there is no pending teardown (else this would not be scheduled later). + # Set the dag run state only if there is no pending teardown (else this would not be scheduled later). if not any(dag.task_dict[ti.task_id].is_teardown for ti in (running_tis + pending_tis)): - _set_dag_run_state(dag.dag_id, run_id, DagRunState.FAILED, session) + _set_dag_run_state(dag.dag_id, run_id, run_state, session) - return pending_normal_tis + set_state( + all_updated = pending_normal_tis + set_state( tasks=running_tasks, run_id=run_id, - state=TaskInstanceState.FAILED, + state=ti_state, + commit=commit, + session=session, + ) + return all_updated, killed_tis + + +@provide_session +def set_dag_run_state_to_success( + *, + dag: SerializedDAG, + run_id: str | None = None, + commit: bool = False, + session: SASession = NEW_SESSION, +) -> tuple[list[TaskInstance], list[TaskInstance]]: + """ + Set the dag run's state to success. + + Set for a specific logical date and its task instances to success. + + :param dag: the Dag of which to alter state + :param run_id: the run_id to start looking from + :param commit: commit Dag and tasks to be altered to the database + :param session: database session + :return: A tuple ``(all_updated_tis, killed_tis)``. + ``all_updated_tis`` is the combined list of task instances that were updated: + previously-running ones (now SUCCESS) and non-finished pending ones (now SKIPPED). + If ``commit`` is ``False``, this is the list of task instances *that would be* updated. + ``killed_tis`` contains only the non-teardown task instances that were in an active + running state (RUNNING, DEFERRED, UP_FOR_RESCHEDULE, AWAITING_INPUT) and were + forcefully terminated — teardown tasks are intentionally excluded because they are + left running to finish their own cleanup. Use ``killed_tis`` for firing terminal + listener hooks. + :raises: ValueError if dag or logical_date is invalid + """ + return _set_dag_run_terminal_state( + dag=dag, + run_id=run_id, + run_state=DagRunState.SUCCESS, + ti_state=TaskInstanceState.SUCCESS, + commit=commit, + session=session, + ) + + +@provide_session +def set_dag_run_state_to_failed( + *, + dag: SerializedDAG, + run_id: str | None = None, + commit: bool = False, + session: SASession = NEW_SESSION, +) -> tuple[list[TaskInstance], list[TaskInstance]]: + """ + Set the dag run's state to failed. + + Set for a specific logical date and its task instances to failed. + + :param dag: the Dag of which to alter state + :param run_id: the Dag run_id to start looking from + :param commit: commit Dag and tasks to be altered to the database + :param session: database session + :return: A tuple ``(all_updated_tis, killed_tis)``. + ``all_updated_tis`` is the combined list of task instances that were updated: + previously-running ones (now FAILED) and non-finished pending ones (now SKIPPED). + If ``commit`` is ``False``, this is the list of task instances *that would be* updated. + ``killed_tis`` contains only the non-teardown task instances that were in an active + running state (RUNNING, DEFERRED, UP_FOR_RESCHEDULE, AWAITING_INPUT) and were + forcefully terminated — teardown tasks are intentionally excluded because they are + left running to finish their own cleanup. Use ``killed_tis`` for firing terminal + listener hooks. + """ + return _set_dag_run_terminal_state( + dag=dag, + run_id=run_id, + run_state=DagRunState.FAILED, + ti_state=TaskInstanceState.FAILED, commit=commit, session=session, ) diff --git a/airflow-core/src/airflow/api_fastapi/app.py b/airflow-core/src/airflow/api_fastapi/app.py index a4dbc3c9b722e..233965bd56ecd 100644 --- a/airflow-core/src/airflow/api_fastapi/app.py +++ b/airflow-core/src/airflow/api_fastapi/app.py @@ -27,9 +27,9 @@ from fastapi.routing import Mount from airflow.api_fastapi.common.dagbag import create_dag_bag +from airflow.api_fastapi.common.exceptions import init_error_handlers from airflow.api_fastapi.core_api.app import ( init_config, - init_error_handlers, init_flask_plugins, init_middlewares, init_views, @@ -115,7 +115,19 @@ def create_app(apps: str = "all") -> FastAPI: title="Airflow API", description="Airflow API. All endpoints located under ``/api/v2`` can be used safely, are stable and backward compatible. " "Endpoints located under ``/ui`` are dedicated to the UI and are subject to breaking change " - "depending on the need of the frontend. Users should not rely on those but use the public ones instead.", + "depending on the need of the frontend. Users should not rely on those but use the public ones instead." + "\n\n" + "**Filtering with pattern parameters.** Many list endpoints accept ``*_pattern`` and " + "``*_prefix_pattern`` query parameters. Unless a parameter's own description says otherwise, " + "``*_pattern`` is a case-insensitive substring match (SQL ``ILIKE '%term%'``) where ``%`` matches " + "any sequence and ``_`` matches any single character (e.g. ``%customer_%``) — convenient, but it " + "cannot use B-tree indexes, so it is slow on large tables. ``*_prefix_pattern`` matches the start " + "of the value, is case-sensitive and index-friendly (prefer it at scale); there ``%`` and ``_`` " + "are literal and trailing non-alphanumeric characters are stripped so the range scan stays " + "index-compatible under locale-aware collations " + "(e.g. ``test_`` matches values starting with ``test``, and ``s3://`` matches ``s3``). In both, " + "``|`` means OR (e.g. ``dag1|dag2``) and ``~`` matches everything. Regular expressions are not " + "supported by these parameters; regex-capable endpoints expose a separate parameter.", lifespan=lifespan, root_path=API_ROOT_PATH.removesuffix("/"), version="2", @@ -128,7 +140,6 @@ def create_app(apps: str = "all") -> FastAPI: if "all" in apps_list or "execution" in apps_list: task_exec_api_app = create_task_execution_api_app() task_exec_api_app.state.dag_bag = dag_bag - init_error_handlers(task_exec_api_app) app.mount("/execution", task_exec_api_app) if "all" in apps_list or "core" in apps_list: diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts index 17f37daa8cc71..a50840fea0454 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 import { UseQueryResult } from "@tanstack/react-query"; import type { Options } from "../requests/sdk.gen"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts index a0f3de25ddeb2..df781b169f376 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 import { type QueryClient } from "@tanstack/react-query"; import type { Options } from "../requests/sdk.gen"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts index fd344d39ed445..0523b0c1cf709 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 export * from "./common"; export * from "./queries"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts index eb9895b02c265..6681a6cf9503d 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts @@ -1 +1 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts index 9d3156f311a54..90a6afbe34177 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 import { type QueryClient } from "@tanstack/react-query"; import type { Options } from "../requests/sdk.gen"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts index 461248cf6bc04..dcac78b9cda3c 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 import { useMutation, UseMutationOptions, useQuery, UseQueryOptions } from "@tanstack/react-query"; import { AxiosError } from "axios"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts index f34840b44965b..0f1a42693d936 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/openapi-react-query-codegen@2.1.0 +// generated with @7nohe/openapi-react-query-codegen@2.2.0 import { useSuspenseQuery, UseSuspenseQueryOptions } from "@tanstack/react-query"; import { AxiosError } from "axios"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts index cab3c70195b3c..47828b746cf5d 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -import { type ClientOptions, type Config, createClient, createConfig } from './client'; +import { type Client, type ClientOptions, type Config, createClient, createConfig } from './client'; import type { ClientOptions as ClientOptions2 } from './types.gen'; /** @@ -13,4 +13,4 @@ import type { ClientOptions as ClientOptions2 } from './types.gen'; */ export type CreateClientConfig = (override?: Config) => Config & T>; -export const client = createClient(createConfig()); +export const client: Client = createClient(createConfig()); diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts index 9b3b2fa6a0e1a..d42045a3c2d9e 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts @@ -35,7 +35,13 @@ export const createClient = (config: Config = {}): Client => { return getConfig(); }; - const beforeRequest = async (options: RequestOptions) => { + const beforeRequest = async < + TData = unknown, + ThrowOnError extends boolean = boolean, + Url extends string = string, + >( + options: RequestOptions, + ) => { const opts = { ..._config, ...options, @@ -44,10 +50,7 @@ export const createClient = (config: Config = {}): Client => { }; if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security, - }); + await setAuthParams(opts); } if (opts.requestValidator) { @@ -65,7 +68,6 @@ export const createClient = (config: Config = {}): Client => { // @ts-expect-error const request: Client['request'] = async (options) => { - // @ts-expect-error const { opts, url } = await beforeRequest(options); try { // assign Axios here for consistency with fetch @@ -126,8 +128,11 @@ export const createClient = (config: Config = {}): Client => { }); }; + const _buildUrl: Client['buildUrl'] = (options) => + buildUrl({ axios: instance, ..._config, ...options }); + return { - buildUrl, + buildUrl: _buildUrl, connect: makeMethodFn('CONNECT'), delete: makeMethodFn('DELETE'), get: makeMethodFn('GET'), diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts index 7bd7b98807a15..3e877a5426f2c 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts @@ -9,6 +9,8 @@ export { } from '../core/bodySerializer.gen'; export { buildClientParams } from '../core/params.gen'; export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen'; +export type { ServerSentEventsResult } from '../core/serverSentEvents.gen'; +export type { ClientMeta } from '../core/types.gen'; export { createClient } from './client.gen'; export type { Client, diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts index 3a6f9244287a3..9d4eeb0bb6fed 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts @@ -60,6 +60,7 @@ export interface RequestOptions< }>, Pick< ServerSentEventsOptions, + | 'onRequest' | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' @@ -106,9 +107,14 @@ type MethodFn = , 'method'>, ) => RequestResult; -type SseFn = ( - options: Omit, 'method'>, -) => Promise>; +type SseFn = < + TData = unknown, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _TError = unknown, + ThrowOnError extends boolean = false, +>( + options: Omit, 'method'>, +) => Promise>; type RequestFn = ( options: Omit, 'method'> & @@ -117,13 +123,16 @@ type RequestFn = ; query?: Record; url: string; }, >( - options: TData & Options, + options: TData & + Pick< + RequestOptions, + 'axios' | 'baseURL' | 'paramsSerializer' | 'querySerializer' + >, ) => string; export type Client = CoreClient & { diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts index 1b4600f76873e..6b0faec428bec 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts @@ -13,8 +13,8 @@ import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' export const createQuerySerializer = ({ parameters = {}, ...args -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { +}: QuerySerializerOptions = {}): ((queryParams: T) => string) => { + const querySerializer = (queryParams: T): string => { const search: string[] = []; if (queryParams && typeof queryParams === 'object') { for (const name in queryParams) { @@ -83,14 +83,12 @@ const checkForExistence = ( return false; }; -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { +export async function setAuthParams( + options: Pick & { headers: Record; - }) => { - for (const auth of security) { + }, +): Promise { + for (const auth of options.security ?? []) { if (checkForExistence(options, auth.name)) { continue; } @@ -124,13 +122,13 @@ export const setAuthParams = async ({ break; } } -}; +} export const buildUrl: Client['buildUrl'] = (options) => { const instanceBaseUrl = options.axios?.defaults?.baseURL; const baseUrl = - !!options.baseURL && typeof options.baseURL === 'string' ? options.baseURL : instanceBaseUrl; + options.baseURL && typeof options.baseURL === 'string' ? options.baseURL : instanceBaseUrl; return getUrl({ baseUrl: baseUrl as string, @@ -192,7 +190,7 @@ export const mergeHeaders = ( mergedHeaders[key] = [...(mergedHeaders[key] ?? []), v as string]; } } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their + // assume object headers are meant to be JSON stringified, i.e., their // content value in OpenAPI specification is 'application/json' mergedHeaders[key] = typeof value === 'object' ? JSON.stringify(value) : (value as string); } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts index 3ebf9947883f3..c6636644876f4 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts @@ -9,6 +9,13 @@ export interface Auth { * @default 'header' */ in?: 'header' | 'query' | 'cookie'; + /** + * A unique identifier for the security scheme. + * + * Defined only when there are multiple security schemes whose `Auth` + * shape would otherwise be identical. + */ + key?: string; /** * Header or query parameter name. * diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts index 8ad92c9ffd6ac..67daca60f899b 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts @@ -4,7 +4,7 @@ import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerialize export type QuerySerializer = (query: Record) => string; -export type BodySerializer = (body: any) => any; +export type BodySerializer = (body: unknown) => unknown; type QuerySerializerOptionsObject = { allowReserved?: boolean; @@ -39,12 +39,10 @@ const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: }; export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T, - ): FormData => { + bodySerializer: (body: unknown): FormData => { const data = new FormData(); - Object.entries(body).forEach(([key, value]) => { + Object.entries(body as Record).forEach(([key, value]) => { if (value === undefined || value === null) { return; } @@ -60,15 +58,15 @@ export const formDataBodySerializer = { }; export const jsonBodySerializer = { - bodySerializer: (body: T): string => + bodySerializer: (body: unknown): string => JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)), }; export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { + bodySerializer: (body: unknown): string => { const data = new URLSearchParams(); - Object.entries(body).forEach(([key, value]) => { + Object.entries(body as Record).forEach(([key, value]) => { if (value === undefined || value === null) { return; } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts index 6099cab1b428e..5e8908f205ffb 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts @@ -62,7 +62,7 @@ type KeyMap = Map< } >; -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { +function buildKeyMap(fields: FieldsConfig, map?: KeyMap): KeyMap { if (!map) { map = new Map(); } @@ -85,33 +85,42 @@ const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { } return map; -}; +} interface Params { - body: unknown; + body?: unknown; headers: Record; path: Record; query: Record; } -const stripEmptySlots = (params: Params) => { +function stripEmptySlots(params: Params): void { for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { + if (slot === 'body') continue; + if (value && typeof value === 'object' && !Array.isArray(value) && !Object.keys(value).length) { delete params[slot as Slot]; } } -}; +} -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { +export function buildClientParams(args: ReadonlyArray, fields: FieldsConfig): Params { const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {}, + headers: Object.create(null), + path: Object.create(null), + query: Object.create(null), }; const map = buildKeyMap(fields); + function writeSlot(slot: Slot, key: string, value: unknown): void { + let record = params[slot] as Record | undefined; + if (record === undefined) { + record = Object.create(null) as Record; + params[slot] = record; + } + record[key] = value; + } + let config: FieldsConfig[number] | undefined; for (const [index, arg] of args.entries()) { @@ -128,7 +137,7 @@ export const buildClientParams = (args: ReadonlyArray, fields: FieldsCo const field = map.get(config.key)!; const name = field.map || config.key; if (field.in) { - (params[field.in] as Record)[name] = arg; + writeSlot(field.in, name, arg); } } else { params.body = arg; @@ -140,7 +149,7 @@ export const buildClientParams = (args: ReadonlyArray, fields: FieldsCo if (field) { if (field.in) { const name = field.map || key; - (params[field.in] as Record)[name] = value; + writeSlot(field.in, name, value); } else { params[field.map] = value; } @@ -149,11 +158,11 @@ export const buildClientParams = (args: ReadonlyArray, fields: FieldsCo if (extra) { const [prefix, slot] = extra; - (params[slot] as Record)[key.slice(prefix.length)] = value; + writeSlot(slot, key.slice(prefix.length), value); } else if ('allowExtra' in config && config.allowExtra) { for (const [slot, allowed] of Object.entries(config.allowExtra)) { if (allowed) { - (params[slot as Slot] as Record)[key] = value; + writeSlot(slot as Slot, key, value); break; } } @@ -166,4 +175,4 @@ export const buildClientParams = (args: ReadonlyArray, fields: FieldsCo stripEmptySlots(params); return params; -}; +} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts index 994b2848c63f0..fab1ed4b98ed5 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts @@ -25,7 +25,7 @@ interface SerializePrimitiveParam extends SerializePrimitiveOptions { value: string; } -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { +export const separatorArrayExplode = (style: ArraySeparatorStyle): '.' | ';' | ',' | '&' => { switch (style) { case 'label': return '.'; @@ -38,7 +38,7 @@ export const separatorArrayExplode = (style: ArraySeparatorStyle) => { } }; -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { +export const separatorArrayNoExplode = (style: ArraySeparatorStyle): ',' | '|' | '%20' => { switch (style) { case 'form': return ','; @@ -51,7 +51,7 @@ export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { } }; -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { +export const separatorObjectExplode = (style: ObjectSeparatorStyle): '.' | ';' | ',' | '&' => { switch (style) { case 'label': return '.'; @@ -72,7 +72,7 @@ export const serializeArrayParam = ({ value, }: SerializeOptions & { value: unknown[]; -}) => { +}): string => { if (!explode) { const joinedValues = ( allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) @@ -110,7 +110,7 @@ export const serializePrimitiveParam = ({ allowReserved, name, value, -}: SerializePrimitiveParam) => { +}: SerializePrimitiveParam): string => { if (value === undefined || value === null) { return ''; } @@ -134,7 +134,7 @@ export const serializeObjectParam = ({ }: SerializeOptions & { value: Record | Date; valueOnly?: boolean; -}) => { +}): string => { if (value instanceof Date) { return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts index 5000df606f37c..773b0650b19d0 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts @@ -14,7 +14,7 @@ export type JsonValue = /** * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes. */ -export const queryKeyJsonReplacer = (_key: string, value: unknown) => { +export const queryKeyJsonReplacer = (_key: string, value: unknown): unknown | undefined => { if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { return undefined; } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts index 6aa6cf02a4f40..ddf3c4d13a434 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts @@ -79,7 +79,7 @@ export type ServerSentEventsResult; }; -export const createSseClient = ({ +export function createSseClient({ onRequest, onSseError, onSseEvent, @@ -91,7 +91,7 @@ export const createSseClient = ({ sseSleepFn, url, ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { +}: ServerSentEventsOptions): ServerSentEventsResult { let lastEventId: string | undefined; const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); @@ -155,8 +155,7 @@ export const createSseClient = ({ const { done, value } = await reader.read(); if (done) break; buffer += value; - // Normalize line endings: CRLF -> LF, then CR -> LF - buffer = buffer.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + buffer = buffer.replace(/\r\n?/g, '\n'); // normalize line endings const chunks = buffer.split('\n\n'); buffer = chunks.pop() ?? ''; @@ -240,4 +239,4 @@ export const createSseClient = ({ const stream = createStream(); return { stream }; -}; +} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts index 97463257e43ec..c657c8599b347 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts @@ -80,7 +80,7 @@ export interface Config { requestValidator?: (data: unknown) => Promise; /** * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. + * for post-processing data, e.g., converting ISO strings into Date objects. */ responseTransformer?: (data: unknown) => Promise; /** @@ -91,6 +91,12 @@ export interface Config { responseValidator?: (data: unknown) => Promise; } +/** + * Arbitrary metadata passed through the `meta` request option. + */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface ClientMeta {} + type IsExactlyNeverOrNeverUndefined = [T] extends [never] ? true : [T] extends [never | undefined] diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts index e7ddbe3541176..af56e0711ec9e 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts @@ -13,9 +13,9 @@ export interface PathSerializer { url: string; } -export const PATH_PARAM_RE = /\{[^{}]+\}/g; +export const PATH_PARAM_RE: RegExp = /\{[^{}]+\}/g; -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer): string => { let url = _url; const matches = _url.match(PATH_PARAM_RE); if (matches) { @@ -94,7 +94,7 @@ export const getUrl = ({ query?: Record; querySerializer: QuerySerializer; url: string; -}) => { +}): string => { const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; let url = (baseUrl ?? '') + pathUrl; if (path) { @@ -114,7 +114,7 @@ export function getValidRequestBody(options: { body?: unknown; bodySerializer?: BodySerializer | null; serializedBody?: unknown; -}) { +}): unknown { const hasBody = options.body !== undefined; const isSerializedBody = hasBody && options.bodySerializer; @@ -126,7 +126,7 @@ export function getValidRequestBody(options: { return hasSerializedBody ? options.serializedBody : null; } - // not all clients implement a serializedBody property (i.e. client-axios) + // not all clients implement a serializedBody property (i.e., client-axios) return options.body !== '' ? options.body : null; } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts index d34e29be6ae19..330d470cae161 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts @@ -1,10 +1,10 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Client, Options as Options2, TDataShape } from './client'; +import type { Client, ClientMeta, Options as Options2, RequestResult, TDataShape } from './client'; import { client } from './client.gen'; import type { CreateTokenAllAdminsData, CreateTokenAllAdminsErrors, CreateTokenAllAdminsResponses, CreateTokenCliData, CreateTokenCliErrors, CreateTokenCliResponses, CreateTokenData, CreateTokenErrors, CreateTokenResponses, LoginAllAdminsData, LoginAllAdminsErrors } from './types.gen'; -export type Options = Options2 & { +export type Options = Options2 & { /** * You can provide a client instance returned by `createClient()` instead of * individual options. This might be also useful if you want to implement a @@ -15,7 +15,7 @@ export type Options; + meta?: keyof ClientMeta extends never ? Record : ClientMeta; }; /** @@ -23,7 +23,7 @@ export type Options(options?: Options) => (options?.client ?? client).get({ +export const createTokenAllAdmins = (options?: Options): RequestResult => (options?.client ?? client).get({ responseType: 'json', url: '/auth/token', ...options @@ -34,7 +34,7 @@ export const createTokenAllAdmins = (optio * * Authenticate the user. */ -export const createToken = (options: Options) => (options.client ?? client).post({ +export const createToken = (options: Options): RequestResult => (options.client ?? client).post({ responseType: 'json', url: '/auth/token', ...options, @@ -49,14 +49,14 @@ export const createToken = (options: Optio * * Login the user with no credentials. */ -export const loginAllAdmins = (options?: Options) => (options?.client ?? client).get({ url: '/auth/token/login', ...options }); +export const loginAllAdmins = (options?: Options): RequestResult => (options?.client ?? client).get({ url: '/auth/token/login', ...options }); /** * Create Token Cli * * Authenticate the user for the CLI. */ -export const createTokenCli = (options: Options) => (options.client ?? client).post({ +export const createTokenCli = (options: Options): RequestResult => (options.client ?? client).post({ responseType: 'json', url: '/auth/token/cli', ...options, diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json index a00c95abbcabd..eda98955deeef 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json @@ -18,20 +18,20 @@ "coverage": "vitest run --coverage" }, "dependencies": { - "@chakra-ui/react": "^3.36.0", + "@chakra-ui/react": "^3.36.1", "@hey-api/client-axios": "^0.9.1", - "@hey-api/openapi-ts": "^0.98.2", - "@tanstack/react-query": "^5.101.0", - "axios": "^1.18.0", + "@hey-api/openapi-ts": "^0.99.0", + "@tanstack/react-query": "^5.101.4", + "axios": "^1.18.1", "next-themes": "^0.4.6", - "react": "^19.2.7", + "react": "^19.2.8", "react-cookie": "^8.1.2", - "react-dom": "^19.2.7", - "react-hook-form": "^7.79.0", - "react-router-dom": "^7.18.0" + "react-dom": "^19.2.8", + "react-hook-form": "^7.83.0", + "react-router-dom": "^7.18.1" }, "devDependencies": { - "@7nohe/openapi-react-query-codegen": "^2.1.0", + "@7nohe/openapi-react-query-codegen": "^2.2.0", "@eslint/compat": "^2.1.0", "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", @@ -40,28 +40,28 @@ "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "8.61.1", - "@typescript-eslint/parser": "8.61.1", - "@typescript-eslint/utils": "^8.61.1", - "@vitejs/plugin-react-swc": "^4.3.1", - "@vitest/coverage-v8": "^4.1.9", - "eslint": "^10.5.0", + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/utils": "^8.65.0", + "@vitejs/plugin-react-swc": "^4.3.2", + "@vitest/coverage-v8": "^4.1.10", + "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-perfectionist": "^5.9.1", + "eslint-plugin-perfectionist": "^5.10.0", "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.3", "eslint-plugin-unicorn": "^67.0.0", - "happy-dom": "^20.10.6", - "prettier": "^3.8.4", + "happy-dom": "^20.11.1", + "prettier": "^3.9.6", "ts-morph": "^28.0.0", "typescript": "~6.0.3", - "typescript-eslint": "^8.61.1", - "vite": "^8.0.16", - "vite-plugin-css-injected-by-js": "^5.0.1", - "vitest": "^4.1.9" + "typescript-eslint": "^8.65.0", + "vite": "^8.1.5", + "vite-plugin-css-injected-by-js": "^5.0.2", + "vitest": "^4.1.10" }, "pnpm": { "minimumReleaseAge": 5760, @@ -89,7 +89,10 @@ "vite@>=7.0.0 <=7.3.1": ">=7.3.2", "vite@>=7.1.0 <=7.3.1": ">=7.3.2", "axios@<1.15.0": ">=1.15.0", - "esbuild@>=0.17.0 <0.28.1": ">=0.28.1" + "esbuild@>=0.17.0 <0.28.1": ">=0.28.1", + "@babel/core@<=7.29.0": ">=7.29.6", + "js-yaml@>=4.0.0 <4.3.0": "^4.3.0", + "@hey-api/openapi-ts@<0.97.3": ">=0.97.3" } } } diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml index 3c11980f1244e..e14c95e1f3a91 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml @@ -25,66 +25,69 @@ overrides: vite@>=7.1.0 <=7.3.1: '>=7.3.2' axios@<1.15.0: '>=1.15.0' esbuild@>=0.17.0 <0.28.1: '>=0.28.1' + '@babel/core@<=7.29.0': '>=7.29.6' + js-yaml@>=4.0.0 <4.3.0: ^4.3.0 + '@hey-api/openapi-ts@<0.97.3': '>=0.97.3' importers: .: dependencies: '@chakra-ui/react': - specifier: ^3.36.0 - version: 3.36.0(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^3.36.1 + version: 3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@hey-api/client-axios': specifier: ^0.9.1 - version: 0.9.1(@hey-api/openapi-ts@0.98.2(magicast@0.5.3)(typescript@6.0.3))(axios@1.18.0) + version: 0.9.1(@hey-api/openapi-ts@0.99.0(magicast@0.5.3)(typescript@6.0.3))(axios@1.18.1) '@hey-api/openapi-ts': - specifier: ^0.98.2 - version: 0.98.2(magicast@0.5.3)(typescript@6.0.3) + specifier: ^0.99.0 + version: 0.99.0(magicast@0.5.3)(typescript@6.0.3) '@tanstack/react-query': - specifier: ^5.101.0 - version: 5.101.0(react@19.2.7) + specifier: ^5.101.4 + version: 5.101.4(react@19.2.8) axios: - specifier: ^1.18.0 - version: 1.18.0 + specifier: ^1.18.1 + version: 1.18.1 next-themes: specifier: ^0.4.6 - version: 0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + version: 0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react: - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.8 + version: 19.2.8 react-cookie: specifier: ^8.1.2 - version: 8.1.2(@types/react@19.2.17)(react@19.2.7) + version: 8.1.2(@types/react@19.2.17)(react@19.2.8) react-dom: - specifier: ^19.2.7 - version: 19.2.7(react@19.2.7) + specifier: ^19.2.8 + version: 19.2.8(react@19.2.8) react-hook-form: - specifier: ^7.79.0 - version: 7.79.0(react@19.2.7) + specifier: ^7.83.0 + version: 7.83.0(react@19.2.8) react-router-dom: - specifier: ^7.18.0 - version: 7.18.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^7.18.1 + version: 7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) devDependencies: '@7nohe/openapi-react-query-codegen': - specifier: ^2.1.0 - version: 2.1.0(commander@15.0.0)(magicast@0.5.3)(ts-morph@28.0.0)(typescript@6.0.3) + specifier: ^2.2.0 + version: 2.2.0(commander@15.0.0)(magicast@0.5.3)(ts-morph@28.0.0)(typescript@6.0.3) '@eslint/compat': specifier: ^2.1.0 - version: 2.1.0(eslint@10.5.0(jiti@2.7.0)) + version: 2.1.0(eslint@10.8.0(jiti@2.7.0)) '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.5.0(jiti@2.7.0)) + version: 10.0.1(eslint@10.8.0(jiti@2.7.0)) '@stylistic/eslint-plugin': specifier: ^5.10.0 - version: 5.10.0(eslint@10.5.0(jiti@2.7.0)) + version: 5.10.0(eslint@10.8.0(jiti@2.7.0)) '@testing-library/jest-dom': specifier: ^6.9.1 version: 6.9.1 '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 - version: 6.0.2(prettier@3.8.4) + version: 6.0.2(prettier@3.9.6) '@types/react': specifier: ^19.2.17 version: 19.2.17 @@ -92,53 +95,53 @@ importers: specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.17) '@typescript-eslint/eslint-plugin': - specifier: 8.61.1 - version: 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.65.0 + version: 8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.61.1 - version: 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/utils': - specifier: ^8.61.1 - version: 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) '@vitejs/plugin-react-swc': - specifier: ^4.3.1 - version: 4.3.1(@swc/helpers@0.5.23)(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)) + specifier: ^4.3.2 + version: 4.3.2(@swc/helpers@0.5.23)(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)) '@vitest/coverage-v8': - specifier: ^4.1.9 - version: 4.1.9(vitest@4.1.9) + specifier: ^4.1.10 + version: 4.1.10(vitest@4.1.10) eslint: - specifier: ^10.5.0 - version: 10.5.0(jiti@2.7.0) + specifier: ^10.8.0 + version: 10.8.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.5.0(jiti@2.7.0)) + version: 10.1.8(eslint@10.8.0(jiti@2.7.0)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@10.5.0(jiti@2.7.0)) + version: 6.10.2(eslint@10.8.0(jiti@2.7.0)) eslint-plugin-perfectionist: - specifier: ^5.9.1 - version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + specifier: ^5.10.0 + version: 5.10.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-prettier: specifier: ^5.5.6 - version: 5.5.6(eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)))(eslint@10.5.0(jiti@2.7.0))(prettier@3.8.4) + version: 5.5.6(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)))(eslint@10.8.0(jiti@2.7.0))(prettier@3.9.6) eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@10.5.0(jiti@2.7.0)) + version: 7.37.5(eslint@10.8.0(jiti@2.7.0)) eslint-plugin-react-hooks: specifier: ^7.1.1 - version: 7.1.1(eslint@10.5.0(jiti@2.7.0)) + version: 7.1.1(eslint@10.8.0(jiti@2.7.0)) eslint-plugin-react-refresh: specifier: ^0.5.3 - version: 0.5.3(eslint@10.5.0(jiti@2.7.0)) + version: 0.5.3(eslint@10.8.0(jiti@2.7.0)) eslint-plugin-unicorn: specifier: ^67.0.0 - version: 67.0.0(eslint@10.5.0(jiti@2.7.0)) + version: 67.0.0(eslint@10.8.0(jiti@2.7.0)) happy-dom: - specifier: ^20.10.6 - version: 20.10.6 + specifier: ^20.11.1 + version: 20.11.1 prettier: - specifier: ^3.8.4 - version: 3.8.4 + specifier: ^3.9.6 + version: 3.9.6 ts-morph: specifier: ^28.0.0 version: 28.0.0 @@ -146,28 +149,28 @@ importers: specifier: ~6.0.3 version: 6.0.3 typescript-eslint: - specifier: ^8.61.1 - version: 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) vite: - specifier: ^8.0.16 - version: 8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3) + specifier: ^8.1.5 + version: 8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3) vite-plugin-css-injected-by-js: - specifier: ^5.0.1 - version: 5.0.1(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)) + specifier: ^5.0.2 + version: 5.0.2(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)) vitest: - specifier: ^4.1.9 - version: 4.1.9(@types/node@26.0.0)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.6)(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)) + specifier: ^4.1.10 + version: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)) packages: - '@7nohe/openapi-react-query-codegen@2.1.0': - resolution: {integrity: sha512-aUIjrGRASWQC7CnKJilZlp5klrszZXudQNjNb91R1S1oUwhoP0HBLQYQp5GvkQXdn2+xrVJkY7ukptPR9z/0QA==} - engines: {node: '>=20.19.0', pnpm: '>=9'} + '@7nohe/openapi-react-query-codegen@2.2.0': + resolution: {integrity: sha512-QSvdjXpAL2JaT85LEBC7U65uQ+/wqOKkMdDrmX56RmEI/1QBDf68f12Gd5Xsxp3r55hs/NCJ7gPZ/vJw5a78fg==} + engines: {node: '>=22.18.0', pnpm: '>=9'} hasBin: true peerDependencies: commander: 12.x - ts-morph: 27.x - typescript: 5.x + ts-morph: 28.x + typescript: 5.x || 6.x '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} @@ -190,29 +193,33 @@ packages: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} + '@babel/code-frame@8.0.0': + resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} + '@babel/compat-data@8.0.0': + resolution: {integrity: sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/core@8.0.1': + resolution: {integrity: sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/generator@7.28.6': resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.29.7': - resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} - engines: {node: '>=6.9.0'} + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@8.0.0': + resolution: {integrity: sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} @@ -222,20 +229,14 @@ packages: resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} + '@babel/helper-globals@8.0.0': + resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-module-imports@7.29.7': resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -244,17 +245,25 @@ packages: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} - engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helpers@8.0.0': + resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/parser@7.28.6': resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} @@ -271,6 +280,16 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + '@babel/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} @@ -287,17 +306,21 @@ packages: resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/traverse@7.28.6': resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.7': - resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} - engines: {node: '>=6.9.0'} + '@babel/traverse@8.0.4': + resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/types@7.28.6': resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} @@ -311,25 +334,33 @@ packages: resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@chakra-ui/react@3.36.0': - resolution: {integrity: sha512-6AxUbJsC6yyTzPeYL8sxyAL07lflT0NA+S6tcPzEuwdMux+benRMFOpPktnkifWKl/Vq/JD7fhxDyMuDQ4M0gA==} + '@chakra-ui/react@3.36.1': + resolution: {integrity: sha512-8uPVBdkw9CfwDQSGGmNqx8jLygUanV9virh2dwbj3x02Cu5bmw12ZCRdD/RZ+00+KrklJZlVnmG20y7PwLhyqg==} peerDependencies: '@emotion/react': '>=11' react: '>=18' react-dom: '>=18' - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -375,6 +406,12 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -398,8 +435,8 @@ packages: resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.6.0': - resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/core@1.2.1': @@ -423,72 +460,44 @@ packages: resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@floating-ui/core@1.7.5': - resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} - '@floating-ui/dom@1.7.6': - resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} - '@floating-ui/utils@0.2.11': - resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} '@hey-api/client-axios@0.9.1': resolution: {integrity: sha512-fvpOdnEz6tu5T2+IMNZW3g9mAZwaXavqpsvtapEZNtYxyYtQ+lQs9wJn/VPhZEvdXAXu8HPTCRpmfa0t1aRATA==} deprecated: Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts. peerDependencies: - '@hey-api/openapi-ts': < 2 + '@hey-api/openapi-ts': '>=0.97.3' axios: '>=1.15.0' - '@hey-api/codegen-core@0.7.0': - resolution: {integrity: sha512-HglL4B4QwpzocE+c8qDU6XK8zMf8W8Pcv0RpFDYxHuYALWLTnpDUuEsglC7NQ4vC1maoXsBpMbmwpco0N4QviA==} - engines: {node: '>=20.19.0'} - peerDependencies: - typescript: '>=5.5.3' - - '@hey-api/codegen-core@0.9.0': - resolution: {integrity: sha512-OK9/R8WuujwgvnrDIPnEiIf6WnfUOi3GaEr6kIngqoI5FUQwYbeDKHE/frTVUl2A76ZQPCrMknHtPx6Gqtwf8Q==} + '@hey-api/codegen-core@0.9.1': + resolution: {integrity: sha512-s97jL1dgTMuiMHv2BZ1X4Tgd99Mf9GOvGdNqNcGwIMmnR+PgYNoraj4Zvp134MKsNCap/m7k0r0vKKnl56pj4w==} engines: {node: '>=22.18.0'} - '@hey-api/json-schema-ref-parser@1.2.4': - resolution: {integrity: sha512-uuOaZ6tStUgRJFUqnX3Xdbs792++ezxOLI5NMxuikVklpbFWk2wcvIZbeX+qTWDv6kiS1Ik2EVKQgeQFWHML4A==} - engines: {node: '>= 16'} - - '@hey-api/json-schema-ref-parser@1.4.3': - resolution: {integrity: sha512-UzGSDzh3QUhrnwl4atnHc2YqDO6KemYVEOwl1Ynowm/tcr0XlpdHOpyWr5UaWIJfiXTXdYRIC9k2Yxm19pcPzQ==} + '@hey-api/json-schema-ref-parser@1.4.4': + resolution: {integrity: sha512-otmd+zCxbYVBIp/mlMTnGkvlNYLkVKgs3VOIq0kSnenhB1+fRwLPQIeSwyWM6E51oXhUedkYjVsVpkVexeuJOA==} engines: {node: '>=22.18.0'} - '@hey-api/openapi-ts@0.92.3': - resolution: {integrity: sha512-D+2ySL+PXvp1iZtS+1gTEeGChwjHT3d/a6o9IwAaNdGJVsI1lPqESZx7vxqjoUtE/DruovGZC2/jPc/kA5IQPg==} - engines: {node: '>=20.19.0'} - hasBin: true - peerDependencies: - typescript: '>=5.5.3' - - '@hey-api/openapi-ts@0.98.2': - resolution: {integrity: sha512-2nVJXH8tpFPGTBOhxyjEd1Jw0hsRqJqeTQW3kltAjVdSU4YWxeu97x5sgNOmsbsfeg6Dqz7Wfzs26walBOuswA==} + '@hey-api/openapi-ts@0.99.0': + resolution: {integrity: sha512-SePU/5oEWWkvUBYmvzdYRctseoLuskyhs4ET0RvLIcmzc8yLQoA2R+KtBIQ8bPsoSUB0m4E5SmBnl6aGSA0szQ==} engines: {node: '>=22.18.0'} hasBin: true peerDependencies: typescript: '>=5.5.3 || >=6.0.0 || 6.0.1-rc' - '@hey-api/shared@0.1.2': - resolution: {integrity: sha512-dcldulfNI1xiXl/zhdXKDlNX2bvY0TOBWRRyFXNtcfPddMEFcrlXGmi/wk6LN4fPyDO8lM7FAM9aEpkEdUo92A==} - engines: {node: '>=20.19.0'} - peerDependencies: - typescript: '>=5.5.3' - - '@hey-api/shared@0.4.8': - resolution: {integrity: sha512-29Pg2FB0UW20pplYgcfiQn1hQYpbZ9D2gdDJc7nDK3xh3pvHOTGP0v3R2ueFpFnw9GN1SRhIdhiVuAYWMDimjA==} + '@hey-api/shared@0.5.0': + resolution: {integrity: sha512-JN/j4Ebh4cJGYIQ5cwWuqe7GeSUyQoz7oC51WqyhKOcrejK6DKZMDkshc5d1eKTRuRL+rjozuRcoUaZZn2DGPw==} engines: {node: '>=22.18.0'} '@hey-api/spec-types@0.2.0': resolution: {integrity: sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg==} - '@hey-api/types@0.1.3': - resolution: {integrity: sha512-mZaiPOWH761yD4GjDQvtjS2ZYLu5o5pI1TVSvV/u7cmbybv51/FVtinFBeaE1kFQCKZ8OQpn2ezjLBJrKsGATw==} - peerDependencies: - typescript: '>=5.5.3' - '@hey-api/types@0.1.4': resolution: {integrity: sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg==} @@ -521,9 +530,6 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -541,108 +547,114 @@ packages: resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} - '@pandacss/is-valid-prop@1.11.3': - resolution: {integrity: sha512-YaHK+p5DaN8AUpsRx5OqqGxaZzn8uNIdVhP+K1cjvjv3+Qa9D/75/A1dPyLmfKrSRJc8UoR9WN9fxQX0rVzhzQ==} + '@pandacss/is-valid-prop@1.11.5': + resolution: {integrity: sha512-8m1/gG0wSRMa1QypCkWzeKUeMKY7k14nxsJCHs7Z1g1fI9I7WsLjW/VI58bLZdJxAxtoreMtm6TfIITda8P4zQ==} engines: {node: '>=20'} '@pkgr/core@0.3.6': resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} engines: {node: ^14.18.0 || >=16.0.0} - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -659,80 +671,86 @@ packages: peerDependencies: eslint: ^9.0.0 || ^10.0.0 - '@swc/core-darwin-arm64@1.15.40': - resolution: {integrity: sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ==} + '@swc/core-darwin-arm64@1.15.46': + resolution: {integrity: sha512-IsISIT22EfktVJrlvIpnAxG2u/A9aob9l99HMlx80x72WlFmFPk1V3UhkEzx86eJP8hw049KTFv/RISho2cq2Q==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.40': - resolution: {integrity: sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA==} + '@swc/core-darwin-x64@1.15.46': + resolution: {integrity: sha512-4Tj4ppVIPCmUMpmGFiGtyEriwLyJ+yi/US4WfBrP/ok8COGddDZXLEzQETnKyK46mjvr1v0jevrS23zjoff7vA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.40': - resolution: {integrity: sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA==} + '@swc/core-linux-arm-gnueabihf@1.15.46': + resolution: {integrity: sha512-i8tUGnNjyOgMmfmgFSg4aeJLQoFyfpIHK5FjpQAwpRyQIqEUB2w1e8zIDQzY1WhOxx8NoS1S5iUL813Un4Sf5A==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.40': - resolution: {integrity: sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ==} + '@swc/core-linux-arm64-gnu@1.15.46': + resolution: {integrity: sha512-c0OnhqzdhfOvv6qhNCcByepB+sNYOGZyhtr2Qa6ZCHvAWTYhSRw4j/u92Stue9PbZ/6q74b9nHzi76+kVzqQHQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] - '@swc/core-linux-arm64-musl@1.15.40': - resolution: {integrity: sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ==} + '@swc/core-linux-arm64-musl@1.15.46': + resolution: {integrity: sha512-imyRpNEcUzFQFV2LE4jL68ErvmKEuZCbvZru77iQREunJ+bR4i658cupTgtG1mLYM3F1Tzy3Sb9xYb02KghWTg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] - '@swc/core-linux-ppc64-gnu@1.15.40': - resolution: {integrity: sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA==} + '@swc/core-linux-ppc64-gnu@1.15.46': + resolution: {integrity: sha512-ctEfcl/HcUeomK33cbySiHZm98GEDIxTm1EkpBsYCiHxElYBzvTXVeuQT2YwbUXn9XCrjiw4ipyUNk33k26qRg==} engines: {node: '>=10'} cpu: [ppc64] os: [linux] + libc: [glibc] - '@swc/core-linux-s390x-gnu@1.15.40': - resolution: {integrity: sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg==} + '@swc/core-linux-s390x-gnu@1.15.46': + resolution: {integrity: sha512-DxlMdnt84TtRVTv7WL/thWyz9+QU8QZNNoAP9rrk0P68LziuhfePp8MjQ44zIprpTHTsEwyziIuGUUN5iSC1bQ==} engines: {node: '>=10'} cpu: [s390x] os: [linux] + libc: [glibc] - '@swc/core-linux-x64-gnu@1.15.40': - resolution: {integrity: sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg==} + '@swc/core-linux-x64-gnu@1.15.46': + resolution: {integrity: sha512-SKxI7J6t90XPl8hRUqtJi9NfGdunN/E/vZMc7Bc0figeRdOPDBT+Tm8g7cx9xM0T0mewh2l+8dewa3Am27/P+A==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] - '@swc/core-linux-x64-musl@1.15.40': - resolution: {integrity: sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA==} + '@swc/core-linux-x64-musl@1.15.46': + resolution: {integrity: sha512-qj9T6B7bosI0VEsrWOVXZN1OXxS8Tp63ywyrLxNdOycnUtLdkgYcoBsN5y8ImnDDsnwrEWZOy1e+J4xSe7mA3Q==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] - '@swc/core-win32-arm64-msvc@1.15.40': - resolution: {integrity: sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A==} + '@swc/core-win32-arm64-msvc@1.15.46': + resolution: {integrity: sha512-8p7l4c3LU+eA5g9Et1JPhNeMC1oQwXTGU+uah8DPIBX7YXzqswvaBtyKVmXefVGi/DJU1x3YJsc3mbAp9aWzSQ==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.40': - resolution: {integrity: sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw==} + '@swc/core-win32-ia32-msvc@1.15.46': + resolution: {integrity: sha512-tUEnfr3Bn9u6FOjUb3PN9p+09qZC2j+wNDLKHzXXZn22rqGcUqR/ohCRSS+nG9B9+X+U+3FewNEHJkTmdIvMjQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.40': - resolution: {integrity: sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w==} + '@swc/core-win32-x64-msvc@1.15.46': + resolution: {integrity: sha512-Vux7UDzBJYQggSuPfcl2w9iu+IJpgpRCxHzgCaVkELnAXAE4XZMOTX9HNcaNiwfeIDqdu2rkr69RuDm6wY8neA==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.40': - resolution: {integrity: sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg==} + '@swc/core@1.15.46': + resolution: {integrity: sha512-Ri3em2mBpq3h2zSPliCYl63otDGqek8PPEfv2nWgRQEbZ/VBCNyypVTVQ6cEbTCXBhy+WE2T3fQb08moIyuYaw==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -746,14 +764,14 @@ packages: '@swc/helpers@0.5.23': resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} - '@swc/types@0.1.26': - resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} + '@swc/types@0.1.27': + resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==} - '@tanstack/query-core@5.101.0': - resolution: {integrity: sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow==} + '@tanstack/query-core@5.101.4': + resolution: {integrity: sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw==} - '@tanstack/react-query@5.101.0': - resolution: {integrity: sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg==} + '@tanstack/react-query@5.101.4': + resolution: {integrity: sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA==} peerDependencies: react: ^18 || ^19 @@ -802,8 +820,8 @@ packages: '@ts-morph/common@0.29.0': resolution: {integrity: sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==} - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -820,16 +838,22 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + '@types/hoist-non-react-statics@3.3.7': resolution: {integrity: sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==} peerDependencies: '@types/react': '*' + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@26.0.0': - resolution: {integrity: sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==} + '@types/node@26.1.2': + resolution: {integrity: sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -848,39 +872,39 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.61.1': - resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==} + '@typescript-eslint/eslint-plugin@8.65.0': + resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.61.1 + '@typescript-eslint/parser': ^8.65.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.61.1': - resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==} + '@typescript-eslint/parser@8.65.0': + resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.61.1': - resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==} + '@typescript-eslint/project-service@8.65.0': + resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.61.1': - resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==} + '@typescript-eslint/scope-manager@8.65.0': + resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.61.1': - resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==} + '@typescript-eslint/tsconfig-utils@8.65.0': + resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.61.1': - resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==} + '@typescript-eslint/type-utils@8.65.0': + resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -890,47 +914,47 @@ packages: resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.61.1': - resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} + '@typescript-eslint/types@8.65.0': + resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.61.1': - resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==} + '@typescript-eslint/typescript-estree@8.65.0': + resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.61.1': - resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==} + '@typescript-eslint/utils@8.65.0': + resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.61.1': - resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==} + '@typescript-eslint/visitor-keys@8.65.0': + resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-react-swc@4.3.1': - resolution: {integrity: sha512-PaeokKjAGraNN+s5SIApgsktnJprIyt3zgEIu7awnEdfn29QiB2crTcCzyi2XGpX9rUnTc0cKU07Wm0N0g7H2w==} + '@vitejs/plugin-react-swc@4.3.2': + resolution: {integrity: sha512-MlSlmSAYbYwPjGa+CjOAqwij09iPYAQDHwx8osVkwoDamCxXlg+avpkC65Ysv+L/uqUWvRTsnJCKPjVhZih/sA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: '>=7.3.2' - '@vitest/coverage-v8@4.1.9': - resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} + '@vitest/coverage-v8@4.1.10': + resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} peerDependencies: - '@vitest/browser': 4.1.9 - vitest: 4.1.9 + '@vitest/browser': 4.1.10 + vitest: 4.1.10 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.9': - resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} - '@vitest/mocker@4.1.9': - resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} peerDependencies: msw: ^2.4.9 vite: '>=7.3.2' @@ -940,20 +964,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.9': - resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} - '@vitest/runner@4.1.9': - resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} - '@vitest/snapshot@4.1.9': - resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} - '@vitest/spy@4.1.9': - resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} - '@vitest/utils@4.1.9': - resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} '@zag-js/accordion@1.41.2': resolution: {integrity: sha512-7G//V7svGGT8k5avw7bbQvbRC0Q/9QtX51b4iyAB1alR9E5mFd6Ch8q4njwcXClMQ7xePS3jUfVnzVGiRInEiQ==} @@ -1199,8 +1223,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} engines: {node: '>=0.4.0'} hasBin: true @@ -1290,8 +1314,8 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios@1.18.0: - resolution: {integrity: sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw==} + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -1313,15 +1337,15 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - brace-expansion@1.1.13: - resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + brace-expansion@1.1.16: + resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} - brace-expansion@2.0.3: - resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@2.1.2: + resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} browserslist@4.28.2: resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} @@ -1340,14 +1364,6 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} - c12@3.3.3: - resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} - peerDependencies: - magicast: '*' - peerDependenciesMeta: - magicast: - optional: true - c12@3.3.4: resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} peerDependencies: @@ -1394,12 +1410,6 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - citty@0.2.2: - resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} @@ -1418,10 +1428,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} - commander@15.0.0: resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} engines: {node: '>=22.12.0'} @@ -1432,10 +1438,6 @@ packages: confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -1556,6 +1558,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} @@ -1579,8 +1585,8 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + es-module-lexer@2.3.0: + resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -1618,8 +1624,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-perfectionist@5.9.1: - resolution: {integrity: sha512-30mHLNfEhzwaq5cquyWgnzrNXvT8AzwIwyeH5aj4U5ajhHSF2uiO6i09xpMDLv7koaZVTjLsvYF4m3gK/15tyA==} + eslint-plugin-perfectionist@5.10.0: + resolution: {integrity: sha512-HiqpDrUDbGrMC6iHQbemgDyHJ0366Vyz/qRWmxQcSAkmG25cXr8BdRgx8yAhOKhEfBXn8Rnf/mTCsV4EqUJSxg==} engines: {node: ^20.0.0 || >=22.0.0} peerDependencies: eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 @@ -1677,8 +1683,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.5.0: - resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} + eslint@10.8.0: + resolution: {integrity: sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -1714,12 +1720,12 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + exsolve@1.1.0: + resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1761,8 +1767,8 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} follow-redirects@1.16.0: resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} @@ -1815,10 +1821,6 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - giget@2.0.0: - resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} - hasBin: true - giget@3.3.0: resolution: {integrity: sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==} hasBin: true @@ -1839,8 +1841,8 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} - happy-dom@20.10.6: - resolution: {integrity: sha512-6QD0ilzDDt93tX44y8tbmZdAcdTRYDhUP+Asgi6pC8Pp5IA3cvaZGyoVN/EGtlq9ziT65iPuBBn3ASLr6hCgVw==} + happy-dom@20.11.1: + resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -1894,14 +1896,17 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -2064,10 +2069,6 @@ packages: javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -2078,8 +2079,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} hasBin: true jsesc@3.1.0: @@ -2122,74 +2123,78 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: @@ -2202,15 +2207,13 @@ packages: lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} - lodash@4.18.1: - resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + engines: {node: 20 || >=22} lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} @@ -2242,8 +2245,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} minimatch@3.1.5: @@ -2256,8 +2259,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -2274,18 +2277,10 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - node-releases@2.0.48: resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==} engines: {node: '>=18'} - nypm@0.6.5: - resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} - engines: {node: '>=18'} - hasBin: true - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2389,8 +2384,9 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} pkg-types@2.3.1: resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} @@ -2403,8 +2399,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.22: + resolution: {integrity: sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==} engines: {node: ^10 || ^12 || >=14} powershell-utils@0.1.0: @@ -2419,8 +2415,8 @@ packages: resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} - prettier@3.8.4: - resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} + prettier@3.9.6: + resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} engines: {node: '>=14'} hasBin: true @@ -2445,9 +2441,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - rc9@2.1.2: - resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - rc9@3.0.1: resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} @@ -2456,13 +2449,13 @@ packages: peerDependencies: react: '>= 16.3.0' - react-dom@19.2.7: - resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} + react-dom@19.2.8: + resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} peerDependencies: - react: ^19.2.7 + react: ^19.2.8 - react-hook-form@7.79.0: - resolution: {integrity: sha512-mhYp/MTmXvzYX6AJcJVko0rktoIhhmRnEouObj4wF5i/tCttgJvnp1+9wRkpITZjDTqpo4IOSJqu0dBlPlV/Lw==} + react-hook-form@7.83.0: + resolution: {integrity: sha512-AXt8cMCmx5a7u4uvpb2uRFVrWQhllI4pV+LSykxIac/hjt44TnQkmX9BKuQi2i+LDC62esmiLpilkav+kjVf/A==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -2473,15 +2466,15 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-router-dom@7.18.0: - resolution: {integrity: sha512-Fi0yY6kgtKae/Th2xibdWK0KSdYZ4B53Gyf6wRtomOKWgpNm7H7+DyfDhncdz9FKbpS+1jmDhg3F4WoGJ+yFOA==} + react-router-dom@7.18.1: + resolution: {integrity: sha512-KaZh+X/6UtEp28x51AUYZDMg9NGoz2ja3dNHa+ta/tk40vCzKhQ/RypCWBMLbmDr6//E24Vv5uPsrqXFozdkAg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' react-dom: '>=18' - react-router@7.18.0: - resolution: {integrity: sha512-pTTGt8J+ji1NOmYnjzT+bAJy/1zD+Jp4ziO6cL7T3ZLvXKtusO7BpFqlRXitqpcPVqllsIXFHRMt+2/k3Xn6HQ==} + react-router@7.18.1: + resolution: {integrity: sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -2490,8 +2483,8 @@ packages: react-dom: optional: true - react@19.2.7: - resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} + react@19.2.8: + resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} engines: {node: '>=0.10.0'} readdirp@5.0.0: @@ -2530,8 +2523,8 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2558,13 +2551,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - - semver@7.8.2: - resolution: {integrity: sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true @@ -2626,8 +2614,8 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} @@ -2722,8 +2710,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.61.1: - resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==} + typescript-eslint@8.65.0: + resolution: {integrity: sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2756,18 +2744,18 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - vite-plugin-css-injected-by-js@5.0.1: - resolution: {integrity: sha512-JSB0jjN4VCKqG7XTUdrwiIl5gA+z2yi/tAl9WHo0X4sdyJ1yrmbLOEjf95TDoDIIuKr4GJIc7lMJG0CT88eEUQ==} + vite-plugin-css-injected-by-js@5.0.2: + resolution: {integrity: sha512-Hvg48QfYsCL53ju9T5zTC0Ofg90XLa8t5zhhKmPYbayoMQieNcQDkkRX8pv4TAcKPZwVisLFiwDy5uBjOn+3Ow==} peerDependencies: vite: '>8.0.0-0' - vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + vite@8.1.5: + resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + '@vitejs/devtools': ^0.3.0 esbuild: '>=0.28.1' jiti: '>=1.21.0' less: ^4.0.0 @@ -2804,20 +2792,20 @@ packages: yaml: optional: true - vitest@4.1.9: - resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.9 - '@vitest/browser-preview': 4.1.9 - '@vitest/browser-webdriverio': 4.1.9 - '@vitest/coverage-istanbul': 4.1.9 - '@vitest/coverage-v8': 4.1.9 - '@vitest/ui': 4.1.9 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 happy-dom: '>=20.8.8' jsdom: '*' vite: '>=7.3.2' @@ -2879,8 +2867,8 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + ws@8.21.1: + resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2895,9 +2883,6 @@ packages: resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} engines: {node: '>=20'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@1.10.3: resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} @@ -2922,9 +2907,9 @@ packages: snapshots: - '@7nohe/openapi-react-query-codegen@2.1.0(commander@15.0.0)(magicast@0.5.3)(ts-morph@28.0.0)(typescript@6.0.3)': + '@7nohe/openapi-react-query-codegen@2.2.0(commander@15.0.0)(magicast@0.5.3)(ts-morph@28.0.0)(typescript@6.0.3)': dependencies: - '@hey-api/openapi-ts': 0.92.3(magicast@0.5.3)(typescript@6.0.3) + '@hey-api/openapi-ts': 0.99.0(magicast@0.5.3)(typescript@6.0.3) commander: 15.0.0 cross-spawn: 7.0.6 ts-morph: 28.0.0 @@ -2934,7 +2919,7 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@ark-ui/react@5.37.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@ark-ui/react@5.37.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@internationalized/date': 3.12.2 '@zag-js/accordion': 1.41.2 @@ -2984,7 +2969,7 @@ snapshots: '@zag-js/qr-code': 1.41.2 '@zag-js/radio-group': 1.41.2 '@zag-js/rating-group': 1.41.2 - '@zag-js/react': 1.41.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@zag-js/react': 1.41.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@zag-js/scroll-area': 1.41.2 '@zag-js/select': 1.41.2 '@zag-js/signature-pad': 1.41.2 @@ -3003,8 +2988,8 @@ snapshots: '@zag-js/tree-view': 1.41.2 '@zag-js/types': 1.41.2 '@zag-js/utils': 1.41.2 - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) '@babel/code-frame@7.28.6': dependencies: @@ -3024,27 +3009,31 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} + '@babel/code-frame@8.0.0': + dependencies: + '@babel/helper-validator-identifier': 8.0.4 + js-tokens: 10.0.0 + + '@babel/compat-data@8.0.0': {} - '@babel/core@7.29.0': + '@babel/core@8.0.1': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-compilation-targets': 8.0.0 + '@babel/helpers': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@types/gensync': 1.0.5 convert-source-map: 2.0.0 - debug: 4.4.3 + empathic: 2.0.1 gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + obug: 2.1.3 + semver: 7.8.5 '@babel/generator@7.28.6': dependencies: @@ -3054,54 +3043,41 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/generator@7.29.1': + '@babel/generator@7.29.8': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/generator@7.29.7': + '@babel/generator@8.0.0': dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.28.6': + '@babel/helper-compilation-targets@8.0.0': dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 + '@babel/compat-data': 8.0.0 + '@babel/helper-validator-option': 8.0.0 browserslist: 4.28.2 - lru-cache: 5.1.1 - semver: 6.3.1 + lru-cache: 11.5.2 + semver: 7.8.5 '@babel/helper-globals@7.28.0': {} '@babel/helper-globals@7.29.7': {} - '@babel/helper-module-imports@7.28.6': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color + '@babel/helper-globals@8.0.0': {} '@babel/helper-module-imports@7.29.7': dependencies: - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color @@ -3109,14 +3085,18 @@ snapshots: '@babel/helper-string-parser@7.29.7': {} + '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-identifier@8.0.4': {} + + '@babel/helper-validator-option@8.0.0': {} - '@babel/helpers@7.29.2': + '@babel/helpers@8.0.0': dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 '@babel/parser@7.28.6': dependencies: @@ -3130,6 +3110,14 @@ snapshots: dependencies: '@babel/types': 7.29.7 + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 + + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + '@babel/runtime@7.28.6': {} '@babel/runtime@7.29.7': {} @@ -3143,8 +3131,14 @@ snapshots: '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 '@babel/traverse@7.28.6': dependencies: @@ -3158,30 +3152,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/traverse@7.29.7': + '@babel/traverse@7.29.8': dependencies: '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 + '@babel/generator': 7.29.8 '@babel/helper-globals': 7.29.7 - '@babel/parser': 7.29.7 + '@babel/parser': 7.29.8 '@babel/template': 7.29.7 - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 debug: 4.4.3 transitivePeerDependencies: - supports-color + '@babel/traverse@8.0.4': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-globals': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 + obug: 2.1.3 + '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -3197,33 +3189,43 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + '@bcoe/v8-coverage@1.0.2': {} - '@chakra-ui/react@3.36.0(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@chakra-ui/react@3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@ark-ui/react': 5.37.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@ark-ui/react': 5.37.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.8) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.8) '@emotion/utils': 1.4.2 - '@pandacss/is-valid-prop': 1.11.3 + '@pandacss/is-valid-prop': 1.11.5 csstype: 3.2.3 - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) - '@emnapi/core@1.10.0': + '@emnapi/core@1.11.1': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@1.2.2': dependencies: tslib: 2.8.1 optional: true @@ -3260,17 +3262,17 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7)': + '@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.8) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.7 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.17 transitivePeerDependencies: @@ -3288,36 +3290,41 @@ snapshots: '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.7)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.8)': dependencies: - react: 19.2.7 + react: 19.2.8 '@emotion/utils@1.4.2': {} '@emotion/weak-memoize@0.4.0': {} - '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.8.0(jiti@2.7.0))': + dependencies: + eslint: 10.8.0(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@10.8.0(jiti@2.7.0))': dependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.5.0(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.8.0(jiti@2.7.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) '@eslint/config-array@0.23.5': dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3 - minimatch: 10.2.5 + minimatch: 10.2.6 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.6.0': + '@eslint/config-helpers@0.7.0': dependencies: '@eslint/core': 1.2.1 @@ -3325,9 +3332,9 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.5.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.8.0(jiti@2.7.0))': optionalDependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} @@ -3336,33 +3343,23 @@ snapshots: '@eslint/core': 1.2.1 levn: 0.4.1 - '@floating-ui/core@1.7.5': + '@floating-ui/core@1.8.0': dependencies: - '@floating-ui/utils': 0.2.11 + '@floating-ui/utils': 0.2.12 - '@floating-ui/dom@1.7.6': + '@floating-ui/dom@1.8.0': dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/utils': 0.2.11 - - '@floating-ui/utils@0.2.11': {} + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 - '@hey-api/client-axios@0.9.1(@hey-api/openapi-ts@0.98.2(magicast@0.5.3)(typescript@6.0.3))(axios@1.18.0)': - dependencies: - '@hey-api/openapi-ts': 0.98.2(magicast@0.5.3)(typescript@6.0.3) - axios: 1.18.0 + '@floating-ui/utils@0.2.12': {} - '@hey-api/codegen-core@0.7.0(magicast@0.5.3)(typescript@6.0.3)': + '@hey-api/client-axios@0.9.1(@hey-api/openapi-ts@0.99.0(magicast@0.5.3)(typescript@6.0.3))(axios@1.18.1)': dependencies: - '@hey-api/types': 0.1.3(typescript@6.0.3) - ansi-colors: 4.1.3 - c12: 3.3.3(magicast@0.5.3) - color-support: 1.1.3 - typescript: 6.0.3 - transitivePeerDependencies: - - magicast + '@hey-api/openapi-ts': 0.99.0(magicast@0.5.3)(typescript@6.0.3) + axios: 1.18.1 - '@hey-api/codegen-core@0.9.0(magicast@0.5.3)': + '@hey-api/codegen-core@0.9.1(magicast@0.5.3)': dependencies: '@hey-api/types': 0.1.4 ansi-colors: 4.1.3 @@ -3371,37 +3368,17 @@ snapshots: transitivePeerDependencies: - magicast - '@hey-api/json-schema-ref-parser@1.2.4': + '@hey-api/json-schema-ref-parser@1.4.4': dependencies: '@jsdevtools/ono': 7.1.3 '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 - lodash: 4.18.1 + js-yaml: 4.3.0 - '@hey-api/json-schema-ref-parser@1.4.3': + '@hey-api/openapi-ts@0.99.0(magicast@0.5.3)(typescript@6.0.3)': dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 - - '@hey-api/openapi-ts@0.92.3(magicast@0.5.3)(typescript@6.0.3)': - dependencies: - '@hey-api/codegen-core': 0.7.0(magicast@0.5.3)(typescript@6.0.3) - '@hey-api/json-schema-ref-parser': 1.2.4 - '@hey-api/shared': 0.1.2(magicast@0.5.3)(typescript@6.0.3) - '@hey-api/types': 0.1.3(typescript@6.0.3) - ansi-colors: 4.1.3 - color-support: 1.1.3 - commander: 14.0.3 - typescript: 6.0.3 - transitivePeerDependencies: - - magicast - - '@hey-api/openapi-ts@0.98.2(magicast@0.5.3)(typescript@6.0.3)': - dependencies: - '@hey-api/codegen-core': 0.9.0(magicast@0.5.3) - '@hey-api/json-schema-ref-parser': 1.4.3 - '@hey-api/shared': 0.4.8(magicast@0.5.3) + '@hey-api/codegen-core': 0.9.1(magicast@0.5.3) + '@hey-api/json-schema-ref-parser': 1.4.4 + '@hey-api/shared': 0.5.0(magicast@0.5.3) '@hey-api/spec-types': 0.2.0 '@hey-api/types': 0.1.4 '@lukeed/ms': 2.0.2 @@ -3413,29 +3390,16 @@ snapshots: transitivePeerDependencies: - magicast - '@hey-api/shared@0.1.2(magicast@0.5.3)(typescript@6.0.3)': - dependencies: - '@hey-api/codegen-core': 0.7.0(magicast@0.5.3)(typescript@6.0.3) - '@hey-api/json-schema-ref-parser': 1.2.4 - '@hey-api/types': 0.1.3(typescript@6.0.3) - ansi-colors: 4.1.3 - cross-spawn: 7.0.6 - open: 11.0.0 - semver: 7.7.3 - typescript: 6.0.3 - transitivePeerDependencies: - - magicast - - '@hey-api/shared@0.4.8(magicast@0.5.3)': + '@hey-api/shared@0.5.0(magicast@0.5.3)': dependencies: - '@hey-api/codegen-core': 0.9.0(magicast@0.5.3) - '@hey-api/json-schema-ref-parser': 1.4.3 + '@hey-api/codegen-core': 0.9.1(magicast@0.5.3) + '@hey-api/json-schema-ref-parser': 1.4.4 '@hey-api/spec-types': 0.2.0 '@hey-api/types': 0.1.4 ansi-colors: 4.1.3 cross-spawn: 7.0.6 open: 11.0.0 - semver: 7.8.2 + semver: 7.8.4 transitivePeerDependencies: - magicast @@ -3443,10 +3407,6 @@ snapshots: dependencies: '@hey-api/types': 0.1.4 - '@hey-api/types@0.1.3(typescript@6.0.3)': - dependencies: - typescript: 6.0.3 - '@hey-api/types@0.1.4': {} '@humanfs/core@0.19.2': @@ -3478,11 +3438,6 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} @@ -3496,135 +3451,135 @@ snapshots: '@lukeed/ms@2.0.2': {} - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 optional: true - '@oxc-project/types@0.133.0': {} + '@oxc-project/types@0.139.0': {} - '@pandacss/is-valid-prop@1.11.3': {} + '@pandacss/is-valid-prop@1.11.5': {} '@pkgr/core@0.3.6': {} - '@rolldown/binding-android-arm64@1.0.3': + '@rolldown/binding-android-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@rolldown/binding-darwin-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@rolldown/binding-darwin-x64@1.1.5': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@rolldown/binding-freebsd-x64@1.1.5': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@rolldown/binding-linux-arm64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@rolldown/binding-linux-arm64-musl@1.1.5': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@rolldown/binding-linux-ppc64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@rolldown/binding-linux-s390x-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@rolldown/binding-linux-x64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@rolldown/binding-linux-x64-musl@1.1.5': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@rolldown/binding-openharmony-arm64@1.1.5': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': + '@rolldown/binding-wasm32-wasi@1.1.5': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@rolldown/binding-win32-arm64-msvc@1.1.5': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@rolldown/binding-win32-x64-msvc@1.1.5': optional: true '@rolldown/pluginutils@1.0.1': {} '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.7.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.8.0(jiti@2.7.0))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@2.7.0)) '@typescript-eslint/types': 8.57.0 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.4 - '@swc/core-darwin-arm64@1.15.40': + '@swc/core-darwin-arm64@1.15.46': optional: true - '@swc/core-darwin-x64@1.15.40': + '@swc/core-darwin-x64@1.15.46': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.40': + '@swc/core-linux-arm-gnueabihf@1.15.46': optional: true - '@swc/core-linux-arm64-gnu@1.15.40': + '@swc/core-linux-arm64-gnu@1.15.46': optional: true - '@swc/core-linux-arm64-musl@1.15.40': + '@swc/core-linux-arm64-musl@1.15.46': optional: true - '@swc/core-linux-ppc64-gnu@1.15.40': + '@swc/core-linux-ppc64-gnu@1.15.46': optional: true - '@swc/core-linux-s390x-gnu@1.15.40': + '@swc/core-linux-s390x-gnu@1.15.46': optional: true - '@swc/core-linux-x64-gnu@1.15.40': + '@swc/core-linux-x64-gnu@1.15.46': optional: true - '@swc/core-linux-x64-musl@1.15.40': + '@swc/core-linux-x64-musl@1.15.46': optional: true - '@swc/core-win32-arm64-msvc@1.15.40': + '@swc/core-win32-arm64-msvc@1.15.46': optional: true - '@swc/core-win32-ia32-msvc@1.15.40': + '@swc/core-win32-ia32-msvc@1.15.46': optional: true - '@swc/core-win32-x64-msvc@1.15.40': + '@swc/core-win32-x64-msvc@1.15.46': optional: true - '@swc/core@1.15.40(@swc/helpers@0.5.23)': + '@swc/core@1.15.46(@swc/helpers@0.5.23)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.26 + '@swc/types': 0.1.27 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.40 - '@swc/core-darwin-x64': 1.15.40 - '@swc/core-linux-arm-gnueabihf': 1.15.40 - '@swc/core-linux-arm64-gnu': 1.15.40 - '@swc/core-linux-arm64-musl': 1.15.40 - '@swc/core-linux-ppc64-gnu': 1.15.40 - '@swc/core-linux-s390x-gnu': 1.15.40 - '@swc/core-linux-x64-gnu': 1.15.40 - '@swc/core-linux-x64-musl': 1.15.40 - '@swc/core-win32-arm64-msvc': 1.15.40 - '@swc/core-win32-ia32-msvc': 1.15.40 - '@swc/core-win32-x64-msvc': 1.15.40 + '@swc/core-darwin-arm64': 1.15.46 + '@swc/core-darwin-x64': 1.15.46 + '@swc/core-linux-arm-gnueabihf': 1.15.46 + '@swc/core-linux-arm64-gnu': 1.15.46 + '@swc/core-linux-arm64-musl': 1.15.46 + '@swc/core-linux-ppc64-gnu': 1.15.46 + '@swc/core-linux-s390x-gnu': 1.15.46 + '@swc/core-linux-x64-gnu': 1.15.46 + '@swc/core-linux-x64-musl': 1.15.46 + '@swc/core-win32-arm64-msvc': 1.15.46 + '@swc/core-win32-ia32-msvc': 1.15.46 + '@swc/core-win32-x64-msvc': 1.15.46 '@swc/helpers': 0.5.23 '@swc/counter@0.1.3': {} @@ -3633,16 +3588,16 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/types@0.1.26': + '@swc/types@0.1.27': dependencies: '@swc/counter': 0.1.3 - '@tanstack/query-core@5.101.0': {} + '@tanstack/query-core@5.101.4': {} - '@tanstack/react-query@5.101.0(react@19.2.7)': + '@tanstack/react-query@5.101.4(react@19.2.8)': dependencies: - '@tanstack/query-core': 5.101.0 - react: 19.2.7 + '@tanstack/query-core': 5.101.4 + react: 19.2.8 '@testing-library/dom@10.4.0': dependencies: @@ -3664,17 +3619,17 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.28.6 '@testing-library/dom': 10.4.0 - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.17 '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.4)': + '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.9.6)': dependencies: '@babel/generator': 7.28.6 '@babel/parser': 7.28.6 @@ -3684,17 +3639,17 @@ snapshots: lodash-es: 4.18.1 minimatch: 9.0.9 parse-imports-exports: 0.2.4 - prettier: 3.8.4 + prettier: 3.9.6 transitivePeerDependencies: - supports-color '@ts-morph/common@0.29.0': dependencies: - minimatch: 10.2.5 + minimatch: 10.2.6 path-browserify: 1.0.1 tinyglobby: 0.2.17 - '@tybys/wasm-util@0.10.2': + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 optional: true @@ -3712,14 +3667,18 @@ snapshots: '@types/estree@1.0.9': {} + '@types/gensync@1.0.5': {} + '@types/hoist-non-react-statics@3.3.7(@types/react@19.2.17)': dependencies: '@types/react': 19.2.17 hoist-non-react-statics: 3.3.2 + '@types/jsesc@2.5.1': {} + '@types/json-schema@7.0.15': {} - '@types/node@26.0.0': + '@types/node@26.1.2': dependencies: undici-types: 8.3.0 @@ -3737,61 +3696,61 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 26.0.0 + '@types/node': 26.1.2 - '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.1 - eslint: 10.5.0(jiti@2.7.0) - ignore: 7.0.5 + '@typescript-eslint/parser': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/type-utils': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.65.0 + eslint: 10.8.0(jiti@2.7.0) + ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.61.1(typescript@6.0.3)': + '@typescript-eslint/project-service@8.65.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.61.1': + '@typescript-eslint/scope-manager@8.65.0': dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 - '@typescript-eslint/tsconfig-utils@8.61.1(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.65.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -3799,16 +3758,16 @@ snapshots: '@typescript-eslint/types@8.57.0': {} - '@typescript-eslint/types@8.61.1': {} + '@typescript-eslint/types@8.65.0': {} - '@typescript-eslint/typescript-estree@8.61.1(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.65.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.61.1(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/project-service': 8.65.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3 - minimatch: 10.2.5 + minimatch: 10.2.6 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3816,82 +3775,82 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - eslint: 10.5.0(jiti@2.7.0) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + eslint: 10.8.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.61.1': + '@typescript-eslint/visitor-keys@8.65.0': dependencies: - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/types': 8.65.0 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-react-swc@4.3.1(@swc/helpers@0.5.23)(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3))': + '@vitejs/plugin-react-swc@4.3.2(@swc/helpers@0.5.23)(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.1 - '@swc/core': 1.15.40(@swc/helpers@0.5.23) - vite: 8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3) + '@swc/core': 1.15.46(@swc/helpers@0.5.23) + vite: 8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3) transitivePeerDependencies: - '@swc/helpers' - '@vitest/coverage-v8@4.1.9(vitest@4.1.9)': + '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.9 + '@vitest/utils': 4.1.10 ast-v8-to-istanbul: 1.0.4 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.3 obug: 2.1.3 - std-env: 4.1.0 + std-env: 4.2.0 tinyrainbow: 3.1.0 - vitest: 4.1.9(@types/node@26.0.0)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.6)(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)) + vitest: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)) - '@vitest/expect@4.1.9': + '@vitest/expect@4.1.10': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3))': dependencies: - '@vitest/spy': 4.1.9 + '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3) + vite: 8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3) - '@vitest/pretty-format@4.1.9': + '@vitest/pretty-format@4.1.10': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.9': + '@vitest/runner@4.1.10': dependencies: - '@vitest/utils': 4.1.9 + '@vitest/utils': 4.1.10 pathe: 2.0.3 - '@vitest/snapshot@4.1.9': + '@vitest/snapshot@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.9 - '@vitest/utils': 4.1.9 + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.9': {} + '@vitest/spy@4.1.10': {} - '@vitest/utils@4.1.9': + '@vitest/utils@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.9 + '@vitest/pretty-format': 4.1.10 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -4243,7 +4202,7 @@ snapshots: '@zag-js/popper@1.41.2': dependencies: - '@floating-ui/dom': 1.7.6 + '@floating-ui/dom': 1.8.0 '@zag-js/dom-query': 1.41.2 '@zag-js/utils': 1.41.2 @@ -4288,14 +4247,14 @@ snapshots: '@zag-js/types': 1.41.2 '@zag-js/utils': 1.41.2 - '@zag-js/react@1.41.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@zag-js/react@1.41.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@zag-js/core': 1.41.2 '@zag-js/store': 1.41.2 '@zag-js/types': 1.41.2 '@zag-js/utils': 1.41.2 - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) '@zag-js/rect-utils@1.41.2': {} @@ -4466,13 +4425,13 @@ snapshots: dependencies: acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.17.0): + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - acorn: 8.17.0 + acorn: 8.18.0 acorn@8.16.0: {} - acorn@8.17.0: {} + acorn@8.18.0: {} agent-base@6.0.2: dependencies: @@ -4580,7 +4539,7 @@ snapshots: axe-core@4.10.3: {} - axios@1.18.0: + axios@1.18.1: dependencies: follow-redirects: 1.16.0 form-data: 4.0.6 @@ -4604,16 +4563,16 @@ snapshots: baseline-browser-mapping@2.10.38: {} - brace-expansion@1.1.13: + brace-expansion@1.1.16: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.3: + brace-expansion@2.1.2: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.6: + brace-expansion@5.0.9: dependencies: balanced-match: 4.0.4 @@ -4627,7 +4586,7 @@ snapshots: buffer-image-size@0.6.4: dependencies: - '@types/node': 26.0.0 + '@types/node': 26.1.2 builtin-modules@5.2.0: {} @@ -4635,30 +4594,13 @@ snapshots: dependencies: run-applescript: 7.1.0 - c12@3.3.3(magicast@0.5.3): - dependencies: - chokidar: 5.0.0 - confbox: 0.2.4 - defu: 6.1.7 - dotenv: 17.4.2 - exsolve: 1.0.8 - giget: 2.0.0 - jiti: 2.6.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.0 - rc9: 2.1.2 - optionalDependencies: - magicast: 0.5.3 - c12@3.3.4(magicast@0.5.3): dependencies: chokidar: 5.0.0 confbox: 0.2.4 defu: 6.1.7 dotenv: 17.4.2 - exsolve: 1.0.8 + exsolve: 1.1.0 giget: 3.3.0 jiti: 2.7.0 ohash: 2.0.11 @@ -4705,12 +4647,6 @@ snapshots: ci-info@4.4.0: {} - citty@0.1.6: - dependencies: - consola: 3.4.2 - - citty@0.2.2: {} - code-block-writer@13.0.3: {} color-convert@2.0.1: @@ -4725,16 +4661,12 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@14.0.3: {} - commander@15.0.0: {} concat-map@0.0.1: {} confbox@0.2.4: {} - consola@3.4.2: {} - convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} @@ -4842,6 +4774,8 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.1: {} + entities@7.0.1: {} error-ex@1.3.4: @@ -4925,7 +4859,7 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 - es-module-lexer@2.1.0: {} + es-module-lexer@2.3.0: {} es-object-atoms@1.1.1: dependencies: @@ -4952,11 +4886,11 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)): dependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) - eslint-plugin-jsx-a11y@6.10.2(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-jsx-a11y@6.10.2(eslint@10.8.0(jiti@2.7.0)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -4966,7 +4900,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -4975,40 +4909,38 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-perfectionist@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + eslint-plugin-perfectionist@5.10.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.5.0(jiti@2.7.0) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.8.0(jiti@2.7.0) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)))(eslint@10.5.0(jiti@2.7.0))(prettier@3.8.4): + eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)))(eslint@10.8.0(jiti@2.7.0))(prettier@3.9.6): dependencies: - eslint: 10.5.0(jiti@2.7.0) - prettier: 3.8.4 + eslint: 10.8.0(jiti@2.7.0) + prettier: 3.9.6 prettier-linter-helpers: 1.0.1 synckit: 0.11.13 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@10.5.0(jiti@2.7.0)) + eslint-config-prettier: 10.1.8(eslint@10.8.0(jiti@2.7.0)) - eslint-plugin-react-hooks@7.1.1(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-react-hooks@7.1.1(eslint@10.8.0(jiti@2.7.0)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 8.0.1 '@babel/parser': 7.29.2 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) - transitivePeerDependencies: - - supports-color - eslint-plugin-react-refresh@0.5.3(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-react-refresh@0.5.3(eslint@10.8.0(jiti@2.7.0)): dependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) - eslint-plugin-react@7.37.5(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-react@7.37.5(eslint@10.8.0(jiti@2.7.0)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -5016,7 +4948,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -5030,16 +4962,16 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-unicorn@67.0.0(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-unicorn@67.0.0(eslint@10.8.0(jiti@2.7.0)): dependencies: '@babel/helper-validator-identifier': 7.29.7 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@2.7.0)) browserslist: 4.28.2 change-case: 5.4.4 ci-info: 4.4.0 core-js-compat: 3.49.0 detect-indent: 7.0.2 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.8.0(jiti@2.7.0) find-up-simple: 1.0.1 globals: 17.6.0 indent-string: 5.0.0 @@ -5063,12 +4995,12 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.5.0(jiti@2.7.0): + eslint@10.8.0(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 - '@eslint/config-helpers': 0.6.0 + '@eslint/config-helpers': 0.7.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 @@ -5092,7 +5024,7 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.5 + minimatch: 10.2.6 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -5108,8 +5040,8 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -5128,9 +5060,9 @@ snapshots: esutils@2.0.3: {} - expect-type@1.3.0: {} + expect-type@1.4.0: {} - exsolve@1.0.8: {} + exsolve@1.1.0: {} fast-deep-equal@3.1.3: {} @@ -5140,9 +5072,9 @@ snapshots: fast-levenshtein@2.0.6: {} - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 file-entry-cache@8.0.0: dependencies: @@ -5159,10 +5091,10 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.4.2 + flatted: 3.4.4 keyv: 4.5.4 - flatted@3.4.2: {} + flatted@3.4.4: {} follow-redirects@1.16.0: {} @@ -5224,15 +5156,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - giget@2.0.0: - dependencies: - citty: 0.1.6 - consola: 3.4.2 - defu: 6.1.7 - node-fetch-native: 1.6.7 - nypm: 0.6.5 - pathe: 2.0.3 - giget@3.3.0: {} glob-parent@6.0.2: @@ -5248,15 +5171,15 @@ snapshots: gopd@1.2.0: {} - happy-dom@20.10.6: + happy-dom@20.11.1: dependencies: - '@types/node': 26.0.0 + '@types/node': 26.1.2 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 buffer-image-size: 0.6.4 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.21.0 + ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -5308,13 +5231,15 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -5480,15 +5405,13 @@ snapshots: javascript-natural-sort@0.7.1: {} - jiti@2.6.1: {} - jiti@2.7.0: {} js-tokens@10.0.0: {} js-tokens@4.0.0: {} - js-yaml@4.1.1: + js-yaml@4.3.0: dependencies: argparse: 2.0.1 @@ -5526,54 +5449,54 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.32.0: + lightningcss-android-arm64@1.33.0: optional: true - lightningcss-darwin-arm64@1.32.0: + lightningcss-darwin-arm64@1.33.0: optional: true - lightningcss-darwin-x64@1.32.0: + lightningcss-darwin-x64@1.33.0: optional: true - lightningcss-freebsd-x64@1.32.0: + lightningcss-freebsd-x64@1.33.0: optional: true - lightningcss-linux-arm-gnueabihf@1.32.0: + lightningcss-linux-arm-gnueabihf@1.33.0: optional: true - lightningcss-linux-arm64-gnu@1.32.0: + lightningcss-linux-arm64-gnu@1.33.0: optional: true - lightningcss-linux-arm64-musl@1.32.0: + lightningcss-linux-arm64-musl@1.33.0: optional: true - lightningcss-linux-x64-gnu@1.32.0: + lightningcss-linux-x64-gnu@1.33.0: optional: true - lightningcss-linux-x64-musl@1.32.0: + lightningcss-linux-x64-musl@1.33.0: optional: true - lightningcss-win32-arm64-msvc@1.32.0: + lightningcss-win32-arm64-msvc@1.33.0: optional: true - lightningcss-win32-x64-msvc@1.32.0: + lightningcss-win32-x64-msvc@1.33.0: optional: true - lightningcss@1.32.0: + lightningcss@1.33.0: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 lines-and-columns@1.2.4: {} @@ -5583,15 +5506,11 @@ snapshots: lodash-es@4.18.1: {} - lodash@4.18.1: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 + lru-cache@11.5.2: {} lz-string@1.5.0: {} @@ -5619,41 +5538,33 @@ snapshots: min-indent@1.0.1: {} - minimatch@10.2.5: + minimatch@10.2.6: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.9 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.13 + brace-expansion: 1.1.16 minimatch@9.0.9: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.1.2 ms@2.1.3: {} - nanoid@3.3.12: {} + nanoid@3.3.16: {} natural-compare@1.4.0: {} natural-orderby@5.0.0: {} - next-themes@0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + next-themes@0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) - - node-fetch-native@1.6.7: {} + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) node-releases@2.0.48: {} - nypm@0.6.5: - dependencies: - citty: 0.2.2 - pathe: 2.0.3 - tinyexec: 1.2.4 - object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -5763,25 +5674,21 @@ snapshots: picomatch@4.0.4: {} - pkg-types@2.3.0: - dependencies: - confbox: 0.2.4 - exsolve: 1.0.8 - pathe: 2.0.3 + picomatch@4.0.5: {} pkg-types@2.3.1: dependencies: confbox: 0.2.4 - exsolve: 1.0.8 + exsolve: 1.1.0 pathe: 2.0.3 pluralize@8.0.0: {} possible-typed-array-names@1.1.0: {} - postcss@8.5.15: + postcss@8.5.22: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.16 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -5793,7 +5700,7 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@3.8.4: {} + prettier@3.9.6: {} pretty-format@27.5.1: dependencies: @@ -5817,53 +5724,48 @@ snapshots: punycode@2.3.1: {} - rc9@2.1.2: - dependencies: - defu: 6.1.7 - destr: 2.0.5 - rc9@3.0.1: dependencies: defu: 6.1.7 destr: 2.0.5 - react-cookie@8.1.2(@types/react@19.2.17)(react@19.2.7): + react-cookie@8.1.2(@types/react@19.2.17)(react@19.2.8): dependencies: '@types/hoist-non-react-statics': 3.3.7(@types/react@19.2.17) hoist-non-react-statics: 3.3.2 - react: 19.2.7 + react: 19.2.8 universal-cookie: 8.1.2 transitivePeerDependencies: - '@types/react' - react-dom@19.2.7(react@19.2.7): + react-dom@19.2.8(react@19.2.8): dependencies: - react: 19.2.7 + react: 19.2.8 scheduler: 0.27.0 - react-hook-form@7.79.0(react@19.2.7): + react-hook-form@7.83.0(react@19.2.8): dependencies: - react: 19.2.7 + react: 19.2.8 react-is@16.13.1: {} react-is@17.0.2: {} - react-router-dom@7.18.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + react-router-dom@7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - react: 19.2.7 - react-dom: 19.2.7(react@19.2.7) - react-router: 7.18.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-router: 7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react-router@7.18.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + react-router@7.18.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: cookie: 1.1.1 - react: 19.2.7 + react: 19.2.8 set-cookie-parser: 2.7.2 optionalDependencies: - react-dom: 19.2.7(react@19.2.7) + react-dom: 19.2.8(react@19.2.8) - react@19.2.7: {} + react@19.2.8: {} readdirp@5.0.0: {} @@ -5913,26 +5815,26 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rolldown@1.0.3: + rolldown@1.1.5: dependencies: - '@oxc-project/types': 0.133.0 + '@oxc-project/types': 0.139.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 run-applescript@7.1.0: {} @@ -5959,9 +5861,7 @@ snapshots: semver@6.3.1: {} - semver@7.7.3: {} - - semver@7.8.2: {} + semver@7.8.4: {} semver@7.8.5: {} @@ -6031,7 +5931,7 @@ snapshots: stackback@0.0.2: {} - std-env@4.1.0: {} + std-env@4.2.0: {} string.prototype.includes@2.0.1: dependencies: @@ -6107,8 +6007,8 @@ snapshots: tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tinyrainbow@3.1.0: {} @@ -6160,13 +6060,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + typescript-eslint@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.5.0(jiti@2.7.0) + '@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.8.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -6198,49 +6098,49 @@ snapshots: dependencies: punycode: 2.3.1 - vite-plugin-css-injected-by-js@5.0.1(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)): + vite-plugin-css-injected-by-js@5.0.2(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)): dependencies: - vite: 8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3) + vite: 8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3) - vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3): + vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3): dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.0.3 + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.22 + rolldown: 1.1.5 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.0.0 + '@types/node': 26.1.2 fsevents: 2.3.3 jiti: 2.7.0 yaml: 2.8.3 - vitest@4.1.9(@types/node@26.0.0)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.6)(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)): - dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 + vitest@4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.0 + expect-type: 1.4.0 magic-string: 0.30.21 obug: 2.1.3 pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 + picomatch: 4.0.5 + std-env: 4.2.0 tinybench: 2.9.0 tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@26.0.0)(jiti@2.7.0)(yaml@2.8.3) + vite: 8.1.5(@types/node@26.1.2)(jiti@2.7.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 26.0.0 - '@vitest/coverage-v8': 4.1.9(vitest@4.1.9) - happy-dom: 20.10.6 + '@types/node': 26.1.2 + '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) + happy-dom: 20.11.1 transitivePeerDependencies: - msw @@ -6298,15 +6198,13 @@ snapshots: word-wrap@1.2.5: {} - ws@8.21.0: {} + ws@8.21.1: {} wsl-utils@0.3.1: dependencies: is-wsl: 3.1.1 powershell-utils: 0.1.0 - yallist@3.1.1: {} - yaml@1.10.3: {} yaml@2.8.3: diff --git a/airflow-core/src/airflow/api_fastapi/common/cursors.py b/airflow-core/src/airflow/api_fastapi/common/cursors.py index 2eb5569f890fa..c775e72ab7059 100644 --- a/airflow-core/src/airflow/api_fastapi/common/cursors.py +++ b/airflow-core/src/airflow/api_fastapi/common/cursors.py @@ -28,7 +28,7 @@ import msgspec from fastapi import HTTPException, status -from sqlalchemy import and_, or_ +from sqlalchemy import and_, false, or_, true from sqlalchemy.sql import Select from sqlalchemy.sql.elements import ColumnElement from sqlalchemy.sql.sqltypes import Uuid @@ -43,55 +43,57 @@ def _b64url_decode_padded(token: str) -> bytes: return base64.urlsafe_b64decode(token.encode("ascii")) -def _nonstrict_bound(col: ColumnElement, value: Any, is_desc: bool) -> ColumnElement[bool]: +def _dialect_nulls_last(is_desc: bool, dialect: str) -> bool: """ - Inclusive range edge on the leading column at each nesting level (``>=`` / ``<=``). + Where a plain ``ORDER BY col`` puts NULLs on this backend. - When *value* is ``None`` the column is nullable and the cursor sits at a - NULL boundary. ``col IS NULL`` is used instead of ``col >= NULL`` (which - SQLAlchemy rejects and SQL evaluates as UNKNOWN). + PostgreSQL sorts NULLs last for ASC, first for DESC; MySQL and SQLite treat + NULL as the lowest value, so NULLs come first for ASC and last for DESC. """ - if value is None: - return col.is_(None) - return col <= value if is_desc else col >= value + return (not is_desc) if dialect == "postgresql" else is_desc -def _strict_bound(col: ColumnElement, value: Any, is_desc: bool) -> ColumnElement[bool]: +def _bounds( + col: ColumnElement, value: Any, is_desc: bool, dialect: str +) -> tuple[ColumnElement[bool], ColumnElement[bool]]: """ - Strict inequality for ``or_`` branches (``<`` / ``>``). - - When *value* is ``None`` the cursor is at a NULL boundary. The only rows - that can be "strictly after" a NULL are non-NULL rows (regardless of - whether the database sorts NULLs first or last), so ``col IS NOT NULL`` is - used. When the surrounding ``_nonstrict_bound`` already constrains - ``col IS NULL``, this branch evaluates to FALSE and the inner keyset - predicate takes over — which is the correct behaviour. + ``(non_strict, strict)`` keyset bounds matching the backend's native NULL placement. + + A NULL *value* means the cursor sits in the NULL block; otherwise a trailing + NULL block (when NULLs sort last) is also admitted after a non-NULL cursor. + The ``col IS NULL`` terms are vacuous for non-nullable columns. """ + nulls_last = _dialect_nulls_last(is_desc, dialect) if value is None: - return col.is_not(None) - return col < value if is_desc else col > value + if nulls_last: + return col.is_(None), false() + return true(), col.is_not(None) + ge = col <= value if is_desc else col >= value + gt = col < value if is_desc else col > value + if nulls_last: + return or_(ge, col.is_(None)), or_(gt, col.is_(None)) + return ge, gt def _nested_keyset_predicate( - resolved: list[tuple[str, ColumnElement, bool]], values: list[Any] + resolved: list[tuple[str, ColumnElement, bool]], values: list[Any], dialect: str ) -> ColumnElement[bool]: """ Keyset predicate for rows strictly after the cursor in ``ORDER BY`` order. Uses nested ``and_(non-strict, or_(strict, ...))`` so leading sort keys use inclusive range bounds and inner branches use strict inequalities—friendly - for composite index range scans. Logically equivalent to an OR-of-prefix- - equalities formulation. + for composite index range scans. NULL placement follows each backend's + native ordering for a plain ``ORDER BY`` (see :func:`_bounds`), so the + ``ORDER BY`` stays a bare column and can still use an index. """ n = len(resolved) _, col, is_desc = resolved[n - 1] - inner: ColumnElement[bool] = _strict_bound(col, values[n - 1], is_desc) + _, inner = _bounds(col, values[n - 1], is_desc, dialect) for i in range(n - 2, -1, -1): _, col_i, is_desc_i = resolved[i] - inner = and_( - _nonstrict_bound(col_i, values[i], is_desc_i), - or_(_strict_bound(col_i, values[i], is_desc_i), inner), - ) + non_strict, strict = _bounds(col_i, values[i], is_desc_i, dialect) + inner = and_(non_strict, or_(strict, inner)) return inner @@ -163,7 +165,7 @@ def decode_cursor(token: str) -> list[Any]: def apply_cursor_filter( - statement: Select, token: str, sort_param: SortParam, *, is_backward: bool = False + statement: Select, token: str, sort_param: SortParam, dialect: str, *, is_backward: bool = False ) -> Select: """ Apply a keyset pagination WHERE clause from a cursor token. @@ -173,6 +175,10 @@ def apply_cursor_filter( flipped so the predicate selects rows strictly *before* the cursor in the original sort order. The caller is responsible for reversing the ORDER BY and the final result list when using a backward cursor. + + *dialect* is the backend dialect name (``session.get_bind().dialect.name``); + the predicate matches that backend's native NULL placement, so the keyset + ``ORDER BY`` stays a bare column and keeps using indexes. """ raw_values = decode_cursor(token) @@ -185,4 +191,4 @@ def apply_cursor_filter( if is_backward: resolved = [(name, col, not is_desc) for name, col, is_desc in resolved] - return statement.where(_nested_keyset_predicate(resolved, parsed_values)) + return statement.where(_nested_keyset_predicate(resolved, parsed_values, dialect)) diff --git a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py index f9ae3d6c3b6c6..1508ea8528ebb 100644 --- a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py @@ -127,7 +127,7 @@ def attach_dag_versions_to_runs(dag_runs: Sequence[DagRun], *, session: Session) .where(DagVersion.id.in_(all_version_ids)) .options(joinedload(DagVersion.bundle)) ) - versions_by_id = {dv.id: dv for dv in session.scalars(dv_query).unique()} + versions_by_id = {dv.id: dv for dv in session.scalars(dv_query)} versions_per_run: dict[tuple[str, str], dict[UUID, DagVersion]] = defaultdict(dict) for row in rows: diff --git a/airflow-core/src/airflow/api_fastapi/common/exceptions.py b/airflow-core/src/airflow/api_fastapi/common/exceptions.py index 86af9e062cd96..f1c28a2cd423e 100644 --- a/airflow-core/src/airflow/api_fastapi/common/exceptions.py +++ b/airflow-core/src/airflow/api_fastapi/common/exceptions.py @@ -23,15 +23,16 @@ from enum import Enum from typing import Generic, TypeVar -from fastapi import HTTPException, Request, status -from sqlalchemy.exc import DatabaseError, DataError, IntegrityError +from fastapi import FastAPI, HTTPException, Request, status +from sqlalchemy.exc import DataError, IntegrityError, SQLAlchemyError +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.configuration import conf from airflow.exceptions import DeserializationError from airflow.utils.strings import get_random_string T = TypeVar("T", bound=Exception) -DBError = TypeVar("DBError", bound=DatabaseError) +DBError = TypeVar("DBError", bound=SQLAlchemyError) log = logging.getLogger(__name__) @@ -70,35 +71,41 @@ class _DatabaseErrorHandler(BaseErrorHandler[DBError]): def _should_handle(self, exc: DBError) -> bool: return True - def exception_handler(self, request: Request, exc: DBError): - if not self._should_handle(exc): - return + def _raise_database_error_response(self, exc: DBError) -> None: + statement = getattr(exc, "statement", "hidden") + orig_error = getattr(exc, "orig", "hidden") exception_id = get_random_string() stacktrace = "".join(traceback.format_tb(exc.__traceback__)) - log_message = f"Error with id {exception_id}, statement: {exc.statement}\n{stacktrace}" + log_message = f"Error with id {exception_id}, statement: {statement}\n{stacktrace}" log.error(log_message) + if conf.get("api", "expose_stacktrace") == "True": message = log_message - statement = str(exc.statement) - orig_error = str(exc.orig) + statement_out = str(statement) + orig_error_out = str(orig_error) else: message = ( "Serious error when handling your request. Check logs for more details - " f"you will find it in api server when you look for ID {exception_id}" ) - statement = "hidden" - orig_error = "hidden" + statement_out = "hidden" + orig_error_out = "hidden" raise HTTPException( status_code=self.status_code, detail={ "reason": self.reason, - "statement": statement, - "orig_error": orig_error, + "statement": statement_out, + "orig_error": orig_error_out, "message": message, }, ) + def exception_handler(self, request: Request, exc: DBError): + if not self._should_handle(exc): + return + self._raise_database_error_response(exc) + class _UniqueConstraintErrorHandler(_DatabaseErrorHandler[IntegrityError]): """Translate a unique-constraint ``IntegrityError`` into a 409, matched per database dialect.""" @@ -137,7 +144,7 @@ class DataErrorHandler(_DatabaseErrorHandler[DataError]): range, or the wrong type for its column), so it is a client error, not a 500. """ - status_code = status.HTTP_422_UNPROCESSABLE_ENTITY + status_code = HTTP_422_UNPROCESSABLE_CONTENT reason = "Value rejected by database" def __init__(self): @@ -158,8 +165,24 @@ def exception_handler(self, request: Request, exc: DeserializationError): ) +class SQLAlchemyErrorHandler(_DatabaseErrorHandler[SQLAlchemyError]): + """Generic handler for SQLAlchemyError -> 500 responses.""" + + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + reason = "Database error" + + def __init__(self): + super().__init__(SQLAlchemyError) + + ERROR_HANDLERS: list[BaseErrorHandler] = [ _UniqueConstraintErrorHandler(), DataErrorHandler(), + SQLAlchemyErrorHandler(), DagErrorHandler(), ] + + +def init_error_handlers(app: FastAPI) -> None: + for handler in ERROR_HANDLERS: + app.add_exception_handler(handler.exception_cls, handler.exception_handler) diff --git a/airflow-core/src/airflow/api_fastapi/common/parameters.py b/airflow-core/src/airflow/api_fastapi/common/parameters.py index 935b547c1a7cf..9f53cfaedbb21 100644 --- a/airflow-core/src/airflow/api_fastapi/common/parameters.py +++ b/airflow-core/src/airflow/api_fastapi/common/parameters.py @@ -286,6 +286,11 @@ def transform_aliases(self, value: str | None) -> str | None: return value +def _build_pipe_clause(pipe_as_or: bool) -> str: + """Build the per-parameter pipe note. OR is the documented default (see the API description), so only the literal exception is spelled out.""" + return "" if pipe_as_or else "Here `|` is matched literally, not as OR. " + + _LIKE_ESCAPE_CHAR = "\\" @@ -418,13 +423,10 @@ def depends( task_display_name_prefix_pattern: str | None = Query( default=None, description=( - "Prefix match on task display name: optional ``_task_display_property_value`` else " - "``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly alternative to " - "``task_display_name_pattern``. On large databases, combine with ``dag_id_prefix_pattern`` " - "(or a specific Dag in the path) so ``(dag_id, task_id, ...)`` indexes apply. " - "Use ``|`` for OR. Use ``~`` to match all. Trailing non-alphanumeric characters in the " - "term are stripped before matching so the range scan stays index-compatible under " - "locale-aware collations." + "Case-sensitive prefix match on task display name (`_task_display_property_value` else " + "`task_id`). Index-friendly alternative to `task_display_name_pattern`; on large databases " + "combine with `dag_id_prefix_pattern` (or a specific Dag in the path) so composite indexes " + 'apply. See "Filtering with pattern parameters".' ), ), ) -> Self: @@ -489,20 +491,11 @@ def search_param_factory( skip_none: bool = True, pipe_as_or: bool = True, ) -> Callable[[str | None], _SearchParam]: - pipe_clause = ( - "Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). " - if pipe_as_or - else "The pipe `|` is matched literally, not as an OR separator. " - ) + prefix_pattern_name = pattern_name.replace("_pattern", "_prefix_pattern") DESCRIPTION = ( - "SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). " - f"{pipe_clause}" - "Regular expressions are **not** supported. " - "\n\n" - "**Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and " - "most of the time prevents the database from using B-tree indexes, which can be very " - "slow on large tables. Prefer the equivalent " - f"``{pattern_name.replace('_pattern', '_prefix_pattern')}`` parameter when possible." + "Case-insensitive substring match (SQL `ILIKE`). " + f"{_build_pipe_clause(pipe_as_or)}" + f'Slower than `{prefix_pattern_name}` on large tables — see "Filtering with pattern parameters".' ) def depends_search( @@ -527,20 +520,10 @@ def prefix_search_param_factory( Prefer this over :func:`search_param_factory` for performance: prefix matching uses a B-tree index range scan, while substring matching requires a full table scan. """ - pipe_clause = ( - "Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). " - if pipe_as_or - else "The pipe `|` is part of the prefix, not an OR separator. " - ) DESCRIPTION = ( - "Prefix match — returns items whose value starts with the given string " - f"(case-sensitive, index-friendly). {pipe_clause}" - "Use `~` to match all. Wildcard characters (`%`, `_`) " - "are treated as literal characters. Trailing non-alphanumeric characters " - "in the prefix are stripped before matching so the range scan stays " - "index-compatible under locale-aware collations — e.g. `test_` effectively " - "matches items starting with `test`, and `s3://` matches items starting with " - "`s3`." + "Case-sensitive, index-friendly prefix match. " + f"{_build_pipe_clause(pipe_as_or)}" + 'See "Filtering with pattern parameters".' ) def depends_prefix_search( @@ -1236,7 +1219,12 @@ def to_orm(self, select: Select) -> Select: def depends( cls, consuming_asset_pattern: str | None = Query( - None, description="Filter by consuming asset name or URI using pattern matching" + None, + description=( + "Case-insensitive substring match against the consuming asset name or URI. " + "Unlike the wildcard `*_pattern` parameters, `%` and `_` are matched literally, " + "`|` is not an OR separator, and `~` does not match everything." + ), ), ) -> _ConsumingAssetFilter: return cls().set_value(consuming_asset_pattern) @@ -1283,11 +1271,39 @@ def depends(cls, has_pending_actions: bool | None = Query(None)) -> _PendingActi QueryPendingActionsFilter = Annotated[_PendingActionsFilter, Depends(_PendingActionsFilter.depends)] + +class _AnyDagRunStateFilter(BaseParam[DagRunState | None]): + """Filter Dags that have any DagRun in the given state, not only the latest one.""" + + def to_orm(self, select: Select) -> Select: + if self.value is None and self.skip_none: + return select + + # EXISTS resolves each Dag via the (dag_id, state) index instead of scanning every run in the state. + has_run_in_state = ( + sql_select(DagRun.dag_id) + .where(DagRun.dag_id == DagModel.dag_id, DagRun.state == self.value) + .exists() + ) + return select.where(has_run_in_state) + + @classmethod + def depends( + cls, + dag_run_state: DagRunState | None = Query( + None, + description="Filter Dags that have any DagRun in the given state.", + ), + ) -> _AnyDagRunStateFilter: + return cls().set_value(dag_run_state) + + # DagRun QueryLastDagRunStateFilter = Annotated[ FilterParam[DagRunState | None], Depends(filter_param_factory(DagRun.state, DagRunState | None, filter_name="last_dag_run_state")), ] +QueryAnyDagRunStateFilter = Annotated[_AnyDagRunStateFilter, Depends(_AnyDagRunStateFilter.depends)] def _transform_dag_run_states(states: Iterable[str] | None) -> list[DagRunState | None] | None: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/app.py b/airflow-core/src/airflow/api_fastapi/core_api/app.py index 27213a4c0a2e8..961f13fbc7146 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/app.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/app.py @@ -170,13 +170,6 @@ def init_config(app: FastAPI) -> None: app.state.secret_key = get_signing_key("api", "secret_key") -def init_error_handlers(app: FastAPI) -> None: - from airflow.api_fastapi.common.exceptions import ERROR_HANDLERS - - for handler in ERROR_HANDLERS: - app.add_exception_handler(handler.exception_cls, handler.exception_handler) - - def init_middlewares(app: FastAPI) -> None: from airflow.api_fastapi.app import get_auth_manager from airflow.api_fastapi.auth.middlewares.refresh_token import JWTRefreshMiddleware diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py index 753ea94f1d9a2..3be0707bee10a 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/assets.py @@ -19,14 +19,24 @@ from collections.abc import Iterable from datetime import datetime -from typing import TYPE_CHECKING - -from pydantic import AliasPath, AwareDatetime, ConfigDict, Field, JsonValue, NonNegativeInt, field_validator +from typing import TYPE_CHECKING, Annotated + +from pydantic import ( + AliasPath, + AwareDatetime, + ConfigDict, + Field, + JsonValue, + NonNegativeInt, + StringConstraints, + field_validator, +) from airflow._shared.secrets_masker import redact from airflow._shared.timezones import timezone from airflow.api_fastapi.core_api.base import BaseModel, StrictBaseModel from airflow.api_fastapi.core_api.datamodels.dag_run import TriggerDAGRunPostBody +from airflow.models.base import ID_LEN from airflow.utils.types import DagRunType if TYPE_CHECKING: @@ -190,7 +200,9 @@ class CreateAssetEventsBody(StrictBaseModel): """Create asset events request.""" asset_id: int - partition_key: str | None = None + # pattern (not strip_whitespace) so the value isn't mutated — must stay byte-identical to what + # `_validate_outlet_event_partition_keys` in the Execution API accepts for the same raw input. + partition_key: Annotated[str, StringConstraints(pattern=r"\S", max_length=ID_LEN)] | None = None extra: dict = Field(default_factory=dict) access_control: AssetEventAccessControl | None = None diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/common.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/common.py index e429673001735..702f6997cdf5e 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/common.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/common.py @@ -93,6 +93,7 @@ class GridRunsResponse(BaseModel): run_type: DagRunType dag_versions: list[DagVersionResponse] = [] has_missed_deadline: bool + has_note: bool @computed_field def duration(self) -> float: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/dashboard.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/dashboard.py index 46fc051daf304..1235b8d76aab4 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/dashboard.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/dashboard.py @@ -52,7 +52,9 @@ class HistoricalMetricDataResponse(BaseModel): dag_run_states: DAGRunStates task_instance_states: TaskInstanceStateCount - state_count_limit: int + # True when the counts above are floors on the real values rather than exact figures. + dag_run_counts_are_lower_bounds: bool = False + task_instance_counts_are_lower_bounds: bool = False class DashboardDagStatsResponse(BaseModel): diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/deadline.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/deadline.py index 6f9402f23603d..9c09176fea414 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/deadline.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/deadline.py @@ -19,9 +19,10 @@ from collections.abc import Iterable from datetime import datetime +from typing import Any from uuid import UUID -from pydantic import AliasPath, Field +from pydantic import AliasPath, Field, field_validator from airflow.api_fastapi.core_api.base import BaseModel @@ -52,9 +53,35 @@ class DeadlineAlertResponse(BaseModel): id: UUID name: str | None = None reference_type: str = Field(validation_alias=AliasPath("reference", "reference_type")) - interval: float = Field(description="Interval in seconds between deadline evaluations.") + interval: float | None = Field( + default=None, + description=( + "Interval in seconds between the reference time and the deadline. " + "Null for a dynamic interval (e.g. a VariableInterval) whose value is " + "only resolved at scheduler evaluation time." + ), + ) created_at: datetime + @field_validator("interval", mode="before") + @classmethod + def coerce_interval_to_seconds(cls, value: Any) -> float | None: + """ + Coerce the stored ``interval`` into seconds. + + ``interval`` is the Airflow-serialized SDK interval: a dict + ``{"__classname__": ..., "__data__": }``, not a plain number. + Return the seconds for a fixed ``timedelta``, or ``None`` for a dynamic + interval (resolved later by the scheduler). Without this, Pydantic 500s on the dict. + """ + if value is None or isinstance(value, (int, float)): + return value + if isinstance(value, dict): + data = value.get("__data__") + if isinstance(data, (int, float)): + return float(data) + return None + class DeadlineAlertCollectionResponse(BaseModel): """DeadlineAlert Collection serializer for responses.""" diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py index 19278430d3f59..98adbb537c6e2 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py @@ -34,6 +34,7 @@ class LightGridTaskInstanceSummary(BaseModel): min_start_date: datetime | None max_end_date: datetime | None dag_version_number: int | None = None + has_note: bool = False class GridTISummaries(BaseModel): diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py index b42cc176f01c7..e6987502ad321 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/xcom.py @@ -16,6 +16,7 @@ # under the License. from __future__ import annotations +import json from collections.abc import Iterable from datetime import datetime from typing import Any @@ -88,6 +89,19 @@ def _check_forbidden_xcom_keys(value: Any) -> Any: from airflow._shared.serialization import FORBIDDEN_XCOM_KEYS def _walk(obj: Any, path: str = "value") -> None: + if isinstance(obj, str): + # A value submitted as a JSON string literal (e.g. ``json.dumps({...})``) + # is stored verbatim and re-parsed into a dict/list on a + # ``deserialize=true`` read, which would otherwise smuggle reserved keys + # past the dict/list checks below. Re-parse and inspect the decoded + # structure the same way the read path does. + try: + decoded = json.loads(obj) + except (ValueError, TypeError): + return + if isinstance(decoded, (dict, list)): + _walk(decoded, path) + return if isinstance(obj, dict): found = FORBIDDEN_XCOM_KEYS & obj.keys() if found: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml index d786e259b4e77..c1112a747fb05 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml @@ -1,10 +1,22 @@ openapi: 3.1.0 info: title: Airflow API - description: Airflow API. All endpoints located under ``/api/v2`` can be used safely, - are stable and backward compatible. Endpoints located under ``/ui`` are dedicated - to the UI and are subject to breaking change depending on the need of the frontend. - Users should not rely on those but use the public ones instead. + description: "Airflow API. All endpoints located under ``/api/v2`` can be used safely,\ + \ are stable and backward compatible. Endpoints located under ``/ui`` are dedicated\ + \ to the UI and are subject to breaking change depending on the need of the frontend.\ + \ Users should not rely on those but use the public ones instead.\n\n**Filtering\ + \ with pattern parameters.** Many list endpoints accept ``*_pattern`` and ``*_prefix_pattern``\ + \ query parameters. Unless a parameter's own description says otherwise, ``*_pattern``\ + \ is a case-insensitive substring match (SQL ``ILIKE '%term%'``) where ``%`` matches\ + \ any sequence and ``_`` matches any single character (e.g. ``%customer_%``) \u2014\ + \ convenient, but it cannot use B-tree indexes, so it is slow on large tables.\ + \ ``*_prefix_pattern`` matches the start of the value, is case-sensitive and index-friendly\ + \ (prefer it at scale); there ``%`` and ``_`` are literal and trailing non-alphanumeric\ + \ characters are stripped so the range scan stays index-compatible under locale-aware\ + \ collations (e.g. ``test_`` matches values starting with ``test``, and ``s3://``\ + \ matches ``s3``). In both, ``|`` means OR (e.g. ``dag1|dag2``) and ``~`` matches\ + \ everything. Regular expressions are not supported by these parameters; regex-capable\ + \ endpoints expose a separate parameter." version: '2' paths: /ui/auth/menus: @@ -181,7 +193,7 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /ui/pending_partitioned_dag_run/{dag_id}/{partition_key}: + /ui/pending_partitioned_dag_run/{dag_id}: get: tags: - PartitionedDagRun @@ -199,7 +211,7 @@ paths: type: string title: Dag Id - name: partition_key - in: path + in: query required: true schema: type: string @@ -339,20 +351,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -360,23 +365,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: dag_display_name_pattern in: query required: false @@ -384,20 +377,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Dag Display Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_display_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: dag_display_name_prefix_pattern in: query required: false @@ -405,23 +391,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Display Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: exclude_stale in: query required: false @@ -457,6 +431,16 @@ paths: - $ref: '#/components/schemas/DagRunState' - type: 'null' title: Last Dag Run State + - name: dag_run_state + in: query + required: false + schema: + anyOf: + - $ref: '#/components/schemas/DagRunState' + - type: 'null' + description: Filter Dags that have any DagRun in the given state. + title: Dag Run State + description: Filter Dags that have any DagRun in the given state. - name: bundle_name in: query required: false @@ -869,6 +853,14 @@ paths: schema: type: string title: Dag Id + - name: version_number + in: query + required: false + schema: + anyOf: + - type: integer + - type: 'null' + title: Version Number - name: limit in: query required: false @@ -894,13 +886,12 @@ paths: type: string description: 'Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, - name, interval`' + name`' default: - created_at title: Order By description: 'Attributes to order by, multi criteria sort is supported. Prefix - with `-` for descending order. Supported attributes: `id, created_at, name, - interval`' + with `-` for descending order. Supported attributes: `id, created_at, name`' responses: '200': description: Successful Response @@ -1220,19 +1211,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``triggering_user`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Triggering User - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``triggering_user`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: triggering_user_prefix in: query required: false @@ -1240,23 +1225,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Triggering User Prefix - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -1393,19 +1366,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``triggering_user`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Triggering User - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``triggering_user`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: triggering_user_prefix in: query required: false @@ -1413,23 +1380,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Triggering User Prefix - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -2515,9 +2470,13 @@ components: type: string title: Reference Type interval: - type: number + anyOf: + - type: number + - type: 'null' title: Interval - description: Interval in seconds between deadline evaluations. + description: Interval in seconds between the reference time and the deadline. + Null for a dynamic interval (e.g. a VariableInterval) whose value is only + resolved at scheduler evaluation time. created_at: type: string format: date-time @@ -2526,7 +2485,6 @@ components: required: - id - reference_type - - interval - created_at title: DeadlineAlertResponse description: DeadlineAlert serializer for responses. @@ -2855,6 +2813,9 @@ components: has_missed_deadline: type: boolean title: Has Missed Deadline + has_note: + type: boolean + title: Has Note duration: type: number title: Duration @@ -2870,6 +2831,7 @@ components: - state - run_type - has_missed_deadline + - has_note - duration title: GridRunsResponse description: Base Node serializer for responses. @@ -3010,14 +2972,18 @@ components: $ref: '#/components/schemas/DAGRunStates' task_instance_states: $ref: '#/components/schemas/TaskInstanceStateCount' - state_count_limit: - type: integer - title: State Count Limit + dag_run_counts_are_lower_bounds: + type: boolean + title: Dag Run Counts Are Lower Bounds + default: false + task_instance_counts_are_lower_bounds: + type: boolean + title: Task Instance Counts Are Lower Bounds + default: false type: object required: - dag_run_states - task_instance_states - - state_count_limit title: HistoricalMetricDataResponse description: Historical Metric Data serializer for responses. JobResponse: @@ -3128,6 +3094,10 @@ components: - type: integer - type: 'null' title: Dag Version Number + has_note: + type: boolean + title: Has Note + default: false type: object required: - task_id diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml index ea6f0a70fcd0a..34068eab85b93 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml @@ -1,10 +1,22 @@ openapi: 3.1.0 info: title: Airflow API - description: Airflow API. All endpoints located under ``/api/v2`` can be used safely, - are stable and backward compatible. Endpoints located under ``/ui`` are dedicated - to the UI and are subject to breaking change depending on the need of the frontend. - Users should not rely on those but use the public ones instead. + description: "Airflow API. All endpoints located under ``/api/v2`` can be used safely,\ + \ are stable and backward compatible. Endpoints located under ``/ui`` are dedicated\ + \ to the UI and are subject to breaking change depending on the need of the frontend.\ + \ Users should not rely on those but use the public ones instead.\n\n**Filtering\ + \ with pattern parameters.** Many list endpoints accept ``*_pattern`` and ``*_prefix_pattern``\ + \ query parameters. Unless a parameter's own description says otherwise, ``*_pattern``\ + \ is a case-insensitive substring match (SQL ``ILIKE '%term%'``) where ``%`` matches\ + \ any sequence and ``_`` matches any single character (e.g. ``%customer_%``) \u2014\ + \ convenient, but it cannot use B-tree indexes, so it is slow on large tables.\ + \ ``*_prefix_pattern`` matches the start of the value, is case-sensitive and index-friendly\ + \ (prefer it at scale); there ``%`` and ``_`` are literal and trailing non-alphanumeric\ + \ characters are stripped so the range scan stays index-compatible under locale-aware\ + \ collations (e.g. ``test_`` matches values starting with ``test``, and ``s3://``\ + \ matches ``s3``). In both, ``|`` means OR (e.g. ``dag1|dag2``) and ``~`` matches\ + \ everything. Regular expressions are not supported by these parameters; regex-capable\ + \ endpoints expose a separate parameter." version: '2' paths: /api/v2/assets: @@ -41,20 +53,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``name_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: name_prefix_pattern in: query required: false @@ -62,23 +67,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: uri_pattern in: query required: false @@ -86,20 +79,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``uri_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `uri_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Uri Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``uri_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `uri_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: uri_prefix_pattern in: query required: false @@ -107,23 +93,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Uri Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: dag_ids in: query required: false @@ -220,20 +194,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``name_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: name_prefix_pattern in: query required: false @@ -241,23 +208,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: order_by in: query required: false @@ -440,20 +395,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``name_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `name_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: name_prefix_pattern in: query required: false @@ -461,23 +409,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: timestamp_gte in: query required: false @@ -1161,6 +1097,12 @@ paths: schema: $ref: '#/components/schemas/HTTPExceptionResponse' description: Conflict + '503': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPExceptionResponse' + description: Service Unavailable '422': description: Validation Error content: @@ -1420,6 +1362,12 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPExceptionResponse' + '503': + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPExceptionResponse' '422': description: Validation Error content: @@ -1735,20 +1683,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``connection_id_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `connection_id_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Connection Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``connection_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `connection_id_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: connection_id_prefix_pattern in: query required: false @@ -1756,23 +1697,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Connection Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -2234,6 +2163,36 @@ paths: schema: type: string title: Dag Id + - name: partition_date_gte + in: query + required: false + schema: + anyOf: + - type: string + format: date + - type: 'null' + description: Inclusive lower bound of the partition_date window, interpreted + as a local calendar day in the Dag's timetable timezone. Runs from the + start of this day onwards match. + title: Partition Date Gte + description: Inclusive lower bound of the partition_date window, interpreted + as a local calendar day in the Dag's timetable timezone. Runs from the start + of this day onwards match. + - name: partition_date_lte + in: query + required: false + schema: + anyOf: + - type: string + format: date + - type: 'null' + description: 'Inclusive upper bound of the partition_date window, interpreted + as a local calendar day in the Dag''s timetable timezone. The whole day + is included: runs up to the end of this day match.' + title: Partition Date Lte + description: 'Inclusive upper bound of the partition_date window, interpreted + as a local calendar day in the Dag''s timetable timezone. The whole day + is included: runs up to the end of this day match.' - name: cursor in: query required: false @@ -2523,15 +2482,15 @@ paths: type: string description: 'Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, - dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, - conf, duration, dag_run_id`' + dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date, + updated_at, conf, duration, dag_run_id`' default: - id title: Order By description: 'Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, - run_id, logical_date, run_after, start_date, end_date, updated_at, conf, - duration, dag_run_id`' + run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at, + conf, duration, dag_run_id`' - name: run_id_pattern in: query required: false @@ -2539,20 +2498,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Run Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``run_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: run_id_prefix_pattern in: query required: false @@ -2560,23 +2512,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Run Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: triggering_user_name_pattern in: query required: false @@ -2584,21 +2524,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``triggering_user_name_prefix_pattern``\ - \ parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user_name_prefix_pattern` on large tables \u2014 see \"\ + Filtering with pattern parameters\"." title: Triggering User Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``triggering_user_name_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `triggering_user_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: triggering_user_name_prefix_pattern in: query required: false @@ -2606,23 +2538,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Triggering User Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: dag_id_pattern in: query required: false @@ -2630,20 +2550,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -2651,23 +2564,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: partition_key_pattern in: query required: false @@ -2675,20 +2576,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ The pipe `|` is matched literally, not as an OR separator. Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the\ - \ database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``partition_key_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Here `|` is\ + \ matched literally, not as OR. Slower than `partition_key_prefix_pattern`\ + \ on large tables \u2014 see \"Filtering with pattern parameters\"." title: Partition Key Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ The pipe `|` is matched literally, not as an OR separator. Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``partition_key_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Here `|` is\ + \ matched literally, not as OR. Slower than `partition_key_prefix_pattern`\ + \ on large tables \u2014 see \"Filtering with pattern parameters\"." - name: partition_key_prefix_pattern in: query required: false @@ -2696,23 +2590,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). The pipe `|` is part\ - \ of the prefix, not an OR separator. Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. Here `|` is matched + literally, not as OR. See "Filtering with pattern parameters". title: Partition Key Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). The pipe `|` is part of\ - \ the prefix, not an OR separator. Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. Here `|` is matched + literally, not as OR. See "Filtering with pattern parameters". - name: consuming_asset_pattern in: query required: false @@ -2720,9 +2602,14 @@ paths: anyOf: - type: string - type: 'null' - description: Filter by consuming asset name or URI using pattern matching + description: Case-insensitive substring match against the consuming asset + name or URI. Unlike the wildcard `*_pattern` parameters, `%` and `_` are + matched literally, `|` is not an OR separator, and `~` does not match + everything. title: Consuming Asset Pattern - description: Filter by consuming asset name or URI using pattern matching + description: Case-insensitive substring match against the consuming asset + name or URI. Unlike the wildcard `*_pattern` parameters, `%` and `_` are + matched literally, `|` is not an OR separator, and `~` does not match everything. responses: '200': description: Successful Response @@ -3650,20 +3537,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -3671,23 +3551,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: dag_display_name_pattern in: query required: false @@ -3695,20 +3563,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Dag Display Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_display_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: dag_display_name_prefix_pattern in: query required: false @@ -3716,23 +3577,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Display Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: exclude_stale in: query required: false @@ -4020,20 +3869,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -4041,23 +3883,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: exclude_stale in: query required: false @@ -4630,20 +4460,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: task_id_pattern in: query required: false @@ -4651,20 +4474,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Task Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``task_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: run_id_pattern in: query required: false @@ -4672,20 +4488,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Run Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``run_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: owner_pattern in: query required: false @@ -4693,20 +4502,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``owner_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `owner_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Owner Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``owner_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `owner_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: event_pattern in: query required: false @@ -4714,20 +4516,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``event_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `event_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Event Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``event_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `event_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -4735,23 +4530,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: task_id_prefix_pattern in: query required: false @@ -4759,23 +4542,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Task Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: run_id_prefix_pattern in: query required: false @@ -4783,23 +4554,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Run Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: owner_prefix_pattern in: query required: false @@ -4807,23 +4566,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Owner Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: event_prefix_pattern in: query required: false @@ -4831,23 +4578,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Event Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -5047,20 +4782,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``filename_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `filename_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Filename Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``filename_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `filename_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: filename_prefix_pattern in: query required: false @@ -5068,23 +4796,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Filename Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: filename in: query required: false @@ -5616,20 +5332,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Pool Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``pool_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: pool_name_prefix_pattern in: query required: false @@ -5637,23 +5346,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Pool Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -6862,20 +6559,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``xcom_key_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `xcom_key_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Xcom Key Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``xcom_key_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `xcom_key_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: xcom_key_prefix_pattern in: query required: false @@ -6883,23 +6573,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Xcom Key Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: dag_display_name_pattern in: query required: false @@ -6907,20 +6585,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Dag Display Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_display_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: dag_display_name_prefix_pattern in: query required: false @@ -6928,23 +6599,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Display Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: run_id_pattern in: query required: false @@ -6952,20 +6611,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Run Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``run_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: run_id_prefix_pattern in: query required: false @@ -6973,23 +6625,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Run Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: task_id_pattern in: query required: false @@ -6997,20 +6637,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Task Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``task_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: task_id_prefix_pattern in: query required: false @@ -7018,23 +6651,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Task Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: map_index_filter in: query required: false @@ -7237,6 +6858,12 @@ paths: schema: $ref: '#/components/schemas/HTTPExceptionResponse' description: Not Found + '409': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPExceptionResponse' + description: Conflict '422': description: Validation Error content: @@ -7727,20 +7354,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Pool Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``pool_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: pool_name_prefix_pattern in: query required: false @@ -7748,23 +7368,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Pool Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: queue in: query required: false @@ -7780,20 +7388,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `queue_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Queue Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``queue_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `queue_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: queue_name_prefix_pattern in: query required: false @@ -7801,23 +7402,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Queue Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: executor in: query required: false @@ -7857,20 +7446,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `operator_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Operator Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``operator_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `operator_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: operator_name_prefix_pattern in: query required: false @@ -7878,23 +7460,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Operator Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: map_index in: query required: false @@ -7910,20 +7480,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``rendered_map_index_prefix_pattern``\ - \ parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `rendered_map_index_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Rendered Map Index Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `rendered_map_index_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: rendered_map_index_prefix_pattern in: query required: false @@ -7931,23 +7494,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Rendered Map Index Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: limit in: query required: false @@ -8726,20 +8277,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``task_display_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Task Display Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``task_display_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_display_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: task_display_name_prefix_pattern in: query required: false @@ -8747,21 +8291,16 @@ paths: anyOf: - type: string - type: 'null' - description: 'Prefix match on task display name: optional ``_task_display_property_value`` - else ``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly - alternative to ``task_display_name_pattern``. On large databases, combine - with ``dag_id_prefix_pattern`` (or a specific Dag in the path) so ``(dag_id, - task_id, ...)`` indexes apply. Use ``|`` for OR. Use ``~`` to match all. - Trailing non-alphanumeric characters in the term are stripped before matching - so the range scan stays index-compatible under locale-aware collations.' + description: Case-sensitive prefix match on task display name (`_task_display_property_value` + else `task_id`). Index-friendly alternative to `task_display_name_pattern`; + on large databases combine with `dag_id_prefix_pattern` (or a specific + Dag in the path) so composite indexes apply. See "Filtering with pattern + parameters". title: Task Display Name Prefix Pattern - description: 'Prefix match on task display name: optional ``_task_display_property_value`` - else ``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly - alternative to ``task_display_name_pattern``. On large databases, combine - with ``dag_id_prefix_pattern`` (or a specific Dag in the path) so ``(dag_id, - task_id, ...)`` indexes apply. Use ``|`` for OR. Use ``~`` to match all. - Trailing non-alphanumeric characters in the term are stripped before matching - so the range scan stays index-compatible under locale-aware collations.' + description: Case-sensitive prefix match on task display name (`_task_display_property_value` + else `task_id`). Index-friendly alternative to `task_display_name_pattern`; + on large databases combine with `dag_id_prefix_pattern` (or a specific Dag + in the path) so composite indexes apply. See "Filtering with pattern parameters". - name: task_group_id in: query required: false @@ -8781,20 +8320,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -8802,23 +8334,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: run_id_pattern in: query required: false @@ -8826,20 +8346,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Run Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``run_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `run_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: run_id_prefix_pattern in: query required: false @@ -8847,23 +8360,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Run Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: state in: query required: false @@ -8887,20 +8388,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Pool Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``pool_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `pool_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: pool_name_prefix_pattern in: query required: false @@ -8908,23 +8402,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Pool Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: queue in: query required: false @@ -8940,20 +8422,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `queue_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Queue Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``queue_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `queue_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: queue_name_prefix_pattern in: query required: false @@ -8961,23 +8436,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Queue Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: executor in: query required: false @@ -9017,20 +8480,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `operator_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Operator Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``operator_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `operator_name_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: operator_name_prefix_pattern in: query required: false @@ -9038,23 +8494,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Operator Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: map_index in: query required: false @@ -9070,20 +8514,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``rendered_map_index_prefix_pattern``\ - \ parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `rendered_map_index_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Rendered Map Index Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `rendered_map_index_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." - name: rendered_map_index_prefix_pattern in: query required: false @@ -9091,23 +8528,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Rendered Map Index Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: limit in: query required: false @@ -10168,20 +9593,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``variable_key_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `variable_key_prefix_pattern` on large tables \u2014 see \"Filtering\ + \ with pattern parameters\"." title: Variable Key Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``variable_key_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `variable_key_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: variable_key_prefix_pattern in: query required: false @@ -10189,23 +9607,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Variable Key Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -10600,20 +10006,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``tag_name_prefix_pattern`` parameter\ - \ when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `tag_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Tag Name Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``tag_name_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `tag_name_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." - name: tag_name_prefix_pattern in: query required: false @@ -10621,23 +10020,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Tag Name Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". responses: '200': description: Successful Response @@ -11104,20 +10491,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Dag Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``dag_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `dag_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: dag_id_prefix_pattern in: query required: false @@ -11125,23 +10505,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Dag Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: task_id in: query required: false @@ -11157,20 +10525,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when\ - \ possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with\ + \ pattern parameters\"." title: Task Id Pattern - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``task_id_prefix_pattern`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `task_id_prefix_pattern` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." - name: task_id_prefix_pattern in: query required: false @@ -11178,23 +10539,11 @@ paths: anyOf: - type: string - type: 'null' - description: "Prefix match \u2014 returns items whose value starts with\ - \ the given string (case-sensitive, index-friendly). Use the pipe `|`\ - \ operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard\ - \ characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches\ - \ items starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering + with pattern parameters". title: Task Id Prefix Pattern - description: "Prefix match \u2014 returns items whose value starts with the\ - \ given string (case-sensitive, index-friendly). Use the pipe `|` operator\ - \ for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters\ - \ (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric\ - \ characters in the prefix are stripped before matching so the range scan\ - \ stays index-compatible under locale-aware collations \u2014 e.g. `test_`\ - \ effectively matches items starting with `test`, and `s3://` matches items\ - \ starting with `s3`." + description: Case-sensitive, index-friendly prefix match. See "Filtering with + pattern parameters". - name: map_index in: query required: false @@ -11242,19 +10591,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``subject_search`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `subject_search` on large tables \u2014 see \"Filtering with pattern\ + \ parameters\"." title: Subject Search - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``subject_search`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `subject_search` on large tables \u2014 see \"Filtering with pattern parameters\"\ + ." - name: body_search in: query required: false @@ -11262,19 +10605,13 @@ paths: anyOf: - type: string - type: 'null' - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular\ - \ expressions are **not** supported. \n\n**Performance note:** this full-match\ - \ pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents\ - \ the database from using B-tree indexes, which can be very slow on large\ - \ tables. Prefer the equivalent ``body_search`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `body_search` on large tables \u2014 see \"Filtering with pattern parameters\"\ + ." title: Body Search - description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ - \ Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions\ - \ are **not** supported. \n\n**Performance note:** this full-match pattern\ - \ is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database\ - \ from using B-tree indexes, which can be very slow on large tables. Prefer\ - \ the equivalent ``body_search`` parameter when possible." + description: "Case-insensitive substring match (SQL `ILIKE`). Slower than\ + \ `body_search` on large tables \u2014 see \"Filtering with pattern parameters\"\ + ." - name: created_at_gte in: query required: false @@ -13147,6 +12484,8 @@ components: partition_key: anyOf: - type: string + maxLength: 250 + pattern: \S - type: 'null' title: Partition Key extra: diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py index 15af36445dd95..9db8e1bffbd08 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py @@ -82,6 +82,7 @@ AssetWatcherModel, TaskOutletAssetReference, ) +from airflow.models.dag import DagModel from airflow.typing_compat import Unpack from airflow.utils.state import DagRunState from airflow.utils.types import DagRunTriggeredByType, DagRunType @@ -435,7 +436,10 @@ def materialize_asset( if not get_auth_manager().is_authorized_dag( method="POST", access_entity=DagAccessEntity.RUN, - details=DagDetails(id=dag_id), + # The Dag is resolved from the asset here rather than named by the caller, so its team has + # to be looked up too. A team-aware auth manager distinguishes a team-scoped Dag from a + # global one by this field, so leaving it None asks the wrong question. + details=DagDetails(id=dag_id, team_name=DagModel.get_team_name(dag_id, session=session)), user=user, ): raise HTTPException( @@ -464,6 +468,7 @@ def materialize_asset( triggering_user_name=user.get_name(), state=DagRunState.QUEUED, partition_key=params["partition_key"], + partition_date=params["partition_date"], note=params["note"], session=session, ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py index 0dba6086e0aee..c4971b883a11b 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/backfills.py @@ -16,12 +16,13 @@ # under the License. from __future__ import annotations -from typing import Annotated +from typing import Annotated, NoReturn from fastapi import Depends, HTTPException, status from fastapi.exceptions import RequestValidationError from pydantic import NonNegativeInt from sqlalchemy import select, update +from sqlalchemy.exc import OperationalError from sqlalchemy.orm import joinedload from airflow._shared.timezones import timezone @@ -56,14 +57,29 @@ InvalidBackfillDateRange, InvalidBackfillDirection, InvalidReprocessBehavior, + NoBackfillRunsToCreate, _create_backfill, _do_dry_run, ) +from airflow.utils.sqlalchemy import is_lock_not_available_error from airflow.utils.state import DagRunState backfills_router = AirflowRouter(tags=["Backfill"], prefix="/backfills") +def _raise_locked_response_or_reraise(e: OperationalError, action: str) -> NoReturn: + """Map a database lock OperationalError to HTTP 503, or re-raise if not a lock error.""" + if not is_lock_not_available_error(e): + raise + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail=( + f"Database is locked. Backfill {action} is not supported on SQLite " + "under concurrent access. Please use PostgreSQL or MySQL." + ), + ) + + @backfills_router.get( path="", dependencies=[ @@ -135,7 +151,6 @@ def pause_backfill(backfill_id: NonNegativeInt, session: SessionDep) -> Backfill raise HTTPException(status.HTTP_409_CONFLICT, "Backfill is already completed.") if b.is_paused is False: b.is_paused = True - session.commit() return b @@ -219,7 +234,12 @@ def cancel_backfill(backfill_id: NonNegativeInt, session: SessionDep) -> Backfil @backfills_router.post( path="", responses=create_openapi_http_exception_doc( - [status.HTTP_400_BAD_REQUEST, status.HTTP_404_NOT_FOUND, status.HTTP_409_CONFLICT] + [ + status.HTTP_400_BAD_REQUEST, + status.HTTP_404_NOT_FOUND, + status.HTTP_409_CONFLICT, + status.HTTP_503_SERVICE_UNAVAILABLE, + ] ), dependencies=[ Depends(action_logging()), @@ -252,6 +272,8 @@ def create_backfill( run_on_latest_version=resolved_run_on_latest, ) return BackfillResponse.model_validate(backfill_obj) + except OperationalError as e: + _raise_locked_response_or_reraise(e, "creation") except AlreadyRunningBackfill: raise HTTPException( @@ -276,13 +298,20 @@ def create_backfill( InvalidBackfillDate, InvalidBackfillDateRange, InvalidBackfillConf, + NoBackfillRunsToCreate, ) as e: raise RequestValidationError(str(e)) @backfills_router.post( path="/dry_run", - responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND, status.HTTP_409_CONFLICT]), + responses=create_openapi_http_exception_doc( + [ + status.HTTP_404_NOT_FOUND, + status.HTTP_409_CONFLICT, + status.HTTP_503_SERVICE_UNAVAILABLE, + ] + ), dependencies=[ Depends(requires_access_backfill(method="POST")), ], @@ -306,13 +335,15 @@ def create_backfill_dry_run( ) backfills = [ DryRunBackfillResponse( - logical_date=d.logical_date, partition_key=d.partition_key, partition_date=d.partition_date + logical_date=d.logical_date, + partition_key=d.partition_key, + partition_date=d.partition_date, ) for d in backfills_dry_run ] - return DryRunBackfillCollectionResponse(backfills=backfills, total_entries=len(backfills)) - + except OperationalError as e: + _raise_locked_response_or_reraise(e, "dry-run") except DagNotFound: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py index 9f4b3359508a1..ea6af1e7e20a7 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/config.py @@ -153,9 +153,7 @@ def get_config_value( ) section_l, option_l = section.lower(), option.lower() - if (section_l, option_l) in conf.sensitive_config_values or _is_per_key_sensitive_option( - section_l, option_l - ): + if conf.is_sensitive_option(section_l, option_l) or _is_per_key_sensitive_option(section_l, option_l): value = "< hidden >" else: value = conf.get(section, option) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py index a1827253180d4..a72c51ada26d6 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py @@ -36,6 +36,7 @@ SortParam, ) from airflow.api_fastapi.common.router import AirflowRouter +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.api_fastapi.core_api.datamodels.common import ( BulkBody, BulkResponse, @@ -96,7 +97,7 @@ def _ensure_executor_is_configured(executor: str | None) -> None: executor in (name.alias, name.module_path, name.module_path.split(".")[-1]) for name in configured ): raise HTTPException( - status.HTTP_422_UNPROCESSABLE_ENTITY, + HTTP_422_UNPROCESSABLE_CONTENT, f"Executor '{executor}' is not configured. " f"Configured executors: {[name.alias or name.module_path for name in configured]}", ) @@ -307,11 +308,30 @@ def test_connection(test_body: ConnectionBody) -> ConnectionTestResponse: try: # Try to get existing connection and merge with provided values try: - existing_conn = Connection.get_connection_from_secrets(test_body.connection_id) + existing_conn: Connection | None = Connection.get_connection_from_secrets(test_body.connection_id) + except AirflowNotFoundException: + existing_conn = None + + if existing_conn is not None: + # Stored credentials are only reused to test the connection's own + # host/port; testing a different destination must supply its own. + fields_set = test_body.model_fields_set + if ("host" in fields_set and test_body.host != existing_conn.host) or ( + "port" in fields_set and test_body.port != existing_conn.port + ): + if "password" not in fields_set: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + "The host or port to test differs from the stored connection. " + "Include the credentials to test in the request body.", + ) + existing_conn = None + + if existing_conn is not None: existing_conn.conn_id = transient_conn_id update_orm_from_pydantic(existing_conn, test_body) conn = existing_conn - except AirflowNotFoundException: + else: data = test_body.model_dump(by_alias=True) data["conn_id"] = transient_conn_id conn = Connection(**data) @@ -330,7 +350,7 @@ def test_connection(test_body: ConnectionBody) -> ConnectionTestResponse: [ status.HTTP_403_FORBIDDEN, status.HTTP_409_CONFLICT, - status.HTTP_422_UNPROCESSABLE_ENTITY, + HTTP_422_UNPROCESSABLE_CONTENT, ] ), dependencies=[Depends(action_logging())], diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_parsing.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_parsing.py index 5a9a5d7e397aa..1a901537dce0e 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_parsing.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_parsing.py @@ -16,25 +16,16 @@ # under the License. from __future__ import annotations -from collections.abc import Sequence -from typing import TYPE_CHECKING +from fastapi import Depends, Request, status +from itsdangerous import URLSafeSerializer -from fastapi import Depends, HTTPException, Request, status -from itsdangerous import BadSignature, URLSafeSerializer -from sqlalchemy import select - -from airflow.api_fastapi.auth.managers.models.resource_details import DagDetails from airflow.api_fastapi.common.db.common import SessionDep from airflow.api_fastapi.common.router import AirflowRouter from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc -from airflow.api_fastapi.core_api.security import requires_access_dag +from airflow.api_fastapi.core_api.security import requires_access_dag_from_file_token from airflow.api_fastapi.logging.decorators import action_logging -from airflow.models.dag import DagModel from airflow.models.dagbag import DagPriorityParsingRequest -if TYPE_CHECKING: - from airflow.api_fastapi.auth.managers.models.batch_apis import IsAuthorizedDagRequest - dag_parsing_router = AirflowRouter(tags=["DAG Parsing"], prefix="/parseDagFile/{file_token}") @@ -42,34 +33,12 @@ "", responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]), status_code=status.HTTP_201_CREATED, - dependencies=[Depends(requires_access_dag(method="PUT")), Depends(action_logging())], + dependencies=[Depends(requires_access_dag_from_file_token(method="PUT")), Depends(action_logging())], ) -def reparse_dag_file( - file_token: str, - session: SessionDep, - request: Request, -) -> None: +def reparse_dag_file(file_token: str, session: SessionDep, request: Request) -> None: """Request re-parsing a Dag file.""" - secret_key = request.app.state.secret_key - auth_s = URLSafeSerializer(secret_key) - try: - payload = auth_s.loads(file_token) - except BadSignature: - raise HTTPException(status.HTTP_404_NOT_FOUND, "File not found") - - bundle_name = payload["bundle_name"] - relative_fileloc = payload["relative_fileloc"] - - requests: Sequence[IsAuthorizedDagRequest] = [ - {"method": "PUT", "details": DagDetails(id=dag_id)} - for dag_id in session.scalars( - select(DagModel.dag_id).where( - DagModel.bundle_name == bundle_name, DagModel.relative_fileloc == relative_fileloc - ) - ) - ] - if not requests: - raise HTTPException(status.HTTP_404_NOT_FOUND, "File not found") - - parsing_request = DagPriorityParsingRequest(bundle_name=bundle_name, relative_fileloc=relative_fileloc) + payload = URLSafeSerializer(request.app.state.secret_key).loads(file_token) + parsing_request = DagPriorityParsingRequest( + bundle_name=payload["bundle_name"], relative_fileloc=payload["relative_fileloc"] + ) session.add(parsing_request) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py index 889251bf81e99..19bffb1015c49 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_run.py @@ -17,6 +17,7 @@ from __future__ import annotations +import datetime import textwrap from typing import Annotated, Literal, cast @@ -222,13 +223,13 @@ def patch_dag_run( data = patch_body.model_dump(include=fields_to_update, by_alias=True) - for attr_name, attr_value_raw in data.items(): - if attr_name == "state" and patch_body.state is not None: - patch_dag_run_state(dag=dag, dag_run=dag_run, state=patch_body.state, session=session) - elif attr_name == "note": - updated_dag_run = session.get(DagRun, dag_run.id) - if updated_dag_run is not None: - patch_dag_run_note(dag_run=updated_dag_run, note=attr_value_raw, user=user) + # Apply "note" before "state" so listeners fired inside patch_dag_run_state() see the updated note. + if "note" in data: + updated_dag_run = session.get(DagRun, dag_run.id) + if updated_dag_run is not None: + patch_dag_run_note(dag_run=updated_dag_run, note=data["note"], user=user) + if "state" in data and patch_body.state is not None: + patch_dag_run_state(dag=dag, dag_run=dag_run, state=patch_body.state, session=session) final_dag_run = session.get(DagRun, dag_run.id) if not final_dag_run: @@ -509,6 +510,7 @@ def get_dag_runs( "dag_id", "run_id", "logical_date", + "partition_date", "run_after", "start_date", "end_date", @@ -547,6 +549,21 @@ def get_dag_runs( partition_key_pattern: QueryDagRunPartitionKeySearch, partition_key_prefix_pattern: QueryDagRunPartitionKeyPrefixSearch, consuming_asset_pattern: QueryConsumingAssetPatternSearch, + partition_date_gte: datetime.date | None = Query( + None, + description=( + "Inclusive lower bound of the partition_date window, interpreted as a local calendar " + "day in the Dag's timetable timezone. Runs from the start of this day onwards match." + ), + ), + partition_date_lte: datetime.date | None = Query( + None, + description=( + "Inclusive upper bound of the partition_date window, interpreted as a local calendar " + "day in the Dag's timetable timezone. The whole day is included: runs up to the end " + "of this day match." + ), + ), cursor: str | None = Query( None, description="Cursor for keyset-based pagination. " @@ -571,9 +588,46 @@ def get_dag_runs( use_cursor = cursor is not None query = select(DagRun).options(*eager_load_dag_run_for_list()) - if dag_id != "~": - get_latest_version_of_dag(dag_bag, dag_id, session) # Check if the Dag exists. + has_partition_date_filter = partition_date_gte is not None or partition_date_lte is not None + + if dag_id == "~": + if has_partition_date_filter: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + "partition_date_gte and partition_date_lte require a specific dag_id.", + ) + else: + dag = get_latest_version_of_dag(dag_bag, dag_id, session) # Check if the Dag exists. query = query.filter(DagRun.dag_id == dag_id).options() + if has_partition_date_filter: + # Runs of a non-partitioned Dag never carry a partition_date (this includes + # partitioned-at-runtime Dags, whose runs keep it NULL), so the filter would + # silently match nothing; reject it instead. + if not dag.timetable.partitioned: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + f"Dag with dag_id: '{dag_id}' is not partitioned; " + "partition_date_gte and partition_date_lte are not supported.", + ) + # The bounds are calendar days, so the whole of partition_date_lte belongs to the + # window: widen it to the following local midnight and exclude that edge. + query = DagRun.apply_partition_date_window( + query, + timetable=dag.timetable, + start=( + datetime.datetime.combine(partition_date_gte, datetime.time.min) + if partition_date_gte is not None + else None + ), + end=( + datetime.datetime.combine( + partition_date_lte + datetime.timedelta(days=1), datetime.time.min + ) + if partition_date_lte is not None + else None + ), + end_exclusive=True, + ) # Add join with DagVersion if dag_version filter is active if dag_version.value: @@ -609,16 +663,19 @@ def get_dag_runs( "int", limit.value ) # LimitFilter value is guaranteed to be set to the default value of QueryLimit cursor_limit = LimitFilter().set_value(page_limit + 1) - dag_run_select = apply_filters_to_select(statement=query, filters=[*filters, order_by, cursor_limit]) + dag_run_select = apply_filters_to_select(statement=query, filters=[*filters, cursor_limit]) + dag_run_select = order_by.to_orm(dag_run_select) is_backward = False if cursor: token, is_backward = parse_cursor(cursor) if is_backward: dag_run_select = order_by.to_orm(dag_run_select, reversed=True) - dag_run_select = apply_cursor_filter(dag_run_select, token, order_by, is_backward=is_backward) + dag_run_select = apply_cursor_filter( + dag_run_select, token, order_by, session.get_bind().dialect.name, is_backward=is_backward + ) - fetched = list(session.scalars(dag_run_select).unique()) + fetched = list(session.scalars(dag_run_select)) has_more = len(fetched) > page_limit dag_runs = fetched[:page_limit] @@ -648,7 +705,7 @@ def get_dag_runs( limit=limit, session=session, ) - dag_runs = list(session.scalars(dag_run_select).unique()) + dag_runs = list(session.scalars(dag_run_select)) attach_dag_versions_to_runs(dag_runs, session=session) return DAGRunCollectionResponse( @@ -777,7 +834,10 @@ def wait_dag_run_until_finished( if not get_auth_manager().is_authorized_dag( method="GET", access_entity=DagAccessEntity.XCOM, - details=DagDetails(id=dag_id), + # The route dependency above already authorizes RUN access with the Dag's team resolved; + # this second, XCom-specific check has to resolve it the same way, or the two checks ask + # a team-aware auth manager about differently-scoped resources. + details=DagDetails(id=dag_id, team_name=DagModel.get_team_name(dag_id, session=session)), user=user, ): if result_task_ids: @@ -902,7 +962,7 @@ def get_list_dag_runs_batch( session=session, ) - dag_runs = list(session.scalars(dag_runs_select).unique()) + dag_runs = list(session.scalars(dag_runs_select)) attach_dag_versions_to_runs(dag_runs, session=session) return DAGRunCollectionResponse( diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_tags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_tags.py index b09f524c1ac6b..d31c71c89c8fe 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_tags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dag_tags.py @@ -21,7 +21,7 @@ from typing import Annotated from fastapi import Depends -from sqlalchemy import select +from sqlalchemy import false, select from airflow.api_fastapi.common.db.common import ( SessionDep, @@ -37,7 +37,7 @@ from airflow.api_fastapi.common.router import AirflowRouter from airflow.api_fastapi.core_api.datamodels.dag_tags import DAGTagCollectionResponse from airflow.api_fastapi.core_api.security import ReadableTagsFilterDep, requires_access_dag -from airflow.models.dag import DagTag +from airflow.models.dag import DagModel, DagTag dag_tags_router = AirflowRouter(tags=["DAG"], prefix="/dagTags") @@ -61,7 +61,12 @@ def get_dag_tags( session: SessionDep, ) -> DAGTagCollectionResponse: """Get all Dag tags.""" - query = select(DagTag.name).group_by(DagTag.name) + query = ( + select(DagTag.name) + .join(DagModel, DagModel.dag_id == DagTag.dag_id) + .where(DagModel.is_stale == false()) + .group_by(DagTag.name) + ) dag_tags_select, total_entries = paginated_select( statement=query, filters=[tag_name_pattern, tag_name_prefix_pattern, readable_tags_filter], diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py index 355ce4ca7a5e7..69b6b2932f095 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/dags.py @@ -250,7 +250,7 @@ def get_dag_details( session.scalar( select(func.count()) .select_from(DagRun) - .where(DagRun.dag_id == dag_id, DagRun.state.in_([DagRunState.RUNNING, DagRunState.QUEUED])) + .where(DagRun.dag_id == dag_id, DagRun.state == DagRunState.RUNNING) ) or 0 ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py index 2ad11a245d664..ccb2c3dd77f2d 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py @@ -243,8 +243,6 @@ def update_hitl_detail( task_instance=locked_ti, session=session, ) - - session.commit() return HITLDetailResponse.model_validate(hitl_detail_model) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py index 68120ace15380..7305e4e89be57 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py @@ -607,9 +607,8 @@ def get_task_instances( "int", limit.value ) # LimitFilter value is guaranteed to be set to the default value of QueryLimit cursor_limit = LimitFilter().set_value(page_limit + 1) - task_instance_select = apply_filters_to_select( - statement=query, filters=[*filters, order_by, cursor_limit] - ) + task_instance_select = apply_filters_to_select(statement=query, filters=[*filters, cursor_limit]) + task_instance_select = order_by.to_orm(task_instance_select) is_backward = False if cursor: @@ -617,7 +616,11 @@ def get_task_instances( if is_backward: task_instance_select = order_by.to_orm(task_instance_select, reversed=True) task_instance_select = apply_cursor_filter( - task_instance_select, token, order_by, is_backward=is_backward + task_instance_select, + token, + order_by, + session.get_bind().dialect.name, + is_backward=is_backward, ) fetched = list(session.scalars(task_instance_select)) @@ -970,16 +973,12 @@ def _collect_relatives(run_id: str, direction: Literal["upstream", "downstream"] # dag.clear() returns TIs without this relationship loaded; re-query with joinedload. # populate_existing=True ensures the joinedload updates TIs already in the identity map. if task_instances: - task_instances = ( - session.scalars( - select(TI) - .options(joinedload(TI.rendered_task_instance_fields)) - .where(TI.id.in_([ti.id for ti in task_instances])) - .execution_options(populate_existing=True) - ) - .unique() - .all() - ) + task_instances = session.scalars( + select(TI) + .options(joinedload(TI.rendered_task_instance_fields)) + .where(TI.id.in_([ti.id for ti in task_instances])) + .execution_options(populate_existing=True) + ).all() return TaskInstanceCollectionResponse( task_instances=[TaskInstanceResponse.model_validate(ti) for ti in task_instances], @@ -1014,6 +1013,14 @@ def patch_task_group_instances( ) response_tis = tis + # Apply "note" before "state" so listeners fired inside _patch_task_group_state() see the updated note. + if "note" in data: + _patch_task_instance_note( + task_instance_body=body, + tis=response_tis, + user=user, + update_mask=update_mask, + ) if "new_state" in data: response_tis = _patch_task_group_state( group_id=group_id, @@ -1023,13 +1030,6 @@ def patch_task_group_instances( data=data, session=session, ) - if "note" in data: - _patch_task_instance_note( - task_instance_body=body, - tis=response_tis, - user=user, - update_mask=update_mask, - ) response_tis = _reload_tis_with_rendered_fields(response_tis, session) @@ -1136,16 +1136,12 @@ def patch_task_instance_dry_run( # set_task_instance_state() returns TIs without this relationship loaded; re-query with joinedload. # populate_existing=True ensures the joinedload updates TIs already in the identity map. if tis: - tis = ( - session.scalars( - select(TI) - .options(joinedload(TI.rendered_task_instance_fields)) - .where(TI.id.in_([ti.id for ti in tis])) - .execution_options(populate_existing=True) - ) - .unique() - .all() - ) + tis = session.scalars( + select(TI) + .options(joinedload(TI.rendered_task_instance_fields)) + .where(TI.id.in_([ti.id for ti in tis])) + .execution_options(populate_existing=True) + ).all() return TaskInstanceCollectionResponse( task_instances=[ @@ -1214,36 +1210,34 @@ def patch_task_instance( dag_id, dag_run_id, task_id, dag_bag, body, session, map_index, update_mask ) - for key, _ in data.items(): - if key == "new_state": - # Create BulkTaskInstanceBody object with map_index field - bulk_ti_body = BulkTaskInstanceBody( - task_id=task_id, - map_index=map_index, - new_state=body.new_state, - note=body.note, - include_upstream=body.include_upstream, - include_downstream=body.include_downstream, - include_future=body.include_future, - include_past=body.include_past, - ) - - _patch_task_instance_state( - task_id=task_id, - dag_run_id=dag_run_id, - dag=dag, - task_instance_body=bulk_ti_body, - data=data, - session=session, - ) - - elif key == "note": - _patch_task_instance_note( - task_instance_body=body, - tis=tis, - user=user, - update_mask=update_mask, - ) + # Apply "note" before "state" so listeners fired inside _patch_task_instance_state() see the updated note. + if "note" in data: + _patch_task_instance_note( + task_instance_body=body, + tis=tis, + user=user, + update_mask=update_mask, + ) + if "new_state" in data: + # Create BulkTaskInstanceBody object with map_index field + bulk_ti_body = BulkTaskInstanceBody( + task_id=task_id, + map_index=map_index, + new_state=body.new_state, + note=body.note, + include_upstream=body.include_upstream, + include_downstream=body.include_downstream, + include_future=body.include_future, + include_past=body.include_past, + ) + _patch_task_instance_state( + task_id=task_id, + dag_run_id=dag_run_id, + dag=dag, + task_instance_body=bulk_ti_body, + data=data, + session=session, + ) return TaskInstanceCollectionResponse( task_instances=[ diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/xcom.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/xcom.py index 13c7f78ed28f5..40bb97cfc9fee 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/xcom.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/xcom.py @@ -237,6 +237,7 @@ def get_xcom_entries( [ status.HTTP_400_BAD_REQUEST, status.HTTP_404_NOT_FOUND, + status.HTTP_409_CONFLICT, ] ), dependencies=[ @@ -269,10 +270,9 @@ def create_xcom_entry( # Validate Dag Run ID if not dag_run: - if not dag_run: - raise HTTPException( - status.HTTP_404_NOT_FOUND, f"Dag Run with ID: `{dag_run_id}` not found for dag: `{dag_id}`" - ) + raise HTTPException( + status.HTTP_404_NOT_FOUND, f"Dag Run with ID: `{dag_run_id}` not found for dag: `{dag_id}`" + ) # Check existing XCom already_existing_query = XComModel.get_many( diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py index d2b86beb2b711..c031d278fa6c0 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py @@ -32,6 +32,7 @@ from airflow.api_fastapi.common.parameters import ( FilterOptionEnum, FilterParam, + QueryAnyDagRunStateFilter, QueryAssetDependencyFilter, QueryBundleNameFilter, QueryBundleVersionFilter, @@ -74,6 +75,9 @@ dags_router = AirflowRouter(prefix="/dags", tags=["DAG"]) +# Per-dag run counts read at most this many rows per state; the UI shows "N+" at the cap. +STATE_COUNT_CAP = 1000 + @dags_router.get( "", @@ -103,6 +107,7 @@ def get_dags( paused: QueryPausedFilter, has_import_errors: QueryHasImportErrorsFilter, last_dag_run_state: QueryLastDagRunStateFilter, + dag_run_state: QueryAnyDagRunStateFilter, bundle_name: QueryBundleNameFilter, bundle_version: QueryBundleVersionFilter, order_by: Annotated[ @@ -148,6 +153,7 @@ def get_dags( tags, owners, last_dag_run_state, + dag_run_state, is_favorite, has_asset_schedule, asset_dependency, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py index 612d5c7c35c0e..62c51c79d2e4d 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dashboard.py @@ -16,10 +16,11 @@ # under the License. from __future__ import annotations -from typing import cast +from decimal import ROUND_FLOOR, Context +from typing import TYPE_CHECKING, cast from fastapi import Depends, status -from sqlalchemy import func, literal, select, union_all +from sqlalchemy import func, select from sqlalchemy.sql.expression import case, false from airflow._shared.timezones import timezone @@ -38,11 +39,45 @@ from airflow.models.taskinstance import TaskInstance from airflow.utils.state import DagRunState, TaskInstanceState +if TYPE_CHECKING: + from sqlalchemy.orm import Session + dashboard_router = AirflowRouter(tags=["Dashboard"], prefix="/dashboard") -# Cap for state counts — avoids counting millions of rows. -# The UI shows "N+" when the returned count equals this value. -STATE_COUNT_CAP = 1000 +# Rows a single scan reads. Windows that fit are counted exactly; wider ones report a floor. +EXACT_COUNT_LIMIT = 50_000 + + +_ROUNDING = Context(prec=2, rounding=ROUND_FLOOR) + + +def _round_down(value: int) -> int: + """Round to two significant digits, never upwards: that would claim uncounted rows.""" + return int(_ROUNDING.create_decimal(value)) + + +def _compute_state_counts( + model, filters, *, session: Session, join=None, null_label: str | None = None +) -> tuple[dict[str, int], bool]: + """ + Per-state counts for the window, and whether they are lower bounds rather than exact. + + A scan that stopped early counted only some of the rows, but each count is still a floor + on the real value. + """ + stmt = select(model.state.label("state")).select_from(model) + if join is not None: + stmt = stmt.join(join) + window = stmt.where(*filters).limit(EXACT_COUNT_LIMIT + 1).subquery() + rows = session.execute(select(window.c.state, func.count().label("cnt")).group_by(window.c.state)).all() + are_lower_bounds = sum(row.cnt for row in rows) > EXACT_COUNT_LIMIT + counts: dict[str, int] = {} + for row in rows: + label = row.state or null_label + if label is None: + continue + counts[label] = _round_down(row.cnt) if are_lower_bounds else row.cnt + return counts, are_lower_bounds @dashboard_router.get( @@ -70,50 +105,31 @@ def historical_metrics( DagRun.dag_id.in_(permitted_dag_ids), ] - # Build one LIMIT-capped subquery per state, then UNION ALL them into a - # single query. Every state gets the same treatment: at most STATE_COUNT_CAP - # rows are read from the index, so even states with millions of rows - # (typically "success") are counted in single-digit milliseconds. - # Each branch is wrapped in a subquery so LIMIT works on all backends - # (SQLite rejects LIMIT inside bare UNION ALL arms). - def _capped_state_counts(model, states, label_fn, join=None): - branches = [] - for state in states: - stmt = select(literal(label_fn(state)).label("state")).select_from(model) - if join is not None: - stmt = stmt.join(join) - branch = ( - stmt.where(*dag_run_filters) - .where(model.state == state if state else model.state.is_(None)) - .limit(STATE_COUNT_CAP) - .subquery() - ) - branches.append(select(branch.c.state)) - capped = union_all(*branches).subquery() - return session.execute( - select(capped.c.state, func.count().label("cnt")).group_by(capped.c.state) - ).all() - - dag_run_state_counts = _capped_state_counts(DagRun, list(DagRunState), lambda s: s.value) - ti_state_counts = _capped_state_counts( + # Judged separately: dag runs often fit when task instances do not. + dag_run_states, dag_runs_are_lower_bounds = _compute_state_counts( + DagRun, dag_run_filters, session=session + ) + task_instance_states, task_instances_are_lower_bounds = _compute_state_counts( TaskInstance, - [None, *TaskInstanceState], - lambda s: s.value if s else "no_status", + dag_run_filters, + session=session, join=TaskInstance.dag_run, + null_label="no_status", ) return HistoricalMetricDataResponse.model_validate( { "dag_run_states": { **{dag_run_state.value: 0 for dag_run_state in DagRunState}, - **{row.state: row.cnt for row in dag_run_state_counts}, + **dag_run_states, }, "task_instance_states": { "no_status": 0, **{ti_state.value: 0 for ti_state in TaskInstanceState}, - **{row.state: row.cnt for row in ti_state_counts}, + **task_instance_states, }, - "state_count_limit": STATE_COUNT_CAP, + "dag_run_counts_are_lower_bounds": dag_runs_are_lower_bounds, + "task_instance_counts_are_lower_bounds": task_instances_are_lower_bounds, } ) @@ -129,16 +145,6 @@ def dag_stats( """Return basic Dag stats with counts of Dags in various states.""" permitted_dag_ids = cast("set[str]", readable_dags_filter.value) - # Active Dags need another query from DagModel, as a Dag may not have any runs but still be active - active_count_query = ( - select(func.count()) - .select_from(DagModel) - .where(DagModel.is_stale == false()) - .where(DagModel.is_paused == false()) - .where(DagModel.dag_id.in_(permitted_dag_ids)) - ) - active_count = session.execute(active_count_query).scalar_one() - latest_state = ( select(DagRun.state) .where(DagRun.dag_id == DagModel.dag_id, DagRun.logical_date.is_not(None)) @@ -147,26 +153,30 @@ def dag_stats( .correlate(DagModel) .scalar_subquery() ) - latest_runs_subq = ( - select(latest_state.label("state")) + dag_counts_query = ( + select( + func.coalesce(func.sum(case((DagModel.is_paused == false(), 1))), 0).label("active"), + func.coalesce(func.sum(case((latest_state == DagRunState.FAILED, 1))), 0).label("failed"), + ) .select_from(DagModel) .where(DagModel.is_stale == false()) .where(DagModel.dag_id.in_(permitted_dag_ids)) - .subquery() ) - combined_runs_query = select( - func.coalesce(func.sum(case((latest_runs_subq.c.state == DagRunState.FAILED, 1))), 0).label("failed"), - func.coalesce(func.sum(case((latest_runs_subq.c.state == DagRunState.RUNNING, 1))), 0).label( - "running" - ), - func.coalesce(func.sum(case((latest_runs_subq.c.state == DagRunState.QUEUED, 1))), 0).label("queued"), - ).select_from(latest_runs_subq) + dag_counts = session.execute(dag_counts_query).one() - counts = session.execute(combined_runs_query).one() + active_states_query = ( + select(DagRun.state, func.count(func.distinct(DagRun.dag_id))) + .join(DagModel, DagModel.dag_id == DagRun.dag_id) + .where(DagModel.is_stale == false()) + .where(DagRun.dag_id.in_(permitted_dag_ids)) + .where(DagRun.state.in_([DagRunState.RUNNING, DagRunState.QUEUED])) + .group_by(DagRun.state) + ) + active_counts = {state: count for state, count in session.execute(active_states_query)} return DashboardDagStatsResponse( - active_dag_count=active_count, - failed_dag_count=counts.failed, - running_dag_count=counts.running, - queued_dag_count=counts.queued, + active_dag_count=dag_counts.active, + failed_dag_count=dag_counts.failed, + running_dag_count=active_counts.get(DagRunState.RUNNING, 0), + queued_dag_count=active_counts.get(DagRunState.QUEUED, 0), ) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/deadlines.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/deadlines.py index d9cfea10d6d94..4127e98104e80 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/deadlines.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/deadlines.py @@ -41,6 +41,7 @@ ) from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc from airflow.api_fastapi.core_api.security import ReadableDagRunsFilterDep, requires_access_dag +from airflow.models.dag_version import DagVersion from airflow.models.dagrun import DagRun from airflow.models.deadline import Deadline from airflow.models.deadline_alert import DeadlineAlert @@ -129,7 +130,7 @@ def get_deadlines( session=session, ) - deadlines = session.scalars(deadlines_select).unique() + deadlines = session.scalars(deadlines_select) if dag_run_id != "~" and total_entries == 0: dag_run = session.scalar(select(DagRun).where(DagRun.dag_id == dag_id, DagRun.run_id == dag_run_id)) @@ -166,27 +167,36 @@ def get_dag_deadline_alerts( SortParam, Depends( SortParam( - ["id", "created_at", "name", "interval"], + ["id", "created_at", "name"], DeadlineAlert, ).dynamic_depends(default="created_at") ), ], + version_number: int | None = None, ) -> DeadlineAlertCollectionResponse: """Get all deadline alerts defined on a Dag.""" - serialized_dag = session.scalar( - select(SerializedDagModel) + serialized_dag_select = ( + select(SerializedDagModel.id) + .join(DagVersion, SerializedDagModel.dag_version_id == DagVersion.id) .where(SerializedDagModel.dag_id == dag_id) - .order_by(SerializedDagModel.id.desc()) ) + if version_number is None: + serialized_dag_select = serialized_dag_select.order_by(DagVersion.version_number.desc()).limit(1) + not_found_detail = f"Dag with id {dag_id} was not found" + else: + serialized_dag_select = serialized_dag_select.where(DagVersion.version_number == version_number) + not_found_detail = f"Dag with id {dag_id} and version number {version_number} was not found" - if not serialized_dag: + serialized_dag_id = session.scalar(serialized_dag_select) + + if not serialized_dag_id: raise HTTPException( status.HTTP_404_NOT_FOUND, - f"Dag with id {dag_id} was not found", + not_found_detail, ) query = select(DeadlineAlert).where( - DeadlineAlert.serialized_dag_id == serialized_dag.id, + DeadlineAlert.serialized_dag_id == serialized_dag_id, ) alerts_select, total_entries = paginated_select( diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py index 72d92fbef2c2f..d23355f505e9c 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py @@ -65,10 +65,10 @@ task_group_to_dict_grid, ) from airflow.models.dag_version import DagVersion -from airflow.models.dagrun import DagRun +from airflow.models.dagrun import DagRun, DagRunNote from airflow.models.deadline import Deadline from airflow.models.serialized_dag import SerializedDagModel -from airflow.models.taskinstance import TaskInstance +from airflow.models.taskinstance import TaskInstance, TaskInstanceNote from airflow.utils.session import create_session if TYPE_CHECKING: @@ -183,15 +183,27 @@ def get_dag_structure( run_ids = list(session.scalars(dag_runs_select_filter)) task_group_sort = get_task_group_children_getter() + # Built once per render and passed down, intentionally not memoized/LRU-cached: it is a + # derived view of a mutable task-group tree, so a cache would go stale with no invalidation + # and would pin the whole map for the group's lifetime, fighting the streaming/expunge below. + # It is released when the request returns (explicitly del-eted after the latest serdag is + # merged on the main path). + latest_group_dict = latest_dag.task_group.get_task_group_dict() if not run_ids: - nodes = [task_group_to_dict_grid(x) for x in task_group_sort(latest_dag.task_group)] + nodes = [ + task_group_to_dict_grid(x, group_dict=latest_group_dict) + for x in task_group_sort(latest_dag.task_group, latest_group_dict) + ] return [GridNodeResponse(**n) for n in nodes] # Process and merge the latest serdag first merged_nodes: list[dict[str, Any]] = [] - nodes = [task_group_to_dict_grid(x) for x in task_group_sort(latest_dag.task_group)] + nodes = [ + task_group_to_dict_grid(x, group_dict=latest_group_dict) + for x in task_group_sort(latest_dag.task_group, latest_group_dict) + ] _merge_node_dicts(merged_nodes, nodes) - del latest_dag + del latest_dag, latest_group_dict # Process serdags one by one and merge immediately to reduce memory usage. # Use yield_per() for streaming results and expunge each serdag after processing @@ -226,7 +238,11 @@ def get_dag_structure( depth=depth, ) # Merge immediately instead of collecting all Dags in memory - nodes = [task_group_to_dict_grid(x) for x in task_group_sort(filtered_dag.task_group)] + filtered_group_dict = filtered_dag.task_group.get_task_group_dict() + nodes = [ + task_group_to_dict_grid(x, group_dict=filtered_group_dict) + for x in task_group_sort(filtered_dag.task_group, filtered_group_dict) + ] _merge_node_dicts(merged_nodes, nodes) session.expunge(serdag) # to allow garbage collection @@ -291,8 +307,14 @@ def get_grid_runs( .correlate(DagRun) .label("has_missed_deadline") ) + has_note_subq = ( + exists() + .where(DagRunNote.dag_run_id == DagRun.id, DagRunNote.content.isnot(None)) + .correlate(DagRun) + .label("has_note") + ) base_query = ( - select(DagRun, has_missed_deadline) + select(DagRun, has_missed_deadline, has_note_subq) .where(DagRun.dag_id == dag_id) .options( load_only( @@ -328,11 +350,11 @@ def get_grid_runs( limit=limit, return_total_entries=False, ) - results = session.execute(dag_runs_select_filter).unique().all() - dag_runs = [run for run, _ in results] + results = session.execute(dag_runs_select_filter).all() + dag_runs = [run for run, _, _ in results] attach_dag_versions_to_runs(dag_runs, session=session) grid_runs = [] - for run, has_missed in results: + for run, has_missed, has_note in results: grid_runs.append( GridRunsResponse.model_validate( { @@ -346,6 +368,7 @@ def get_grid_runs( "run_type": run.run_type, "dag_versions": run.dag_versions, "has_missed_deadline": has_missed, + "has_note": has_note, } ) ) @@ -373,6 +396,7 @@ def _build_ti_summaries( start_date=ti.start_date, end_date=ti.end_date, dag_version_number=getattr(ti, "version_number", None), + has_note=bool(getattr(ti, "has_note", False)), ) if not ti_details: return None @@ -467,6 +491,13 @@ def _generate() -> Generator[str, None, None]: # database connection open for the entire stream duration. # See https://github.com/apache/airflow/issues/65010. + has_note_subq = ( + exists() + .where(TaskInstanceNote.ti_id == TaskInstance.id, TaskInstanceNote.content.isnot(None)) + .correlate(TaskInstance) + .label("has_note") + ) + for run_id in run_ids or []: with create_session(scoped=False) as session: tis = session.execute( @@ -477,6 +508,7 @@ def _generate() -> Generator[str, None, None]: TaskInstance.start_date, TaskInstance.end_date, DagVersion.version_number, + has_note_subq, ) .outerjoin(DagVersion, TaskInstance.dag_version_id == DagVersion.id) .where(TaskInstance.dag_id == dag_id) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/partitioned_dag_runs.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/partitioned_dag_runs.py index e7f949e92cf73..96ab8c1c38502 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/partitioned_dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/partitioned_dag_runs.py @@ -342,7 +342,7 @@ def get_partitioned_dag_runs( @partitioned_dag_runs_router.get( - "/pending_partitioned_dag_run/{dag_id}/{partition_key}", + "/pending_partitioned_dag_run/{dag_id}", dependencies=[Depends(requires_access_asset(method="GET")), Depends(requires_access_dag(method="GET"))], ) def get_pending_partitioned_dag_run( @@ -351,6 +351,9 @@ def get_pending_partitioned_dag_run( session: SessionDep, ) -> PartitionedDagRunDetailResponse: """Return full details for pending PartitionedDagRun.""" + # partition_key is a query param, not a path segment: it is a free-form key + # (up to 250 chars) that may itself contain "/", which would otherwise be + # ambiguous (or mis-routed) as a path segment. partitioned_dag_run = session.execute( select( AssetPartitionDagRun.id, @@ -366,7 +369,11 @@ def get_pending_partitioned_dag_run( AssetPartitionDagRun.partition_key == partition_key, AssetPartitionDagRun.created_dag_run_id.is_(None), ) - ).one_or_none() + # Duplicate pending rows for the same (dag_id, partition_key) can exist + # after a crash; mirror _get_or_create_apdr and work on the latest one. + .order_by(AssetPartitionDagRun.id.desc()) + .limit(1) + ).first() if partitioned_dag_run is None: raise HTTPException( @@ -440,9 +447,15 @@ def get_pending_partitioned_dag_run( required_keys = [] received_count = 0 required_count = 1 - else: + elif is_rollup: received_count = len(received_keys) required_count = len(required_keys) + else: + # Match the list route's _compute_received_count: a non-rollup asset is + # satisfied by any single received event, so credit caps at 1 even if + # several distinct upstream keys mapped onto this one target key. + required_count = len(required_keys) + received_count = 1 if received_keys else 0 assets.append( PartitionedDagRunAssetResponse( asset_id=asset_row.id, diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/structure.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/structure.py index 597f44db424bb..a5cb9d1d8d188 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/structure.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/structure.py @@ -96,7 +96,11 @@ def structure_data( depth=depth, ) - nodes = [task_group_to_dict(child) for child in dag.task_group.topological_sort()] + group_dict = dag.task_group.get_task_group_dict() + nodes = [ + task_group_to_dict(child, group_dict=group_dict) + for child in dag.task_group.topological_sort(group_dict=group_dict) + ] edges = dag_edges(dag) data = { diff --git a/airflow-core/src/airflow/api_fastapi/core_api/security.py b/airflow-core/src/airflow/api_fastapi/core_api/security.py index 724a6967f7499..f5c86a5d6a9cb 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/security.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/security.py @@ -25,7 +25,9 @@ from fastapi import Depends, HTTPException, Request, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer, OAuth2PasswordBearer +from itsdangerous import BadSignature, URLSafeSerializer from jwt import ExpiredSignatureError, InvalidTokenError +from pydantic import NonNegativeInt, TypeAdapter, ValidationError from sqlalchemy import or_, select from sqlalchemy.orm import Session @@ -198,6 +200,49 @@ def inner( return inner +def requires_access_dag_from_file_token( + method: ResourceMethod, +) -> Callable[[str, Request, BaseUser, Session], None]: + """ + Authorize the caller against the DAGs referenced by a signed ``file_token``. + + For ``file_token`` based endpoints (such as ``reparse``), the token is resolved to its referenced file, and authorization is performed against exactly the DAGs defined in that file, never against a request parameter. + """ + + def inner( + file_token: str, + request: Request, + user: GetUserDep, + session: SessionDep, + ) -> None: + try: + payload = URLSafeSerializer(request.app.state.secret_key).loads(file_token) + except BadSignature: + raise HTTPException(status.HTTP_404_NOT_FOUND, "File not found") + + dag_ids = list( + session.scalars( + select(DagModel.dag_id).where( + DagModel.bundle_name == payload["bundle_name"], + DagModel.relative_fileloc == payload["relative_fileloc"], + ) + ) + ) + if not dag_ids: + raise HTTPException(status.HTTP_404_NOT_FOUND, "File not found") + + dag_id_to_team = DagModel.get_dag_id_to_team_name_mapping(dag_ids, session=session) + requests: list[IsAuthorizedDagRequest] = [ + {"method": method, "details": DagDetails(id=dag_id, team_name=dag_id_to_team.get(dag_id))} + for dag_id in dag_ids + ] + _requires_access( + is_authorized_callback=lambda: get_auth_manager().batch_is_authorized_dag(requests, user=user), + ) + + return inner + + class PermittedDagFilter(OrmClause[set[str]]): """A parameter that filters the permitted dags for the user.""" @@ -313,6 +358,12 @@ def depends_permitted_dags_filter( ] +# The type the backfill routes declare for the `backfill_id` path parameter. Shared with +# `requires_access_backfill` so the authorization decision parses the id exactly as the handler +# does; see the comment there for why any divergence is a cross-Dag authorization bypass. +_BACKFILL_ID_ADAPTER: TypeAdapter[NonNegativeInt] = TypeAdapter(NonNegativeInt) + + def requires_access_backfill( method: ResourceMethod, ) -> Callable[[Request, BaseUser, Session], Coroutine[Any, Any, None]]: @@ -328,8 +379,14 @@ async def inner( # Try to retrieve the dag_id from the backfill_id path param backfill_id_raw = request.path_params.get("backfill_id") try: - backfill_id = int(backfill_id_raw) if backfill_id_raw is not None else None - except ValueError: + # Must parse exactly as the handler does (e.g. pydantic's lax mode coerces "1.0" to 1 + # where int() raises), or the two can authorize and act on different backfills. + backfill_id = ( + _BACKFILL_ID_ADAPTER.validate_python(backfill_id_raw) if backfill_id_raw is not None else None + ) + except ValidationError: + # Rejected by the endpoint's parser too, so the handler cannot run: FastAPI answers + # 422 before it is reached. Left as None, preserving that response. backfill_id = None if backfill_id is not None: @@ -337,6 +394,10 @@ async def inner( dag_id = backfill.dag_id if backfill else None # Try to retrieve the dag_id from the request body (POST backfill) + # TODO: a backfill_id that parses but matches no row also lands here, so an unknown + # backfill is authorized against the body's dag_id and answers 404 where an unauthorized + # one answers 403 - disclosing which ids exist. Not exploitable for a cross-Dag action; + # tracked at https://github.com/apache/airflow/issues/71080 if dag_id is None: # Not a json body, ignore with suppress(JSONDecodeError): @@ -963,12 +1024,13 @@ def is_safe_url(target_url: str, request: Request | None = None) -> bool: # According to WHATWG for http/https /// is interpreted as // whereas urllib doesnt # this leads to an inconsistency where python returns a target url with /// as a valid url - # The same thing also happens with \ where under WHATWG \ are translated to / - target_url = unquote(target_url).strip() - if target_url.startswith(("//", "/\\", "\\/", "\\\\")): + # The same thing also happens with \ where under WHATWG \ are translated to /, including + # after a scheme, so "https:\\host" is an authority for a browser but a path for urllib. + target_url = unquote(target_url).strip().replace("\\", "/") + if target_url.startswith("//"): return False for base_url, parsed_base in parsed_bases: - parsed_target = urlparse(urljoin(base_url, unquote(target_url))) # Resolves relative URLs + parsed_target = urlparse(urljoin(base_url, target_url)) # Resolves relative URLs base_path = parsed_base.path or "/" target_path = parsed_target.path or "/" diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py b/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py index d805827d8d61d..e212a838c4673 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/public/config.py @@ -31,6 +31,11 @@ # (e.g. Vault role_id / secret_id) as the registered ``backend_kwargs`` # option, so they need the same redaction treatment when # ``display_sensitive=False``. +# These match literal section names only, so a team scoped spelling of the same option -- the +# ``[=secrets]`` section, or ``AIRFLOW_____SECRETS__BACKEND_KWARG__*``, which is +# reported under a section named after the team -- is not recognised. Nothing leaks today because +# the secrets backend is not team aware; tracked at +# https://github.com/apache/airflow/issues/71037 _PER_KEY_SENSITIVE_PREFIXES: dict[str, str] = { "secrets": "backend_kwarg__", "workers": "secrets_backend_kwarg__", diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/public/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/services/public/dag_run.py index 6d43d18cd3413..9f5e65501c0f9 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/public/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/public/dag_run.py @@ -57,6 +57,7 @@ ) from airflow.api_fastapi.core_api.datamodels.task_instances import NewTaskResponse from airflow.api_fastapi.core_api.services.public.common import BulkService +from airflow.api_fastapi.core_api.services.public.task_instances import _emit_state_listener_hooks from airflow.listeners.listener import get_listener_manager from airflow.models.dagrun import DagRun, clear_partition_runs from airflow.models.taskinstance import TaskInstance @@ -193,9 +194,17 @@ def patch_dag_run_state( ) -> None: """Set a Dag Run's state (success/queued/failed), firing the matching listener hooks.""" if state == DagRunMutableStates.SUCCESS: - set_dag_run_state_to_success(dag=dag, run_id=dag_run.run_id, commit=True, session=session) + _, killed_tis = set_dag_run_state_to_success( + dag=dag, run_id=dag_run.run_id, commit=True, session=session + ) + _emit_state_listener_hooks(killed_tis, TaskInstanceState.SUCCESS) try: - get_listener_manager().hook.on_dag_run_success(dag_run=dag_run, msg="") + if dag_run.dag is None: + dag_run.dag = dag + get_listener_manager().hook.on_dag_run_success( + dag_run=dag_run, + msg=f"Dag Run's state was manually set to `{DagRunMutableStates.SUCCESS.value}`.", + ) except Exception: log.exception("error calling listener") elif state == DagRunMutableStates.QUEUED: @@ -204,16 +213,26 @@ def patch_dag_run_state( # Not notifying on queued - only notifying on RUNNING, which happens in the scheduler. set_dag_run_state_to_queued(dag=dag, run_id=dag_run.run_id, commit=True, session=session) elif state == DagRunMutableStates.FAILED: - set_dag_run_state_to_failed(dag=dag, run_id=dag_run.run_id, commit=True, session=session) + _, killed_tis = set_dag_run_state_to_failed( + dag=dag, run_id=dag_run.run_id, commit=True, session=session + ) + _emit_state_listener_hooks(killed_tis, TaskInstanceState.FAILED) try: - get_listener_manager().hook.on_dag_run_failed(dag_run=dag_run, msg="") + if dag_run.dag is None: + dag_run.dag = dag + get_listener_manager().hook.on_dag_run_failed( + dag_run=dag_run, + msg=f"Dag Run's state was manually set to `{DagRunMutableStates.FAILED.value}`.", + ) except Exception: log.exception("error calling listener") def patch_dag_run_note(*, dag_run: DagRun, note: str | None, user: BaseUser) -> None: - """Set or update a Dag Run's note.""" - if dag_run.dag_run_note is None: + """Set, update, or clear a Dag Run's note. An empty note removes it so the run is left without a note.""" + if note == "": + dag_run.dag_run_note = None + elif dag_run.dag_run_note is None: dag_run.note = (note, user.get_id()) else: dag_run.dag_run_note.content = note diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/public/task_instances.py b/airflow-core/src/airflow/api_fastapi/core_api/services/public/task_instances.py index a5874035e27f8..b00ba4effdbf6 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/public/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/public/task_instances.py @@ -140,9 +140,7 @@ def _reload_tis_with_rendered_fields(tis: list[TI], session: Session) -> list[TI .options(joinedload(TI.rendered_task_instance_fields)) .where(TI.id.in_([ti.id for ti in tis])) .execution_options(populate_existing=True) - ) - .unique() - .all() + ).all() ) @@ -315,7 +313,9 @@ def _patch_task_instance_note( ) -> None: for ti in tis: if update_mask or task_instance_body.note is not None: - if ti.task_instance_note is None: + if task_instance_body.note == "": + ti.task_instance_note = None + elif ti.task_instance_note is None: ti.note = (task_instance_body.note, user.get_id()) else: ti.task_instance_note.content = task_instance_body.note @@ -468,22 +468,22 @@ def _perform_update( update_mask=update_mask, ) - for key, _ in data.items(): - if key == "new_state": - _patch_task_instance_state( - task_id=task_id, - dag_run_id=dag_run_id, - dag=dag, - task_instance_body=entity, - session=self.session, - data=data, - ) - elif key == "note": - _patch_task_instance_note( - task_instance_body=entity, - tis=tis, - user=self.user, - ) + # Apply "note" before "state" so listeners fired inside _patch_task_instance_state() see the updated note. + if "note" in data: + _patch_task_instance_note( + task_instance_body=entity, + tis=tis, + user=self.user, + ) + if "new_state" in data: + _patch_task_instance_state( + task_id=task_id, + dag_run_id=dag_run_id, + dag=dag, + task_instance_body=entity, + session=self.session, + data=data, + ) results.success.append(f"{dag_id}.{dag_run_id}.{task_id}[{map_index}]") diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/connections.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/connections.py index 75a13a175e488..73519c5271734 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/connections.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/connections.py @@ -153,14 +153,14 @@ def mock_any_of(allowed_values: list) -> HookMetaService.MockEnum: ]: try: if not find_spec(mod_name): - raise ModuleNotFoundError + raise ModuleNotFoundError(f"No module named {mod_name!r}", name=mod_name) except ModuleNotFoundError: sys.modules[mod_name] = MagicMock() # We conditionally inject mock classes for missing dependencies # to ensure `ProvidersManager` can initialize hook connection widgets # without crashing when FAB/WTForms are not installed. - if "wtforms.StringField" not in sys.modules: + if isinstance(sys.modules.get("wtforms"), MagicMock): # Only apply mocks if the actual module wasn't loaded beforehand. # This avoids thread-safety issues caused by `unittest.mock.patch` mutating global states. with ( diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dag_run.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dag_run.py index a9ba75417c87b..2a3ab18325239 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dag_run.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dag_run.py @@ -35,7 +35,9 @@ def compute_duration_stats(durations: list[float]) -> DurationStats | None: if not durations: return None - sorted_d = sorted(durations) + # On Postgres 14+, DagRun.duration comes back as Decimal (EXTRACT(epoch ...) returns + # numeric); coerce to float so the percentile interpolation below (Decimal * float) works. + sorted_d = sorted(float(d) for d in durations) counts = Counter(round(d) for d in sorted_d) max_count = max(counts.values()) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dependencies.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dependencies.py index eb4e8e2091034..20ffc78008a8f 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dependencies.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/dependencies.py @@ -135,6 +135,19 @@ def get_scheduling_dependencies(readable_dag_ids: set[str] | None = None) -> dic target = dep.target if ":" in dep.target else f"dag:{dep.target}" edge_tuples.add((source, target)) + # Create missing ``dag:`` nodes which may have been skipped by the loop above. + # A DAG referenced only as a trigger target or a sensor source may have no + # scheduling dependencies of its own. Without this loop, these DAGs will not be + # materialised and will result in dangling edges. + for source, target in edge_tuples: + for endpoint in (source, target): + if endpoint.startswith("dag:") and endpoint not in nodes_dict: + nodes_dict[endpoint] = { + "id": endpoint, + "label": endpoint.removeprefix("dag:"), + "type": "dag", + } + dag_ids = [node["label"] for node in nodes_dict.values() if node["type"] == "dag"] if dag_ids: dag_id_to_team = DagModel.get_dag_id_to_team_name_mapping(dag_ids) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py index bff2fd6629650..12336b7386a44 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py @@ -43,6 +43,7 @@ class GridNodeAgg: min_start_date: datetime | None = None max_end_date: datetime | None = None dag_version_number: int | None = None + has_note: bool = False def add_ti( self, @@ -51,6 +52,7 @@ def add_ti( start_date: datetime | None, end_date: datetime | None, dag_version_number: int | None, + has_note: bool = False, ) -> None: """Merge one task instance row into the summary.""" self.child_states[state] += 1 @@ -62,6 +64,7 @@ def add_ti( self.dag_version_number is None or dag_version_number > self.dag_version_number ): self.dag_version_number = dag_version_number + self.has_note = self.has_note or has_note def merge(self, other: GridNodeAgg) -> None: """Merge another summary into this one.""" @@ -78,6 +81,7 @@ def merge(self, other: GridNodeAgg) -> None: self.dag_version_number is None or other.dag_version_number > self.dag_version_number ): self.dag_version_number = other.dag_version_number + self.has_note = self.has_note or other.has_note def with_placeholder_state(self) -> GridNodeAgg: """Represent mapped tasks without rows as a single no-status square in the grid.""" @@ -133,6 +137,7 @@ def _get_aggs_for_node(summary: GridNodeAgg) -> dict[str, Any]: "max_end_date": summary.max_end_date, "child_states": _serialize_child_states(summary.child_states), "dag_version_number": summary.dag_version_number, + "has_note": summary.has_note, } @@ -140,6 +145,7 @@ def _find_aggregates( node: SerializedTaskGroup | SerializedBaseOperator | TaskMap, parent_node: SerializedTaskGroup | SerializedBaseOperator | TaskMap | None, ti_details: Mapping[str, GridNodeAgg], + group_dict: dict[str | None, SerializedTaskGroup] | None = None, ) -> Iterable[tuple[dict[str, Any], GridNodeAgg]]: """Recursively fill the Task Group Map.""" node_id = node.node_id @@ -166,10 +172,12 @@ def _find_aggregates( return if isinstance(node, SerializedTaskGroup): + if group_dict is None: + group_dict = node.dag.task_group.get_task_group_dict() children_summary = GridNodeAgg() - for child in get_task_group_children_getter()(node): + for child in get_task_group_children_getter()(node, group_dict): for child_node, child_summary in _find_aggregates( - node=child, parent_node=node, ti_details=ti_details + node=child, parent_node=node, ti_details=ti_details, group_dict=group_dict ): if child_node["parent_id"] == node_id: children_summary.merge(child_summary) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py index 47d49757e69e4..f48af6d6258db 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/task_group.py @@ -19,25 +19,29 @@ from __future__ import annotations -from collections.abc import Callable from functools import cache -from operator import methodcaller +from typing import TYPE_CHECKING from airflow.configuration import conf from airflow.serialization.definitions.baseoperator import SerializedBaseOperator from airflow.serialization.definitions.mappedoperator import SerializedMappedOperator, is_mapped +if TYPE_CHECKING: + from collections.abc import Callable + from typing import Any + + from airflow.serialization.definitions.taskgroup import SerializedTaskGroup + @cache def get_task_group_children_getter() -> Callable: """Get the Task Group Children Getter for the Dag.""" - sort_order = conf.get("api", "grid_view_sorting_order") - if sort_order == "topological": - return methodcaller("topological_sort") - return methodcaller("hierarchical_alphabetical_sort") + if conf.get("api", "grid_view_sorting_order") == "topological": + return lambda task_group, group_dict=None: task_group.topological_sort(group_dict=group_dict) + return lambda task_group, group_dict=None: task_group.hierarchical_alphabetical_sort() -def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): +def task_group_to_dict(task_item_or_group, *, group_dict=None, parent_group_is_mapped=False): """Create a nested dict representation of this TaskGroup and its children used to construct the Graph.""" if isinstance(task := task_item_or_group, (SerializedBaseOperator, SerializedMappedOperator)): # we explicitly want the short task ID here, not the full doted notation if in a group @@ -57,10 +61,16 @@ def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): return node_operator task_group = task_item_or_group + if group_dict is None: + group_dict = task_group.dag.task_group.get_task_group_dict() mapped = is_mapped(task_group) children = [ - task_group_to_dict(child, parent_group_is_mapped=parent_group_is_mapped or mapped) - for child in get_task_group_children_getter()(task_group) + task_group_to_dict( + child, + parent_group_is_mapped=parent_group_is_mapped or mapped, + group_dict=group_dict, + ) + for child in get_task_group_children_getter()(task_group, group_dict) ] if task_group.upstream_group_ids or task_group.upstream_task_ids: @@ -82,8 +92,22 @@ def task_group_to_dict(task_item_or_group, parent_group_is_mapped=False): return node -def task_group_to_dict_grid(task_item_or_group, parent_group_is_mapped=False): - """Create a nested dict representation of this TaskGroup and its children used to construct the Grid.""" +def task_group_to_dict_grid( + task_item_or_group, + *, + group_dict: dict[str | None, SerializedTaskGroup] | None = None, + parent_group_is_mapped: bool = False, +) -> dict[str, Any]: + """ + Create a nested dict representation of this TaskGroup and its children used to construct the Grid. + + :param group_dict: A ``{group_id: group}`` map used to resolve cross-group + dependencies. Built once at the top of a render and threaded through the + recursion so nested groups reuse it. + :param parent_group_is_mapped: Whether an ancestor task group is mapped, propagated to children. + """ + node: dict[str, Any] + if isinstance(task := task_item_or_group, (SerializedMappedOperator, SerializedBaseOperator)): mapped = None if parent_group_is_mapped or is_mapped(task): @@ -105,11 +129,17 @@ def task_group_to_dict_grid(task_item_or_group, parent_group_is_mapped=False): return node task_group = task_item_or_group + if group_dict is None: + group_dict = task_group.dag.task_group.get_task_group_dict() task_group_sort = get_task_group_children_getter() mapped = is_mapped(task_group) children = [ - task_group_to_dict_grid(x, parent_group_is_mapped=parent_group_is_mapped or mapped) - for x in task_group_sort(task_group) + task_group_to_dict_grid( + child, + group_dict=group_dict, + parent_group_is_mapped=parent_group_is_mapped or mapped, + ) + for child in task_group_sort(task_group, group_dict) ] node = { diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/AGENTS.md b/airflow-core/src/airflow/api_fastapi/execution_api/AGENTS.md index aff91c070d9ef..4cacd2368baf0 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/AGENTS.md +++ b/airflow-core/src/airflow/api_fastapi/execution_api/AGENTS.md @@ -16,7 +16,7 @@ Workers and API servers deploy independently, so backward compatibility is criti 3. Regenerate Task SDK models: ```bash -cd task-sdk && python dev/generate_task_sdk_models.py +uv run --active --group codegen --project apache-airflow-task-sdk --directory task-sdk -s dev/generate_task_sdk_models.py ``` 4. Add tests for both the new and previous API versions. @@ -44,7 +44,7 @@ Adding a new Execution API feature touches multiple packages. All of these must 5. **Task SDK client** — add the client method in `task-sdk/src/airflow/sdk/api/client.py`. 6. **Supervisor** — handle the new message in `task-sdk/src/airflow/sdk/execution_time/supervisor.py`. 7. **Dag processor & triggerer exclusions** — these use `InProcessExecutionAPI` and have explicit message type unions. Add new types to their handler or exclusion lists in `airflow/dag_processing/processor.py` and `airflow/jobs/triggerer_job_runner.py`. -8. **Regenerate models** — `cd task-sdk && python dev/generate_task_sdk_models.py`. +8. **Regenerate models** — `uv run --active --group codegen --project apache-airflow-task-sdk --directory task-sdk -s dev/generate_task_sdk_models.py`. 9. **Tests** — if the new message type requires an API endpoint, add tests in all of these: - `airflow-core/tests/unit/api_fastapi/execution_api/` — endpoint tests - `task-sdk/tests/task_sdk/api/test_client.py` — client method tests diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/app.py b/airflow-core/src/airflow/api_fastapi/execution_api/app.py index 5a87cdb81e04c..f9e7cb1725000 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/app.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/app.py @@ -287,6 +287,7 @@ def _inject_trace_context_dep(routes, mode: str) -> None: def create_task_execution_api_app(lifespan: svcs.fastapi.lifespan = lifespan) -> FastAPI: """Create FastAPI app for task execution API.""" + from airflow.api_fastapi.common.exceptions import init_error_handlers from airflow.api_fastapi.execution_api.routes import execution_api_router from airflow.api_fastapi.execution_api.versions import bundle from airflow.configuration import conf @@ -314,6 +315,7 @@ def custom_generate_unique_id(route: APIRoute): _inject_trace_context_dep(execution_api_router.routes, mode) app.generate_and_include_versioned_routers(execution_api_router) + init_error_handlers(app) # As we are mounted as a sub app, we don't get any logs for unhandled exceptions without this! @app.exception_handler(Exception) diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/dag_runs.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/dag_runs.py index 31aeb96c63e72..00a9ab37f256e 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/dag_runs.py @@ -163,6 +163,14 @@ def trigger_dag_run( status.HTTP_400_BAD_REQUEST, detail={"reason": "invalid_partition_key", "message": str(e)}, ) from e + except ValueError as e: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + detail={ + "reason": "value_error", + "message": str(e), + }, + ) from e @router.post( diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py index 802b09502e09b..74cda44efe74c 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/hitl.py @@ -131,7 +131,6 @@ def update_hitl_detail( hitl_detail_model.chosen_options = payload.chosen_options hitl_detail_model.params_input = payload.params_input session.add(hitl_detail_model) - session.commit() return HITLDetailResponse.from_hitl_detail_orm(hitl_detail_model) diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py index 3b142a4e6b1b7..41ecf49b053fb 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py @@ -21,8 +21,8 @@ import itertools import json from collections import defaultdict -from collections.abc import Iterator -from typing import TYPE_CHECKING, Annotated, Any, cast +from collections.abc import Callable, Iterator, Sequence +from typing import TYPE_CHECKING, Annotated, Any, NoReturn, cast from uuid import UUID import attrs @@ -319,10 +319,8 @@ def ti_run( # Let the app-level DataErrorHandler return a 422 (not the opaque 500 below). raise except SQLAlchemyError: - log.exception("Error marking Task Instance state as running") - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database error occurred" - ) + # Defer to app-level SQLAlchemyError handler (returns HTTP 500). + raise # JWTReissueMiddleware also writes Refreshed-API-Token but skips workload tokens, so we set it here for the workload→execution swap. if token.claims.scope == "workload": @@ -452,8 +450,9 @@ def ti_update_state( data["_rendered_map_index"] = data.pop("rendered_map_index") query = update(TI).where(TI.id == task_instance_id).values(data) + asset_callbacks: Sequence[Callable[[], None]] = () try: - query, updated_state = _create_ti_state_update_query_and_update_state( + query, updated_state, asset_callbacks = _create_ti_state_update_query_and_update_state( ti_patch_payload=ti_patch_payload, task_instance_id=task_instance_id, session=session, @@ -470,6 +469,7 @@ def ti_update_state( "Error updating Task Instance state. Setting the task to failed.", payload=ti_patch_payload, ) + session.rollback() ti = session.get(TI, task_instance_id, with_for_update={"of": TI}) if session.bind is not None: query = TI.duration_expression_update(timezone.utcnow(), query, session.bind) @@ -502,11 +502,9 @@ def ti_update_state( except DataError: # Let DataErrorHandler return a 422 (not the opaque 500 below). raise - except SQLAlchemyError as e: - log.error("Error updating Task Instance state", error=str(e)) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database error occurred" - ) + except SQLAlchemyError: + # Defer to app-level SQLAlchemyError handler (returns HTTP 500). + raise if updated_state == TaskInstanceState.SUCCESS: if conf.getboolean("state_store", "clear_on_success"): @@ -533,6 +531,12 @@ def ti_update_state( task_id=task_id, ) + # Release the task_instance row lock before running listener callbacks. + session.commit() + + for callback in asset_callbacks: + callback() + def _emit_task_span(ti, state): # just to be safe @@ -630,7 +634,8 @@ def _create_ti_state_update_query_and_update_state( session: SessionDep, dag_bag: DagBagDep, dag_id: str, -) -> tuple[Update, TaskInstanceState]: +) -> tuple[Update, TaskInstanceState, Sequence[Callable[[], None]]]: + asset_callbacks: Sequence[Callable[[], None]] = () if isinstance(ti_patch_payload, (TITerminalStatePayload, TIRetryStatePayload, TISuccessStatePayload)): ti = session.get(TI, task_instance_id, with_for_update={"of": TI}) updated_state = TaskInstanceState(ti_patch_payload.state.value) @@ -643,24 +648,25 @@ def _create_ti_state_update_query_and_update_state( if ti is not None: _handle_fail_fast_for_dag(ti=ti, dag_id=dag_id, session=session, dag_bag=dag_bag) elif isinstance(ti_patch_payload, TIRetryStatePayload): + retry_delay_override = ti_patch_payload.retry_delay_seconds + retry_reason = ti_patch_payload.retry_reason[:500] if ti_patch_payload.retry_reason else None if ti is not None: - # Set the overrides on the TI *before* archiving so record_ti() - # snapshots them into task_instance_history (it copies attrs off - # the ti object). Otherwise the per-try audit trail is always NULL. - ti.retry_delay_override = ti_patch_payload.retry_delay_seconds - ti.retry_reason = ( - ti_patch_payload.retry_reason[:500] if ti_patch_payload.retry_reason else None - ) + # Snapshot the finished try onto the TI *before* archiving so record_ti() + # copies the values into task_instance_history (it reads attrs off the + # ti object and cannot see the live-row UPDATE built below). + ti.retry_delay_override = retry_delay_override + ti.retry_reason = retry_reason + ti.end_date = ti_patch_payload.end_date + ti.set_duration() + if "rendered_map_index" in ti_patch_payload.model_fields_set: + ti._rendered_map_index = ti_patch_payload.rendered_map_index ti.prepare_db_for_next_try(session=session) # Store retry policy overrides so next_retry_datetime() can read them. # These are cleared when the task enters RUNNING (ti_run). - query = query.values( - retry_delay_override=ti_patch_payload.retry_delay_seconds, - retry_reason=(ti_patch_payload.retry_reason[:500] if ti_patch_payload.retry_reason else None), - ) + query = query.values(retry_delay_override=retry_delay_override, retry_reason=retry_reason) elif isinstance(ti_patch_payload, TISuccessStatePayload): if ti is not None: - TI.register_asset_changes_in_db( + asset_callbacks = TI.register_asset_changes_in_db( ti, ti_patch_payload.task_outlets, ti_patch_payload.outlet_events, @@ -771,7 +777,7 @@ def _create_ti_state_update_query_and_update_state( ti = session.get(TI, task_instance_id, with_for_update={"of": TI}) if ti is not None: _handle_fail_fast_for_dag(ti=ti, dag_id=dag_id, session=session, dag_bag=dag_bag) - return query, TaskInstanceState.FAILED + return query, TaskInstanceState.FAILED, () actual_start_date = timezone.utcnow() session.add( @@ -793,7 +799,7 @@ def _create_ti_state_update_query_and_update_state( else: raise ValueError(f"Unexpected Payload Type {type(ti_patch_payload)}") - return query, updated_state + return query, updated_state, asset_callbacks @ti_id_router.patch( @@ -859,6 +865,29 @@ def ti_skip_downstream( log.info("Downstream tasks skipped", tasks_skipped=getattr(result, "rowcount", 0)) +def _raise_ti_not_in_live_table(task_instance_id: UUID, session: SessionDep) -> NoReturn: + """Raise 410 Gone if the missing TI id was archived to history, else 404 Not Found.""" + if session.scalar( + select(func.count(TIH.task_instance_id)).where(TIH.task_instance_id == task_instance_id) + ): + log.error("TaskInstance not in live table but archived in history", ti_id=str(task_instance_id)) + raise HTTPException( + status_code=status.HTTP_410_GONE, + detail={ + "reason": "not_found", + "message": "Task Instance not found, it may have been moved to the Task Instance History table", + }, + ) + log.error("Task Instance not found", ti_id=str(task_instance_id)) + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail={ + "reason": "not_found", + "message": "Task Instance not found", + }, + ) + + @ti_id_router.put( "/{task_instance_id}/heartbeat", status_code=status.HTTP_204_NO_CONTENT, @@ -919,29 +948,7 @@ def ti_heartbeat( # Check if the TI exists in the Task Instance History table. # If it does, it was likely cleared while running, so return 410 Gone # instead of 404 Not Found to give the client a more specific signal. - tih_exists = session.scalar( - select(func.count(TIH.task_instance_id)).where(TIH.task_instance_id == task_instance_id) - ) - if tih_exists: - log.error( - "TaskInstance was previously cleared and archived in history, heartbeat skipped", - ti_id=str(task_instance_id), - ) - raise HTTPException( - status_code=status.HTTP_410_GONE, - detail={ - "reason": "not_found", - "message": "Task Instance not found, it may have been moved to the Task Instance History table", - }, - ) - log.error("Task Instance not found") - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail={ - "reason": "not_found", - "message": "Task Instance not found", - }, - ) + _raise_ti_not_in_live_table(task_instance_id, session) if hostname != ti_payload.hostname or pid != ti_payload.pid: log.warning( @@ -988,6 +995,10 @@ def ti_heartbeat( responses=create_openapi_http_exception_doc( [ (status.HTTP_404_NOT_FOUND, "Task Instance not found"), + ( + status.HTTP_410_GONE, + "Task Instance not found in the TI table but exists in the Task Instance History table", + ), ( HTTP_422_UNPROCESSABLE_CONTENT, "Invalid payload for the setting rendered task instance fields", @@ -1006,10 +1017,8 @@ def ti_put_rtif( task_instance = session.scalar(select(TI).where(TI.id == task_instance_id)) if not task_instance: - log.error("Task Instance not found") - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - ) + # On retry/clear, the server regenerates the TI id. Return 410 for the stale id. + _raise_ti_not_in_live_table(task_instance_id, session) task_instance.update_rtif(put_rtif_payload, session=session) log.debug("RenderedTaskInstanceFields updated successfully") diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_state_store.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_state_store.py index 624926fe639eb..e1dfe7fcd978e 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_state_store.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_state_store.py @@ -58,7 +58,7 @@ def _get_task_scope_for_ti(task_instance_id: UUID, session: Session) -> TaskScop return TaskScope(dag_id=ti.dag_id, run_id=ti.run_id, task_id=ti.task_id, map_index=ti.map_index) -@router.get("/{task_instance_id}/{key}") +@router.get("/{task_instance_id}/{key:path}") def get_task_state_store( task_instance_id: UUID, key: Annotated[str, Path(min_length=1)], @@ -78,7 +78,7 @@ def get_task_state_store( return TaskStateStoreResponse(value=json.loads(value)) -@router.put("/{task_instance_id}/{key}", status_code=status.HTTP_204_NO_CONTENT) +@router.put("/{task_instance_id}/{key:path}", status_code=status.HTTP_204_NO_CONTENT) def set_task_state_store( task_instance_id: UUID, key: Annotated[str, Path(min_length=1)], @@ -90,7 +90,7 @@ def set_task_state_store( get_state_backend().set(scope, key, json.dumps(body.value), expires_at=body.expires_at, session=session) -@router.delete("/{task_instance_id}/{key}", status_code=status.HTTP_204_NO_CONTENT) +@router.delete("/{task_instance_id}/{key:path}", status_code=status.HTTP_204_NO_CONTENT) def delete_task_state_store( task_instance_id: UUID, key: Annotated[str, Path(min_length=1)], diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py index 9ab8eb200712a..0cb6ccb23ce54 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py @@ -481,5 +481,4 @@ def delete_xcom( XComModel.map_index == map_index, ) session.execute(query) - session.commit() return {"message": f"XCom with key: {key} successfully deleted."} diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/versions/v2026_06_30.py b/airflow-core/src/airflow/api_fastapi/execution_api/versions/v2026_06_30.py index e89e2ed04cc5d..930bd1426a407 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/versions/v2026_06_30.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/versions/v2026_06_30.py @@ -114,9 +114,9 @@ class AddTaskAndAssetStateStoreEndpoints(VersionChange): description = __doc__ instructions_to_migrate_to_previous_version = ( - endpoint("/store/ti/{task_instance_id}/{key}", ["GET"]).didnt_exist, - endpoint("/store/ti/{task_instance_id}/{key}", ["PUT"]).didnt_exist, - endpoint("/store/ti/{task_instance_id}/{key}", ["DELETE"]).didnt_exist, + endpoint("/store/ti/{task_instance_id}/{key:path}", ["GET"]).didnt_exist, + endpoint("/store/ti/{task_instance_id}/{key:path}", ["PUT"]).didnt_exist, + endpoint("/store/ti/{task_instance_id}/{key:path}", ["DELETE"]).didnt_exist, endpoint("/store/ti/{task_instance_id}", ["DELETE"]).didnt_exist, endpoint("/store/asset/by-name/value", ["GET"]).didnt_exist, endpoint("/store/asset/by-name/value", ["PUT"]).didnt_exist, diff --git a/airflow-core/src/airflow/api_fastapi/logging/decorators.py b/airflow-core/src/airflow/api_fastapi/logging/decorators.py index f32a2bffc707f..71942cafe41b2 100644 --- a/airflow-core/src/airflow/api_fastapi/logging/decorators.py +++ b/airflow-core/src/airflow/api_fastapi/logging/decorators.py @@ -45,8 +45,51 @@ def _sanitize_for_stdlib_log(value: str) -> str: return value.replace("\r", " ").replace("\n", " ") +def _mask_bulk_entities(extra_fields, mask_entity): + """ + Apply per-entity masking to a bulk request body. + + A ``BulkBody`` has exactly one top-level field, ``actions``; the entities carrying the + secrets sit two levels down, in ``actions[].entities[]``. The per-entity maskers below + inspect top-level key names, so handing them a bulk body means they see only the key + ``actions`` and pass its whole payload through untouched. Reach the entities first. + + Returns ``None`` when the body is not bulk-shaped, so callers fall back to flat masking. + """ + actions = extra_fields.get("actions") + if not isinstance(actions, list): + return None + + masked_actions = [] + for action in actions: + if not isinstance(action, dict): + masked_actions.append(action) + continue + entities = action.get("entities") + if not isinstance(entities, list): + masked_actions.append(action) + continue + # ``delete`` actions may list bare id/key strings rather than entity objects; + # those carry no secret and are left as they are. + masked_actions.append( + { + **action, + "entities": [mask_entity(e) if isinstance(e, dict) else e for e in entities], + } + ) + return {**extra_fields, "actions": masked_actions} + + def _mask_connection_fields(extra_fields): - """Mask connection fields.""" + """Mask connection fields, for either a single-entity or a bulk request body.""" + bulk = _mask_bulk_entities(extra_fields, _mask_connection_entity) + if bulk is not None: + return bulk + return _mask_connection_entity(extra_fields) + + +def _mask_connection_entity(extra_fields): + """Mask the fields of one connection.""" result = {} for k, v in extra_fields.items(): if k == "extra" and v: @@ -59,7 +102,11 @@ def _mask_connection_fields(extra_fields): result[k] = {ek: "***" for ek in parsed_extra} else: result[k] = "Expected JSON object in `extra` field, got non-dict JSON" - except json.JSONDecodeError: + except (json.JSONDecodeError, TypeError): + # ``extra`` is declared as a string, but this runs on the raw body before + # validation, so it can arrive as any JSON type -- a number or an already-decoded + # object makes ``json.loads`` raise TypeError rather than JSONDecodeError. Both + # are recorded without the value, instead of raising out of the audit-log path. result[k] = "Encountered non-JSON in `extra` field" else: result[k] = secrets_masker.redact(v, k) @@ -67,6 +114,14 @@ def _mask_connection_fields(extra_fields): def _mask_variable_fields(extra_fields): + """Mask variable values, for either a single-entity or a bulk request body.""" + bulk = _mask_bulk_entities(extra_fields, _mask_variable_entity) + if bulk is not None: + return bulk + return _mask_variable_entity(extra_fields) + + +def _mask_variable_entity(extra_fields): """ Mask the variable value. diff --git a/airflow-core/src/airflow/assets/manager.py b/airflow-core/src/airflow/assets/manager.py index c3491574e9148..0c7fa50d5af97 100644 --- a/airflow-core/src/airflow/assets/manager.py +++ b/airflow-core/src/airflow/assets/manager.py @@ -17,12 +17,13 @@ # under the License. from __future__ import annotations -from collections.abc import Collection, Iterable +from collections.abc import Callable, Collection, Iterable from contextlib import contextmanager +from functools import partial from typing import TYPE_CHECKING import structlog -from sqlalchemy import exc, or_, select +from sqlalchemy import exc, insert, or_, select from sqlalchemy.orm import joinedload from airflow._shared.observability.metrics import stats @@ -41,6 +42,7 @@ DagScheduleAssetUriReference, PartitionedAssetKeyLog, TaskOutletAssetReference, + asset_alias_asset_event_association_table, ) from airflow.models.log import Log from airflow.timetables.base import compute_rollup_fingerprint @@ -281,6 +283,7 @@ def register_asset_change( api_user_teams: set[str] | None = None, api_allow_consumer_teams: list[str] | None = None, api_allow_global_consumers: bool = True, + callback_sink: list[Callable[[], None]] | None = None, **kwargs, ) -> AssetEvent | None: """ @@ -306,6 +309,8 @@ def register_asset_change( Only used when source_is_api=True. :param api_allow_global_consumers: Whether teamless consumers are allowed for an API-triggered event. Only used when source_is_api=True. Defaults to True. + :param callback_sink: If specified, registration callbacks are added + into the list instead of executed inline. """ from airflow.models.dag import DagModel @@ -350,17 +355,26 @@ def register_asset_change( dags_to_queue_from_asset_alias = set() if source_alias_names: - asset_alias_models: Iterable[AssetAliasModel] = session.scalars( - select(AssetAliasModel) - .where(AssetAliasModel.name.in_(source_alias_names)) - .options( - joinedload(AssetAliasModel.scheduled_dags).joinedload(DagScheduleAssetAliasReference.dag) + asset_alias_models = ( + session.scalars( + select(AssetAliasModel) + .where(AssetAliasModel.name.in_(source_alias_names)) + .options( + joinedload(AssetAliasModel.scheduled_dags).joinedload( + DagScheduleAssetAliasReference.dag + ) + ) ) - ).unique() + .unique() + .all() + ) for asset_alias_model in asset_alias_models: - asset_alias_model.asset_events.append(asset_event) - session.add(asset_alias_model) + session.execute( + insert(asset_alias_asset_event_association_table).values( + alias_id=asset_alias_model.id, event_id=asset_event.id + ) + ) dags_to_queue_from_asset_alias |= { alias_ref.dag @@ -386,20 +400,23 @@ def register_asset_change( ) asset = asset_model.to_serialized() - cls.notify_asset_changed(asset=asset) - cls.nofity_asset_event_emitted( - asset_event=ListenerAssetEvent( - asset=asset, - extra=asset_event.extra, - source_dag_id=asset_event.source_dag_id, - source_task_id=asset_event.source_task_id, - source_run_id=asset_event.source_run_id, - source_map_index=asset_event.source_map_index, - source_aliases=[aam.to_serialized() for aam in asset_alias_models], - partition_key=partition_key, - partition_date=partition_date, - ) + listener_asset_event = ListenerAssetEvent( + asset=asset, + extra=asset_event.extra, + source_dag_id=asset_event.source_dag_id, + source_task_id=asset_event.source_task_id, + source_run_id=asset_event.source_run_id, + source_map_index=asset_event.source_map_index, + source_aliases=[aam.to_serialized() for aam in asset_alias_models], + partition_key=partition_key, + partition_date=partition_date, ) + if callback_sink is None: + cls.notify_asset_changed(asset=asset) + cls.nofity_asset_event_emitted(asset_event=listener_asset_event) + else: + callback_sink.append(partial(cls.notify_asset_changed, asset=asset)) + callback_sink.append(partial(cls.nofity_asset_event_emitted, asset_event=listener_asset_event)) team_name = None if task_instance and conf.getboolean("core", "multi_team"): diff --git a/airflow-core/src/airflow/cli/commands/backfill_command.py b/airflow-core/src/airflow/cli/commands/backfill_command.py index d76d435a391a4..75ba6b03ce4af 100644 --- a/airflow-core/src/airflow/cli/commands/backfill_command.py +++ b/airflow-core/src/airflow/cli/commands/backfill_command.py @@ -27,7 +27,7 @@ from airflow.api_fastapi.common.dagbag import resolve_run_on_latest_version from airflow.cli.simple_table import AirflowConsole from airflow.exceptions import AirflowConfigException -from airflow.models.backfill import ReprocessBehavior, _create_backfill, _do_dry_run +from airflow.models.backfill import NoBackfillRunsToCreate, ReprocessBehavior, _create_backfill, _do_dry_run from airflow.utils import cli as cli_utils from airflow.utils.cli import sigint_handler from airflow.utils.platform import getuser @@ -50,6 +50,13 @@ def create_backfill(args) -> None: else: reprocess_behavior = None + dag_run_conf = None + if args.dag_run_conf: + try: + dag_run_conf = json.loads(args.dag_run_conf) + except json.JSONDecodeError as e: + raise ValueError(f"Invalid JSON in --dag-run-conf: {e}") + with create_session() as session: resolved_run_on_latest = resolve_run_on_latest_version( args.run_on_latest_version, @@ -67,7 +74,7 @@ def create_backfill(args) -> None: to_date=args.to_date, max_active_runs=args.max_active_runs, reverse=args.run_backwards, - dag_run_conf=args.dag_run_conf, + dag_run_conf=dag_run_conf, reprocess_behavior=reprocess_behavior, run_on_latest_version=resolved_run_on_latest, ) @@ -79,7 +86,8 @@ def create_backfill(args) -> None: from_date=args.from_date, to_date=args.to_date, reverse=args.run_backwards, - reprocess_behavior=args.reprocess_behavior, + reprocess_behavior=reprocess_behavior or ReprocessBehavior.NONE, + dag_run_conf=dag_run_conf, session=session, ) console.print("Runs to be attempted:") @@ -97,22 +105,18 @@ def create_backfill(args) -> None: log.warning("Failed to get user name from os: %s, not setting the triggering user", e) user = None - # Parse dag_run_conf if provided - dag_run_conf = None - if args.dag_run_conf: - try: - dag_run_conf = json.loads(args.dag_run_conf) - except json.JSONDecodeError as e: - raise ValueError(f"Invalid JSON in --dag-run-conf: {e}") - - _create_backfill( - dag_id=args.dag_id, - from_date=args.from_date, - to_date=args.to_date, - max_active_runs=args.max_active_runs, - reverse=args.run_backwards, - dag_run_conf=dag_run_conf, - triggering_user_name=user, - reprocess_behavior=reprocess_behavior, - run_on_latest_version=resolved_run_on_latest, - ) + try: + _create_backfill( + dag_id=args.dag_id, + from_date=args.from_date, + to_date=args.to_date, + max_active_runs=args.max_active_runs, + reverse=args.run_backwards, + dag_run_conf=dag_run_conf, + triggering_user_name=user, + reprocess_behavior=reprocess_behavior, + run_on_latest_version=resolved_run_on_latest, + ) + except NoBackfillRunsToCreate as e: + console.print(f"[yellow]Warning:[/yellow] {e}") + raise SystemExit(1) diff --git a/airflow-core/src/airflow/cli/commands/config_command.py b/airflow-core/src/airflow/cli/commands/config_command.py index 21f1dcfc4a9fa..5f087fdfa4c8b 100644 --- a/airflow-core/src/airflow/cli/commands/config_command.py +++ b/airflow-core/src/airflow/cli/commands/config_command.py @@ -28,6 +28,7 @@ from pygments.lexers.configs import IniLexer from airflow.cli.simple_table import AirflowConsole +from airflow.cli.utils import deprecated_for_airflowctl from airflow.configuration import AIRFLOW_CONFIG, ConfigModifications, conf from airflow.exceptions import AirflowConfigException from airflow.utils.cli import should_use_colors @@ -35,6 +36,7 @@ from airflow.utils.providers_configuration_loader import providers_configuration_loaded +@deprecated_for_airflowctl("airflowctl config list") @providers_configuration_loaded def show_config(args): """Show current application configuration.""" @@ -63,6 +65,7 @@ def show_config(args): print(code) +@deprecated_for_airflowctl("airflowctl config get") @providers_configuration_loaded def get_value(args): """Get one value from configuration.""" @@ -1013,13 +1016,12 @@ def update_config(args) -> None: continue conf_section = change.config.section.lower() conf_option = change.config.option.lower() - full_key = f"{conf_section}.{conf_option}" if update_sections_lower is not None and conf_section not in update_sections_lower: continue - if update_options_lower is not None and full_key not in update_options_lower: + if update_options_lower is not None and conf_option not in update_options_lower: continue - if conf_section in ignore_sections_lower or full_key in ignore_options_lower: + if conf_section in ignore_sections_lower or conf_option in ignore_options_lower: continue if conf_section not in config_dict or conf_option not in config_dict[conf_section]: diff --git a/airflow-core/src/airflow/cli/commands/connection_command.py b/airflow-core/src/airflow/cli/commands/connection_command.py index 8911bc80b99e2..ce87af7a9c374 100644 --- a/airflow-core/src/airflow/cli/commands/connection_command.py +++ b/airflow-core/src/airflow/cli/commands/connection_command.py @@ -30,7 +30,12 @@ from sqlalchemy.orm import exc from airflow.cli.simple_table import AirflowConsole -from airflow.cli.utils import SENSITIVE_PLACEHOLDER, is_stdout, print_export_output +from airflow.cli.utils import ( + SENSITIVE_PLACEHOLDER, + deprecated_for_airflowctl, + is_stdout, + print_export_output, +) from airflow.configuration import conf from airflow.exceptions import AirflowNotFoundException from airflow.models import Connection @@ -140,6 +145,7 @@ def connections_get(args): ) +@deprecated_for_airflowctl("airflowctl connections list") @suppress_logs_and_warning @providers_configuration_loaded def connections_list(args): @@ -186,6 +192,7 @@ def _connection_to_dict(conn: Connection) -> dict: } +@deprecated_for_airflowctl("airflowctl connections create-defaults") def create_default_connections(args): db_create_default_connections() @@ -283,6 +290,7 @@ def connections_export(args): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl connections create") @providers_configuration_loaded def connections_add(args): """Add new connection.""" @@ -379,6 +387,7 @@ def connections_add(args): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl connections delete") @providers_configuration_loaded def connections_delete(args): """Delete connection from DB.""" @@ -395,6 +404,7 @@ def connections_delete(args): @cli_utils.action_cli(check_db=False) +@deprecated_for_airflowctl("airflowctl connections import") @providers_configuration_loaded def connections_import(args): """Import connections from a file.""" @@ -433,6 +443,7 @@ def _import_helper(file_path: str, overwrite: bool) -> None: print(f"Imported connection {conn_id}") +@deprecated_for_airflowctl("airflowctl connections test") @suppress_logs_and_warning @providers_configuration_loaded def connections_test(args) -> None: diff --git a/airflow-core/src/airflow/cli/commands/dag_command.py b/airflow-core/src/airflow/cli/commands/dag_command.py index 756048af14d5e..b6688643c5d29 100644 --- a/airflow-core/src/airflow/cli/commands/dag_command.py +++ b/airflow-core/src/airflow/cli/commands/dag_command.py @@ -241,6 +241,7 @@ def _bulk_clear_runs( @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl dags pause") @providers_configuration_loaded def dag_pause(args) -> None: """Pauses a DAG.""" @@ -248,6 +249,7 @@ def dag_pause(args) -> None: @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl dags unpause") @providers_configuration_loaded def dag_unpause(args) -> None: """Unpauses a DAG.""" @@ -406,6 +408,7 @@ def _get_dagbag_dag_details(dag: DAG) -> dict: } +@deprecated_for_airflowctl("airflowctl dags state") @cli_utils.action_cli @providers_configuration_loaded @provide_session @@ -435,6 +438,7 @@ def dag_state(args, *, session: Session = NEW_SESSION) -> None: print(dr.state) +@deprecated_for_airflowctl("airflowctl dags next-execution") @cli_utils.action_cli @providers_configuration_loaded def dag_next_execution(args) -> None: @@ -526,6 +530,7 @@ def iter_next_dagrun_info() -> Iterator[DagRunInfo | None]: print(value) +@deprecated_for_airflowctl("airflowctl dags list") @cli_utils.action_cli @suppress_logs_and_warning @providers_configuration_loaded @@ -614,6 +619,7 @@ def filter_dags_by_bundle(dags: Iterable[DAG], bundle_names: list[str] | None) - ) +@deprecated_for_airflowctl("airflowctl dags get-details") @cli_utils.action_cli @suppress_logs_and_warning @providers_configuration_loaded @@ -637,6 +643,7 @@ def dag_details(args, *, session: Session = NEW_SESSION): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl dags list-import-errors") @suppress_logs_and_warning @providers_configuration_loaded @provide_session @@ -725,6 +732,7 @@ def dag_report(args) -> None: ) +@deprecated_for_airflowctl("airflowctl jobs list") @cli_utils.action_cli @suppress_logs_and_warning @providers_configuration_loaded diff --git a/airflow-core/src/airflow/cli/commands/db_command.py b/airflow-core/src/airflow/cli/commands/db_command.py index 4c15ccc2d488d..54de07299c645 100644 --- a/airflow-core/src/airflow/cli/commands/db_command.py +++ b/airflow-core/src/airflow/cli/commands/db_command.py @@ -306,6 +306,12 @@ def shell(args): url = settings.get_engine().url print(f"DB: {url!r}") + if not url.database: + raise ValueError( + "The metadata database name is missing from the connection URI. " + "Please check your AIRFLOW__DATABASE__SQL_ALCHEMY_CONN configuration." + ) + if url.get_backend_name() == "mysql": with NamedTemporaryFile(suffix="my.cnf") as f: f.write(_build_mysql_cnf(url)) diff --git a/airflow-core/src/airflow/cli/commands/partition_command.py b/airflow-core/src/airflow/cli/commands/partition_command.py index c948e7f4b16eb..13443c424909b 100644 --- a/airflow-core/src/airflow/cli/commands/partition_command.py +++ b/airflow-core/src/airflow/cli/commands/partition_command.py @@ -44,7 +44,9 @@ def clear(args, *, session: Session = NEW_SESSION) -> None: the matching partitions; a date-only value (no time) is treated as local midnight. """ - has_range = args.start_date is not None or args.end_date is not None or args.date is not None + has_start = args.start_date is not None + has_end = args.end_date is not None + has_range = has_start or has_end or args.date is not None selectors_used = sum([args.run_id is not None, args.partition_key is not None, has_range]) if selectors_used != 1: raise SystemExit( @@ -52,8 +54,10 @@ def clear(args, *, session: Session = NEW_SESSION) -> None: "(--start-date/--end-date or --date)." ) - if args.date is not None: - if args.start_date is not None or args.end_date is not None: + from_date_flag = args.date is not None + + if from_date_flag: + if has_start or has_end: raise SystemExit("--date cannot be combined with --start-date / --end-date.") raw = args.date parts = raw.split("~", 1) @@ -64,9 +68,24 @@ def clear(args, *, session: Session = NEW_SESSION) -> None: args.end_date = parsedate(parts[1].strip()) except ValueError: raise SystemExit("--date sides must be parseable as a date or datetime.") + has_start = has_end = True + + has_date_window = has_start or has_end + if has_date_window: + dag = get_db_dag(bundle_names=None, dag_id=args.dag_id) + if has_start and has_end: + lower = dag.timetable.localize_partition_datetime(args.start_date) + upper = dag.timetable.localize_partition_datetime(args.end_date) + if lower > upper: + if from_date_flag: + raise SystemExit( + f"--date: the start of the range ({parts[0].strip()!r}) must be on or before " + f"the end ({parts[1].strip()!r})." + ) + raise SystemExit("--start-date must be on or before --end-date.") + else: + dag = None - has_date_window = args.start_date is not None or args.end_date is not None - dag = get_db_dag(bundle_names=None, dag_id=args.dag_id) if has_date_window else None clear_tis = bool(args.clear_task_instances) processed_any = False diff --git a/airflow-core/src/airflow/cli/commands/provider_command.py b/airflow-core/src/airflow/cli/commands/provider_command.py index 645618fd852cc..fa24b8bb8b884 100644 --- a/airflow-core/src/airflow/cli/commands/provider_command.py +++ b/airflow-core/src/airflow/cli/commands/provider_command.py @@ -22,6 +22,7 @@ import sys from airflow.cli.simple_table import AirflowConsole +from airflow.cli.utils import deprecated_for_airflowctl from airflow.providers_manager import ProvidersManager from airflow.utils.cli import suppress_logs_and_warning from airflow.utils.providers_configuration_loader import providers_configuration_loaded @@ -33,6 +34,7 @@ def _remove_rst_syntax(value: str) -> str: return re.sub("[`_<>]", "", value.strip(" \n.")) +@deprecated_for_airflowctl("airflowctl providers get") @suppress_logs_and_warning @providers_configuration_loaded def provider_get(args): @@ -55,6 +57,7 @@ def provider_get(args): raise SystemExit(f"No such provider installed: {args.provider_name}") +@deprecated_for_airflowctl("airflowctl providers list") @suppress_logs_and_warning @providers_configuration_loaded def providers_list(args): diff --git a/airflow-core/src/airflow/cli/commands/variable_command.py b/airflow-core/src/airflow/cli/commands/variable_command.py index 5216aabb446c6..194b02b529a97 100644 --- a/airflow-core/src/airflow/cli/commands/variable_command.py +++ b/airflow-core/src/airflow/cli/commands/variable_command.py @@ -26,7 +26,7 @@ from sqlalchemy import select from airflow.cli.simple_table import AirflowConsole -from airflow.cli.utils import SENSITIVE_PLACEHOLDER, print_export_output +from airflow.cli.utils import SENSITIVE_PLACEHOLDER, deprecated_for_airflowctl, print_export_output from airflow.exceptions import ( AirflowFileParseException, AirflowUnsupportedFileTypeException, @@ -63,6 +63,7 @@ def with_values(var, hide_sensitive: bool = False) -> dict[str, str]: return {"key": key, "val": val} +@deprecated_for_airflowctl("airflowctl variables list") @suppress_logs_and_warning @providers_configuration_loaded def variables_list(args): @@ -92,6 +93,7 @@ def _mapper(var): AirflowConsole().print_as(data=variables, output=args.output, mapper=None) +@deprecated_for_airflowctl("airflowctl variables get") @suppress_logs_and_warning @providers_configuration_loaded def variables_get(args): @@ -108,6 +110,7 @@ def variables_get(args): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl variables create") @providers_configuration_loaded def variables_set(args): """Create new variable with a given name, value and description.""" @@ -116,6 +119,7 @@ def variables_set(args): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl variables delete") @providers_configuration_loaded def variables_delete(args): """Delete variable by a given name.""" @@ -124,6 +128,7 @@ def variables_delete(args): @cli_utils.action_cli +@deprecated_for_airflowctl("airflowctl variables import") @providers_configuration_loaded @provide_session def variables_import(args, *, session: Session = NEW_SESSION): diff --git a/airflow-core/src/airflow/cli/utils.py b/airflow-core/src/airflow/cli/utils.py index 35a62c9df9135..aef66a8804622 100644 --- a/airflow-core/src/airflow/cli/utils.py +++ b/airflow-core/src/airflow/cli/utils.py @@ -17,6 +17,7 @@ from __future__ import annotations +import logging import sys from collections.abc import Callable from typing import TYPE_CHECKING, TypeVar @@ -78,6 +79,20 @@ def is_stdout(fileio: IOBase) -> bool: return fileio is sys.stdout +def redirect_stdout_log_handlers_to_stderr() -> None: + """ + Redirect any root-logger ``StreamHandler`` writing to stdout so it writes to stderr. + + Called from the CLI entrypoint for commands that emit structured output on + stdout (``-o json|yaml|plain|table``), so log lines do not corrupt that + output. ``FileHandler`` is a ``StreamHandler`` subclass; the identity check + against ``sys.stdout`` correctly skips it. + """ + for handler in logging.getLogger().handlers: + if isinstance(handler, logging.StreamHandler) and handler.stream is sys.stdout: + handler.setStream(sys.stderr) + + def print_export_output(command_type: str, exported_items: Collection, file: TextIOWrapper): if is_stdout(file): print(f"\n{len(exported_items)} {command_type} successfully exported.", file=sys.stderr) diff --git a/airflow-core/src/airflow/config_templates/airflow_local_settings.py b/airflow-core/src/airflow/config_templates/airflow_local_settings.py index e30e68fb17984..c5bb91b682f56 100644 --- a/airflow-core/src/airflow/config_templates/airflow_local_settings.py +++ b/airflow-core/src/airflow/config_templates/airflow_local_settings.py @@ -50,6 +50,9 @@ BASE_LOG_FOLDER: str = os.path.expanduser(conf.get_mandatory_value("logging", "BASE_LOG_FOLDER")) # This isn't used anymore, but kept for compat of people who might have imported it +# Default value for the ``[logging] logging_config_class`` option. Plain +# ``logging.config.dictConfig`` dict; the ``_class`` suffix on the config option +# is historical. DEFAULT_LOGGING_CONFIG: dict[str, Any] = { "version": 1, "disable_existing_loggers": False, @@ -121,6 +124,11 @@ ################## REMOTE_LOGGING: bool = conf.getboolean("logging", "remote_logging") + +# Side-channel attributes read by ``discover_remote_log_handler`` from whichever +# module ``[logging] logging_config_class`` resolves through. Custom modules that +# override that option should define both at module scope to enable remote +# task-log read-back. REMOTE_TASK_LOG: RemoteLogIO | RemoteLogStreamIO | None = None DEFAULT_REMOTE_CONN_ID: str | None = None diff --git a/airflow-core/src/airflow/config_templates/config.yml b/airflow-core/src/airflow/config_templates/config.yml index 975e6ba11213b..27d674b5802e4 100644 --- a/airflow-core/src/airflow/config_templates/config.yml +++ b/airflow-core/src/airflow/config_templates/config.yml @@ -921,9 +921,12 @@ logging: default: "INFO" logging_config_class: description: | - Logging class - Specify the class that will specify the logging configuration - This class has to be on the python classpath + Dotted import path to a ``logging.config.dictConfig`` dict. The + ``_class`` suffix is historical — the target is a dict, not a class. + + Airflow also reads two optional module-level attributes from the + enclosing module: ``REMOTE_TASK_LOG`` and ``DEFAULT_REMOTE_CONN_ID``, + used to drive remote task-log read-back. See :ref:`write-logs-advanced`. version_added: 2.0.0 type: string example: "my.path.default_local_settings.LOGGING_CONFIG" diff --git a/airflow-core/src/airflow/dag_processing/bundles/manager.py b/airflow-core/src/airflow/dag_processing/bundles/manager.py index 78c54266eda9f..1d195d8515443 100644 --- a/airflow-core/src/airflow/dag_processing/bundles/manager.py +++ b/airflow-core/src/airflow/dag_processing/bundles/manager.py @@ -20,11 +20,13 @@ import logging import os import warnings -from typing import TYPE_CHECKING +from collections import defaultdict +from pathlib import Path +from typing import TYPE_CHECKING, cast from itsdangerous import URLSafeSerializer from pydantic import BaseModel, ValidationError -from sqlalchemy import delete, select +from sqlalchemy import and_, delete, exists, or_, select, update from airflow._shared.module_loading import import_string from airflow.configuration import conf @@ -34,17 +36,48 @@ from airflow.models.team import Team from airflow.providers_manager import ProvidersManager from airflow.utils.log.logging_mixin import LoggingMixin -from airflow.utils.session import NEW_SESSION, provide_session +from airflow.utils.session import NEW_SESSION, create_session, provide_session if TYPE_CHECKING: from collections.abc import Iterable + from sqlalchemy.engine import CursorResult from sqlalchemy.orm import Session log = logging.getLogger(__name__) _example_dag_bundle_name = "example_dags" +# Chunk size for the one-time startup repair of unconfigured bundles. +_REASSIGN_BATCH_SIZE = 1000 + + +def _guess_best_bundle_for_fileloc( + fileloc: str, descending_bundle_paths: dict[str, Path] +) -> tuple[str, str] | None: + """ + Return ``(bundle_name, relative_fileloc)`` for the first bundle whose path contains ``fileloc``. + + ``descending_bundle_paths`` must be sorted by path length descending so + the deepest bundle wins when paths overlap. + + Returns ``None`` when ``fileloc`` is not under any bundle's path. + + Uses the same plain ``Path.relative_to`` check as + ``BaseDagImporter.get_relative_path``, so the ``relative_fileloc`` written + here matches what the next parse computes for the same file. Filelocs are + produced by the Dag processor parsing admin-controlled bundle files, so they + are trusted and need no path-traversal normalization. + """ + file_path = Path(fileloc) + for name, path in descending_bundle_paths.items(): + try: + relative = file_path.relative_to(path) + except ValueError: + continue + return name, str(relative) + return None + class _ExternalBundleConfig(BaseModel): """Schema defining the user-specified configuration for a DAG bundle.""" @@ -271,7 +304,7 @@ def parse_config(self) -> None: self.log.info("DAG bundles loaded: %s", ", ".join(self._bundle_config.keys())) @provide_session - def sync_bundles_to_db(self, *, session: Session = NEW_SESSION) -> None: + def sync_bundles_to_db(self, *, deactivate_missing: bool = True, session: Session = NEW_SESSION) -> None: """ Persist the configured DAG bundles into ``DagBundleModel`` rows. @@ -280,6 +313,14 @@ def sync_bundles_to_db(self, *, session: Session = NEW_SESSION) -> None: ``DagModel`` / ``SerializedDagModel`` rows is the responsibility of ``DagBag`` plus ``sync_bag_to_db`` (or, in production, the DAG processor); calling this method does not trigger that work. + + :param deactivate_missing: When ``True`` (the default), any bundle stored in + the database that is not present in this manager's config is marked + inactive. This is only correct when the calling process sees the + *complete* bundle configuration. When multiple dag-processors each run + with a partial config (e.g. one bundle per processor), pass ``False`` so a + processor does not disable bundles owned by other processors -- otherwise + the processors repeatedly deactivate each other and never converge. """ self.log.debug("Syncing DAG bundles to the database") @@ -356,6 +397,11 @@ def _extract_and_sign_template(bundle_name: str) -> tuple[str | None, dict]: ) bundle.teams = [] + if not deactivate_missing: + # This process only owns a subset of the bundles, so the remaining stored + # bundles may well be owned by another dag-processor. Leave them alone. + return + # Import here to avoid circular import from airflow.models.errors import ParseImportError @@ -366,6 +412,199 @@ def _extract_and_sign_template(bundle_name: str) -> tuple[str | None, dict]: session.execute(delete(ParseImportError).where(ParseImportError.bundle_name == name)) self.log.info("Deleted import errors for bundle %s which is no longer configured", name) + def reassign_dags_with_unconfigured_bundles(self) -> int: + """ + Reassign Dags pointing at unconfigured bundles to a configured one. + + Side effect of the ``0082_3_1_0_make_bundle_name_not_nullable`` + migration (#63323): legacy rows get ``bundle_name='dags-folder'`` + and NULL ``relative_fileloc``, which raises ``Requested bundle + '{name}' is not configured.`` at trigger time when the deployment + uses a custom bundle. + + Each legacy-candidate row (NULL ``relative_fileloc`` and no + ``DagVersion``) is routed to the most-specific configured bundle + whose path contains its ``fileloc``, writing ``relative_fileloc`` + atomically. Rows whose ``fileloc`` is under no configured bundle + are left untouched -- writing ``bundle_name`` without a verified + ``relative_fileloc`` would produce a row task workers cannot + execute -- and instead self-heal via the normal staleness + lifecycle: ``sync_bundles_to_db`` deactivates the old bundle, the + stale-scan marks the row stale, and the next successful parse + from any configured bundle resets everything via + ``update_dag_parsing_results_in_db``. No manual ``airflow dags + reserialize`` is required. + + Multi-team-safe because a bundle path belongs to at most one team. + Each chunk runs in its own internally-owned transaction so the + row-lock window stays bounded and no caller-provided session is + committed. + + :return: Number of Dags reassigned. + """ + # Import here to avoid circular import + # (manager -> dag -> dagrun -> taskinstance -> dag_version -> manager) + from airflow.models.dag import DagModel + from airflow.models.dag_version import DagVersion + + # Fast-skip once any 3.x parse cycle has run. DagVersion is written + # only by the parse path, and that path overwrites both bundle_name + # and relative_fileloc on every parse (see + # ``DagModelOperation.update_dags``), so any legacy row whose file + # is under a configured bundle self-heals at the next parse and any + # row whose file is under no configured bundle self-heals via the + # staleness lifecycle -- reassign has no work the parse path will + # not do itself. The probe is an index hit on dag_version's PK + # vs. a sequential scan of dag (no index on relative_fileloc). + with create_session() as session: + if session.scalar(select(DagVersion.id).limit(1)) is not None: + return 0 + + if not (active_bundle_paths := self._resolve_active_bundle_paths(session=session)): + self.log.info( + "No active Dag bundles with resolvable paths; skipping reassignment of Dags " + "with unconfigured bundles." + ) + return 0 + + # Chunked UPDATEs ordered by (bundle_name, dag_id), one transaction per + # chunk; repaired rows drop out of the predicate because writing + # relative_fileloc makes the IS NULL clause false. Scanning in + # bundle_name order groups the movements log by source bundle without + # a Python-side re-sort. + # + # Legacy-candidate predicate (rows never parsed in 3.x): NULL + # relative_fileloc (the 0082 migration leaves it NULL) AND NOT EXISTS + # DagVersion (the parse path writes DagModel.bundle_name before the + # DagVersion). Equivalent under that invariant; both stated as + # defense in depth and repeated on the UPDATE itself as a CAS guard + # so a concurrent parser write wins the race. + movements: dict[tuple[str | None, str], int] = defaultdict(int) + total_reassigned = 0 + total_backfilled = 0 + total_skipped = 0 + last_seen: tuple[str, str] | None = None + + while True: + with create_session() as session: + query = ( + select(DagModel.dag_id, DagModel.bundle_name, DagModel.fileloc) + .where( + DagModel.relative_fileloc.is_(None), + ~exists().where(DagVersion.dag_id == DagModel.dag_id), + ) + .order_by(DagModel.bundle_name, DagModel.dag_id) + .limit(_REASSIGN_BATCH_SIZE) + ) + if last_seen is not None: + last_bundle, last_dag_id = last_seen + query = query.where( + or_( + DagModel.bundle_name > last_bundle, + and_(DagModel.bundle_name == last_bundle, DagModel.dag_id > last_dag_id), + ) + ) + + if not (chunk := session.execute(query).all()): + break + last_seen = (chunk[-1].bundle_name, chunk[-1].dag_id) + + # Route every legacy row by fileloc, not just those on + # unconfigured bundles, so a migration-assigned dags-folder + # row whose file lives under a different configured bundle + # gets relocated instead of stranded. Classify as skip + # (no match), backfill (match == current bundle), or + # reassign (match != current bundle). + chunk_updates: list[tuple[str, str | None, str, str]] = [] + for row in chunk: + match = ( + _guess_best_bundle_for_fileloc(row.fileloc, active_bundle_paths) if row.fileloc else None + ) + if match is None: + total_skipped += 1 + continue + target, relative = match + chunk_updates.append((row.dag_id, row.bundle_name, target, relative)) + + if not chunk_updates: + continue + + with create_session() as session: + # create_session commits on context exit, bounding the + # row-lock window to one chunk. + for dag_id, prev_bundle, target, relative in chunk_updates: + result = cast( + "CursorResult", + session.execute( + update(DagModel) + .where( + DagModel.dag_id == dag_id, + DagModel.relative_fileloc.is_(None), + ~exists().where(DagVersion.dag_id == DagModel.dag_id), + ) + .values(relative_fileloc=relative, bundle_name=target) + .execution_options(synchronize_session=False) + ), + ) + + if result.rowcount: + # Rowcount is the source of truth for whether the CAS actually fired + if target == prev_bundle: + total_backfilled += 1 + else: + movements[(prev_bundle, target)] += 1 + total_reassigned += 1 + else: + self.log.debug("Skipping repair for Dag '%s': lost race to parser.", dag_id) + + for (prev, target), n in movements.items(): + self.log.info( + "Reassigning %d Dag(s) from bundle '%s' to '%s'", + n, + prev, + target, + ) + + if total_backfilled: + self.log.info("Backfilled relative_fileloc for %d legacy Dag(s).", total_backfilled) + + if total_skipped: + self.log.warning( + "Skipped %d legacy Dag(s) whose fileloc is not under any configured bundle; " + "triggering them will keep raising \"Requested bundle '{name}' is not configured.\" " + "until a bundle whose path contains the fileloc is added to " + "dag_bundle_config_list. The next parse will then restore them automatically, " + "or run `airflow dags reserialize` to force the parse path to rewrite " + "bundle_name and relative_fileloc immediately.", + total_skipped, + ) + + return total_reassigned + + def _resolve_active_bundle_paths(self, *, session: Session) -> dict[str, Path]: + """ + Return paths for configured-and-active bundles. + + A bundle is "configured-and-active" when it is both in the manager's + config and persisted as ``active=True`` in ``dag_bundle`` -- bundles + missing from ``dag_bundle`` are excluded so they can't trigger an FK + violation if used as a reassignment target. + + The returned dict is ``{name: path}`` ordered by path length descending + so the most specific bundle wins in ``_guess_best_bundle_for_fileloc``. + """ + active_db_names = set( + session.scalars(select(DagBundleModel.name).where(DagBundleModel.active.is_(True))) + ) + + active_bundle_paths: dict[str, Path] = {} + for bundle in self.get_all_dag_bundles(): + if bundle.name not in active_db_names: + continue + active_bundle_paths[bundle.name] = bundle.path + + return dict(sorted(active_bundle_paths.items(), key=lambda item: len(str(item[1])), reverse=True)) + @staticmethod def _extract_template_params(bundle_instance: BaseDagBundle) -> dict: """ diff --git a/airflow-core/src/airflow/dag_processing/collection.py b/airflow-core/src/airflow/dag_processing/collection.py index 003a4da016e60..9ea66e60ed310 100644 --- a/airflow-core/src/airflow/dag_processing/collection.py +++ b/airflow-core/src/airflow/dag_processing/collection.py @@ -194,20 +194,20 @@ def calculate(cls, dag: LazyDeserializedDAG, *, session: Session) -> Self: return cls(None, 0) if dag.timetable.partitioned: - log.info("Getting latest run for partitioned Dag", dag_id=dag.dag_id) + log.debug("Getting latest run for partitioned Dag", dag_id=dag.dag_id) latest_run = session.scalar(_get_latest_runs_stmt_partitioned(dag_id=dag.dag_id)) else: - log.info("Getting latest run for non-partitioned Dag", dag_id=dag.dag_id) + log.debug("Getting latest run for non-partitioned Dag", dag_id=dag.dag_id) latest_run = session.scalar(_get_latest_runs_stmt(dag_id=dag.dag_id)) if latest_run: - log.info( + log.debug( "got latest run", dag_id=dag.dag_id, logical_date=str(latest_run.logical_date), partition_key=latest_run.partition_key, ) else: - log.info("no latest run found", dag_id=dag.dag_id) + log.debug("no latest run found", dag_id=dag.dag_id) active_run_counts = DagRun.active_runs_of_dags( dag_ids=[dag.dag_id], exclude_backfill=True, diff --git a/airflow-core/src/airflow/dag_processing/manager.py b/airflow-core/src/airflow/dag_processing/manager.py index b2428985a6506..47a1d5f8059dc 100644 --- a/airflow-core/src/airflow/dag_processing/manager.py +++ b/airflow-core/src/airflow/dag_processing/manager.py @@ -333,7 +333,16 @@ def _exit_gracefully(self, signum, frame): def sync_bundles(self) -> None: """Sync configured DAG bundles to the metadata database.""" - DagBundlesManager().sync_bundles_to_db() + # When this processor only parses a subset of bundles, it does not see the full + # bundle configuration and must not deactivate bundles owned by other processors. + dag_bundle_manager = DagBundlesManager() + dag_bundle_manager.sync_bundles_to_db(deactivate_missing=not self.bundle_names_to_parse) + # Best-effort legacy repair: a failure here must not crash DFP startup. + # Affected Dags self-heal on the next successful parse. + try: + dag_bundle_manager.reassign_dags_with_unconfigured_bundles() + except Exception: + self.log.exception("Failed to reassign Dags with unconfigured bundles during startup") def get_all_bundles(self) -> list[BaseDagBundle]: """Return configured DAG bundles filtered by ``bundle_names_to_parse`` if provided.""" @@ -464,17 +473,36 @@ def deactivate_stale_dags( ).where(~DagModel.is_stale) dags_parsed = session.execute(query) + stuck_legacy_rows = 0 for dag in dags_parsed: # Dags whose bundle has been removed from config (bundle no longer active) are stale — # the processor has stopped parsing their files, so the time-based check below would never fire. - if dag.bundle_name in inactive_bundles: + # + # A NULL bundle_name means the row predates bundles (carried over from Airflow 2.x) and has not + # been parsed since the upgrade — parsing is what fills bundle_name in. If the file was removed + # as part of the upgrade, no parse will ever happen, so bundle_name stays NULL forever. Such a + # row can never hit the time-based check below either, because that matches on + # (bundle_name, relative_fileloc) and there is no bundle to match against, so without this + # branch the Dag stays active in the UI indefinitely. If the file does still exist, the next + # parse fills in bundle_name and clears is_stale, so a Dag deactivated here is reactivated. + if dag.bundle_name is None or dag.bundle_name in inactive_bundles: self.log.info( - "Deactivating Dag %s. Its bundle %s is no longer active.", + "Deactivating Dag %s. Its bundle %s is no longer active or is NULL.", dag.dag_id, dag.bundle_name, ) to_deactivate.add(dag.dag_id) continue + # A Dag upgraded from Airflow 2.x can still have a NULL relative_fileloc: + # the 0082 migration adds the column as nullable, and the startup repair + # in DagBundlesManager only backfills it when the Dag's fileloc resolves to + # a configured bundle. Rows whose fileloc matches no bundle stay NULL, so + # the time-based stale check below would build Path(None) and crash. Skip + # them here and count them so the total is surfaced after the loop. + # See https://github.com/apache/airflow/issues/63323. + if dag.relative_fileloc is None: + stuck_legacy_rows += 1 + continue # When the Dag's last_parsed_time is more than the stale_dag_threshold older than the # Dag file's last_finish_time, the Dag is considered stale as has apparently been removed from the file, # This is especially relevant for Dag files that generate Dags in a dynamic manner. @@ -511,6 +539,15 @@ def deactivate_stale_dags( else: raise + if stuck_legacy_rows: + # Surface how many legacy rows the startup repair could not route; + # each one keeps raising "Requested bundle is not configured." until + # a matching bundle is added to dag_bundle_config_list. + self.log.info( + "Skipped stale check for %d legacy Dag(s) with NULL relative_fileloc.", + stuck_legacy_rows, + ) + def _run_parsing_loop(self): # initialize cache to mutualize calls to Variable.get in DAGs # needs to be done before this process is forked to create the DAG parsing processes. @@ -745,11 +782,11 @@ def get_bundle_state(self, bundle_name: str, *, session: Session = NEW_SESSION) Returns ``None`` if the bundle has no database record. """ - row = session.scalar( - select(DagBundleModel) - .where(DagBundleModel.name == bundle_name) - .options(load_only(DagBundleModel.last_refreshed, DagBundleModel.version)) - ) + row = session.execute( + select(DagBundleModel.last_refreshed, DagBundleModel.version).where( + DagBundleModel.name == bundle_name + ) + ).one_or_none() if row is None: return None return BundleState(last_refreshed=row.last_refreshed, version=row.version) @@ -811,7 +848,6 @@ def _refresh_dag_bundles(self, known_files: dict[str, set[DagFileInfo]]): except AirflowException as e: self.log.exception("Error initializing bundle %s: %s", bundle.name, e) continue - # TODO: AIP-66 test to make sure we get a fresh record from the db and it's not cached try: bundle_state = self.get_bundle_state(bundle.name) except Exception: diff --git a/airflow-core/src/airflow/jobs/scheduler_job_runner.py b/airflow-core/src/airflow/jobs/scheduler_job_runner.py index 2f94d480eb6d1..fb73845501947 100644 --- a/airflow-core/src/airflow/jobs/scheduler_job_runner.py +++ b/airflow-core/src/airflow/jobs/scheduler_job_runner.py @@ -2391,19 +2391,15 @@ def _create_dag_runs(self, dag_models: Collection[DagModel], session: Session) - # as DagModel.dag_id and DagModel.next_dagrun # This list is used to verify if the DagRun already exist so that we don't attempt to create # duplicate DagRuns - existing_dagrun_objects = ( - session.scalars( - select(DagRun) - .where( - tuple_(DagRun.dag_id, DagRun.logical_date).in_( - (dm.dag_id, dm.next_dagrun) for dm in dag_models - ) + existing_dagrun_objects = session.scalars( + select(DagRun) + .where( + tuple_(DagRun.dag_id, DagRun.logical_date).in_( + (dm.dag_id, dm.next_dagrun) for dm in dag_models ) - .options(load_only(DagRun.dag_id, DagRun.logical_date)) ) - .unique() - .all() - ) + .options(load_only(DagRun.dag_id, DagRun.logical_date)) + ).all() existing_dagruns = {(x.dag_id, x.logical_date): x for x in existing_dagrun_objects} # backfill runs are not created by scheduler and their concurrency is separate @@ -2581,6 +2577,18 @@ def _create_dag_runs_asset_triggered( .cte() ) + # A first asset-triggered run has no previous run to floor the event window. With + # catchup off, floor it at when the Dag started scheduling on its assets so the + # backlog is skipped; with catchup on, only date.min applies and the backlog replays. + event_window_floor: list[Any] = [cte.c.previous_dag_run_run_after] + if not dag.catchup: + event_window_floor.append( + select(func.min(DagScheduleAssetReference.created_at)) + .where(DagScheduleAssetReference.dag_id == dag.dag_id) + .scalar_subquery() + ) + event_window_floor.append(date.min) + asset_events = list( session.scalars( select(AssetEvent) @@ -2598,7 +2606,7 @@ def _create_dag_runs_asset_triggered( ), ), AssetEvent.timestamp <= triggered_date, - AssetEvent.timestamp > func.coalesce(cte.c.previous_dag_run_run_after, date.min), + AssetEvent.timestamp > func.coalesce(*event_window_floor), ) .order_by(AssetEvent.timestamp.asc(), AssetEvent.id.asc()) ) @@ -2868,7 +2876,7 @@ def _schedule_dag_run( duration, tags=prune_dict( { - "dag_id": dag_run.dag_id, + **dag_run.stats_tags, "team_name": self._get_team_names_for_dag_ids([dag_run.dag_id], session).get( dag_run.dag_id ) @@ -3406,8 +3414,10 @@ def check_awaiting_input_timeouts( num_resolved = 0 num_failed = 0 + num_unresumable = 0 for ti in timed_out_tis: hitl_detail = ti.hitl_detail + resuming = True if hitl_detail is not None and hitl_detail.responded_at is not None: # A response landed just before the deadline; resume with it. handle_event_submit( @@ -3415,7 +3425,6 @@ def check_awaiting_input_timeouts( task_instance=ti, session=session, ) - num_resolved += 1 elif hitl_detail is not None and hitl_detail.defaults is not None: # Apply the configured defaults as the response, then resume to success. hitl_detail.chosen_options = list(hitl_detail.defaults) @@ -3431,7 +3440,6 @@ def check_awaiting_input_timeouts( task_instance=ti, session=session, ) - num_resolved += 1 else: # No defaults and no response: resume into execute_complete with a timeout # failure event so the operator raises HITLTimeoutError (matching the old @@ -3447,16 +3455,29 @@ def check_awaiting_input_timeouts( task_instance=ti, session=session, ) + resuming = False + + # ``handle_event_submit`` routes a task instance it could not process to + # ``__fail__`` instead of resuming it. That is neither of the outcomes the + # branches above intended, so it is counted on its own rather than being + # reported as resolved. + if ti.next_method == TRIGGER_FAIL_REPR: + num_unresumable += 1 + elif resuming: + num_resolved += 1 + else: num_failed += 1 # Flush within the retry block so both branches persist consistently (the defaults # branch already flushes via handle_event_submit; the fail branch relies on this). session.flush() - if num_resolved or num_failed: + if num_resolved or num_failed or num_unresumable: self.log.info( - "AWAITING_INPUT timeout sweep: %i resolved (response/defaults), %i failed", + "AWAITING_INPUT timeout sweep: %i resolved (response/defaults), %i failed, " + "%i could not be resumed", num_resolved, num_failed, + num_unresumable, ) # [START find_and_purge_task_instances_without_heartbeats] @@ -3536,12 +3557,21 @@ def _purge_task_instances_without_heartbeats( # Backfill dag_version_id for legacy tasks (Pydantic requires uuid.UUID). if not _ensure_ti_has_dag_version_id(ti, session, self.log): continue + # ti.task isn't loaded in this purge path, so is_eligible_to_retry() uses its + # no-task fallback (``try_number <= max_tries``), which skips the retries-configured + # check its task-loaded branch applies; guard with ``max_tries > 0`` so a task + # declared with retries=0 isn't treated as retry-eligible here. + if ti.max_tries > 0 and ti.is_eligible_to_retry(): + task_callback_type = TaskInstanceState.UP_FOR_RETRY + else: + task_callback_type = TaskInstanceState.FAILED request = TaskCallbackRequest( filepath=ti.dag_model.relative_fileloc or "", bundle_name=_hb_bundle_name, bundle_version=_hb_bundle_version, ti=ti, msg=str(task_instance_heartbeat_timeout_message_details), + task_callback_type=task_callback_type, context_from_server=TIRunContext( dag_run=DRDataModel.model_validate(ti.dag_run, from_attributes=True), max_tries=ti.max_tries, diff --git a/airflow-core/src/airflow/jobs/triggerer_job_runner.py b/airflow-core/src/airflow/jobs/triggerer_job_runner.py index eccd9d2fc048d..b8788c05e45db 100644 --- a/airflow-core/src/airflow/jobs/triggerer_job_runner.py +++ b/airflow-core/src/airflow/jobs/triggerer_job_runner.py @@ -997,7 +997,7 @@ def _process_log_messages_from_subprocess(self) -> Generator[None, bytes | bytea from airflow.sdk.log import configure_logging - configure_logging() + configure_logging(json_output=conf.getboolean("logging", "json_logs", fallback=False)) fallback_log = structlog.get_logger(logger_name=__name__) diff --git a/airflow-core/src/airflow/logging_config.py b/airflow-core/src/airflow/logging_config.py index 7f4ae605cb21a..da337997de8ed 100644 --- a/airflow-core/src/airflow/logging_config.py +++ b/airflow-core/src/airflow/logging_config.py @@ -36,7 +36,7 @@ class _ActiveLoggingConfig: """Private class to hold active logging config variables.""" logging_config_loaded: bool = False - remote_task_log: RemoteLogIO | None + remote_task_log: RemoteLogIO | None = None default_remote_conn_id: str | None = None @classmethod @@ -120,6 +120,44 @@ def load_logging_config() -> tuple[dict[str, Any], str]: ) or DEFAULT_LOGGING_CONFIG_PATH +def _warn_if_missing_remote_task_log(logging_class_path: str) -> None: + """ + Warn if ``[logging] remote_logging`` is on but the user module exposes no remote IO. + + Runs *after* ``dictConfig`` has constructed handlers, so deprecated + self-registration in provider task handlers (Elasticsearch, OpenSearch) has + already had its chance to populate ``_ActiveLoggingConfig.remote_task_log``. + Only fires for user-defined ``logging_config_class`` values; the stock + fallback is exempt. + + :param logging_class_path: the resolved ``[logging] logging_config_class`` + dotted path (already defaulted to :data:`DEFAULT_LOGGING_CONFIG_PATH`). + """ + # An empty path is not a meaningful override -- ``_get_logging_config()`` treats it the + # same as unset and falls back to ``DEFAULT_LOGGING_CONFIG_PATH``, so it must not be + # treated as a user-defined logging config class here either. + has_user_defined_logging_config_class = ( + bool(logging_class_path) and logging_class_path != DEFAULT_LOGGING_CONFIG_PATH + ) + remote_logging_enabled = conf.getboolean("logging", "remote_logging", fallback=False) + if not (has_user_defined_logging_config_class and remote_logging_enabled): + return + if get_remote_task_log() is not None: + return + # Strip the trailing ``.`` to leave the enclosing module path. + # ``logging_class_path`` should always be dotted since ``import_string`` + # would have raised otherwise, but guard the access defensively. + parts = logging_class_path.rsplit(".", 1) + modpath = parts[0] if len(parts) == 2 else logging_class_path + log.warning( + "[logging] remote_logging is enabled but the user-defined logging module %r " + "does not expose a REMOTE_TASK_LOG attribute, so remote task-log read-back is " + "disabled. Define REMOTE_TASK_LOG (a RemoteLogIO instance) at module scope " + "to enable it.", + modpath, + ) + + def configure_logging(): from airflow._shared.logging import configure_logging, init_log_folder, translate_config_values @@ -171,6 +209,16 @@ def configure_logging(): # otherwise Airflow would silently fall back on the default config raise e + # Runs after dictConfig so deprecated handler self-registration (ES/OS) has + # had its chance to populate _ActiveLoggingConfig.remote_task_log. + # The trailing `or DEFAULT_LOGGING_CONFIG_PATH` also covers an explicit + # `logging_config_class = ""`, which conf.get() would otherwise return as-is. + logging_class_path = ( + conf.get("logging", "logging_config_class", fallback=DEFAULT_LOGGING_CONFIG_PATH) + or DEFAULT_LOGGING_CONFIG_PATH + ) + _warn_if_missing_remote_task_log(logging_class_path) + validate_logging_config() new_folder_permissions = int( diff --git a/airflow-core/src/airflow/migrations/versions/0003_2_7_0_add_include_deferred_column_to_pool.py b/airflow-core/src/airflow/migrations/versions/0003_2_7_0_add_include_deferred_column_to_pool.py index 6cfae9ce36b11..e0a3038114b6b 100644 --- a/airflow-core/src/airflow/migrations/versions/0003_2_7_0_add_include_deferred_column_to_pool.py +++ b/airflow-core/src/airflow/migrations/versions/0003_2_7_0_add_include_deferred_column_to_pool.py @@ -17,7 +17,7 @@ # under the License. """ -add include_deferred column to pool. +Add include_deferred column to pool. Revision ID: 405de8318b3a Revises: 788397e78828 diff --git a/airflow-core/src/airflow/migrations/versions/0004_2_8_0_add_clear_number_to_dag_run.py b/airflow-core/src/airflow/migrations/versions/0004_2_8_0_add_clear_number_to_dag_run.py index 94f2a14874aba..6444ee381fa20 100644 --- a/airflow-core/src/airflow/migrations/versions/0004_2_8_0_add_clear_number_to_dag_run.py +++ b/airflow-core/src/airflow/migrations/versions/0004_2_8_0_add_clear_number_to_dag_run.py @@ -17,7 +17,7 @@ # under the License. """ -add new field 'clear_number' to dagrun. +Add new field 'clear_number' to dagrun. Revision ID: 375a816bbbf4 Revises: 405de8318b3a diff --git a/airflow-core/src/airflow/migrations/versions/0011_2_9_0_add_dataset_expression_in_dagmodel.py b/airflow-core/src/airflow/migrations/versions/0011_2_9_0_add_dataset_expression_in_dagmodel.py index e667a1e04aaa5..2a55e67f8997d 100644 --- a/airflow-core/src/airflow/migrations/versions/0011_2_9_0_add_dataset_expression_in_dagmodel.py +++ b/airflow-core/src/airflow/migrations/versions/0011_2_9_0_add_dataset_expression_in_dagmodel.py @@ -17,7 +17,7 @@ # under the License. """ -add dataset_expression in DagModel. +Add dataset_expression in DagModel. Revision ID: ab34f260b71c Revises: d75389605139 diff --git a/airflow-core/src/airflow/migrations/versions/0012_2_9_0_adding_adding_max_failure_runs_column_.py b/airflow-core/src/airflow/migrations/versions/0012_2_9_0_adding_adding_max_failure_runs_column_.py index 1aff04a7cbe8c..2683110738e02 100644 --- a/airflow-core/src/airflow/migrations/versions/0012_2_9_0_adding_adding_max_failure_runs_column_.py +++ b/airflow-core/src/airflow/migrations/versions/0012_2_9_0_adding_adding_max_failure_runs_column_.py @@ -17,7 +17,7 @@ # under the License. """ -Adding max_consecutive_failed_dag_runs column to dag_model table. +Add max_consecutive_failed_dag_runs column to dag_model table. Revision ID: 8e1c784a4fc7 Revises: ab34f260b71c diff --git a/airflow-core/src/airflow/migrations/versions/0014_2_9_0_add_display_name_for_dag_and_task_.py b/airflow-core/src/airflow/migrations/versions/0014_2_9_0_add_display_name_for_dag_and_task_.py index 80ad5822ce469..43ec8985985b7 100644 --- a/airflow-core/src/airflow/migrations/versions/0014_2_9_0_add_display_name_for_dag_and_task_.py +++ b/airflow-core/src/airflow/migrations/versions/0014_2_9_0_add_display_name_for_dag_and_task_.py @@ -17,7 +17,7 @@ # under the License. """ -add display name for dag and task instance. +Add display name for dag and task instance. Revision ID: ee1467d4aa35 Revises: b4078ac230a1 diff --git a/airflow-core/src/airflow/migrations/versions/0015_2_9_0_update_trigger_kwargs_type.py b/airflow-core/src/airflow/migrations/versions/0015_2_9_0_update_trigger_kwargs_type.py index d90cd60c79bf1..5e3715137ca65 100644 --- a/airflow-core/src/airflow/migrations/versions/0015_2_9_0_update_trigger_kwargs_type.py +++ b/airflow-core/src/airflow/migrations/versions/0015_2_9_0_update_trigger_kwargs_type.py @@ -17,7 +17,7 @@ # under the License. """ -update trigger kwargs type and encrypt. +Update trigger kwargs type and encrypt. Revision ID: 1949afb29106 Revises: ee1467d4aa35 diff --git a/airflow-core/src/airflow/migrations/versions/0019_2_10_0_add_new_executor_field_to_db.py b/airflow-core/src/airflow/migrations/versions/0019_2_10_0_add_new_executor_field_to_db.py index 694f0f84f8f28..bfbd1ab650671 100644 --- a/airflow-core/src/airflow/migrations/versions/0019_2_10_0_add_new_executor_field_to_db.py +++ b/airflow-core/src/airflow/migrations/versions/0019_2_10_0_add_new_executor_field_to_db.py @@ -17,7 +17,7 @@ # under the License. """ -add new executor field to db. +Add new executor field to db. Revision ID: 677fdbb7fc54 Revises: 0fd0c178cbe8 diff --git a/airflow-core/src/airflow/migrations/versions/0020_2_10_0_added_dagpriorityparsingrequest_table.py b/airflow-core/src/airflow/migrations/versions/0020_2_10_0_added_dagpriorityparsingrequest_table.py index 6580c80973bcb..1be89322635f9 100644 --- a/airflow-core/src/airflow/migrations/versions/0020_2_10_0_added_dagpriorityparsingrequest_table.py +++ b/airflow-core/src/airflow/migrations/versions/0020_2_10_0_added_dagpriorityparsingrequest_table.py @@ -17,7 +17,7 @@ # under the License. """ -Added DagPriorityParsingRequest table. +Add DagPriorityParsingRequest table. Revision ID: c4602ba06b4b Revises: 677fdbb7fc54 diff --git a/airflow-core/src/airflow/migrations/versions/0043_3_0_0_remove_scheduler_lock_column.py b/airflow-core/src/airflow/migrations/versions/0043_3_0_0_remove_scheduler_lock_column.py index 12d1b16d9729d..9dcd8ce049cc4 100644 --- a/airflow-core/src/airflow/migrations/versions/0043_3_0_0_remove_scheduler_lock_column.py +++ b/airflow-core/src/airflow/migrations/versions/0043_3_0_0_remove_scheduler_lock_column.py @@ -17,7 +17,7 @@ # under the License. """ -remove scheduler_lock column. +Remove scheduler_lock column. Revision ID: 486ac7936b78 Revises: d59cbbef95eb diff --git a/airflow-core/src/airflow/migrations/versions/0047_3_0_0_add_dag_versioning.py b/airflow-core/src/airflow/migrations/versions/0047_3_0_0_add_dag_versioning.py index c666a260fa723..4deedb925ce76 100644 --- a/airflow-core/src/airflow/migrations/versions/0047_3_0_0_add_dag_versioning.py +++ b/airflow-core/src/airflow/migrations/versions/0047_3_0_0_add_dag_versioning.py @@ -17,7 +17,7 @@ # under the License. """ -add dag versioning. +Add dag versioning. Revision ID: 2b47dc6bc8df Revises: d03e4a635aa3 diff --git a/airflow-core/src/airflow/migrations/versions/0051_3_0_0_update_task_instance_trigger_timeout_to_utcdatetime.py b/airflow-core/src/airflow/migrations/versions/0051_3_0_0_update_task_instance_trigger_timeout_to_utcdatetime.py index 5a381577366eb..05872c4e259f5 100644 --- a/airflow-core/src/airflow/migrations/versions/0051_3_0_0_update_task_instance_trigger_timeout_to_utcdatetime.py +++ b/airflow-core/src/airflow/migrations/versions/0051_3_0_0_update_task_instance_trigger_timeout_to_utcdatetime.py @@ -17,7 +17,7 @@ # under the License. """ -update trigger_timeout column in task_instance table to UTC. +Update trigger_timeout column in task_instance table to UTC. Revision ID: 038dc8bc6284 Revises: e229247a6cb1 diff --git a/airflow-core/src/airflow/migrations/versions/0055_3_0_0_remove_pickled_data_from_dagrun_table.py b/airflow-core/src/airflow/migrations/versions/0055_3_0_0_remove_pickled_data_from_dagrun_table.py index 31b71e2bedc3b..95638963c05a9 100644 --- a/airflow-core/src/airflow/migrations/versions/0055_3_0_0_remove_pickled_data_from_dagrun_table.py +++ b/airflow-core/src/airflow/migrations/versions/0055_3_0_0_remove_pickled_data_from_dagrun_table.py @@ -17,7 +17,7 @@ # under the License. """ -remove pickled data from dagrun table. +Remove pickled data from dagrun table. Revision ID: e39a26ac59f6 Revises: 38770795785f diff --git a/airflow-core/src/airflow/migrations/versions/0057_3_0_0_add_new_task_instance_field_scheduled_.py b/airflow-core/src/airflow/migrations/versions/0057_3_0_0_add_new_task_instance_field_scheduled_.py index ca071a18d0dea..d3ea57cd8df3b 100644 --- a/airflow-core/src/airflow/migrations/versions/0057_3_0_0_add_new_task_instance_field_scheduled_.py +++ b/airflow-core/src/airflow/migrations/versions/0057_3_0_0_add_new_task_instance_field_scheduled_.py @@ -17,7 +17,7 @@ # under the License. """ -add new task_instance field scheduled_dttm. +Add new task_instance field scheduled_dttm. Revision ID: 33b04e4bfa19 Revises: 8ea135928435 diff --git a/airflow-core/src/airflow/migrations/versions/0059_3_0_0_remove_external_trigger_field.py b/airflow-core/src/airflow/migrations/versions/0059_3_0_0_remove_external_trigger_field.py index 46d3cd9ca57e4..7ca343a2b7855 100644 --- a/airflow-core/src/airflow/migrations/versions/0059_3_0_0_remove_external_trigger_field.py +++ b/airflow-core/src/airflow/migrations/versions/0059_3_0_0_remove_external_trigger_field.py @@ -17,7 +17,7 @@ # under the License. """ -remove external_trigger field. +Remove external_trigger field. Revision ID: e00344393f31 Revises: 6a9e7a527a88 diff --git a/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py b/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py index 1a922d97deed5..f2ca97e42cce3 100644 --- a/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py +++ b/airflow-core/src/airflow/migrations/versions/0084_3_1_0_add_last_parse_duration_to_dag_model.py @@ -17,7 +17,7 @@ # under the License. """ -add last_parse_duration to dag model. +Add last_parse_duration to dag model. Revision ID: eaf332f43c7c Revises: a3c7f2b18d4e diff --git a/airflow-core/src/airflow/migrations/versions/0088_3_2_0_replace_asset_trigger_table_with_asset.py b/airflow-core/src/airflow/migrations/versions/0088_3_2_0_replace_asset_trigger_table_with_asset.py index e4478f58da4a5..81c134741f4d2 100644 --- a/airflow-core/src/airflow/migrations/versions/0088_3_2_0_replace_asset_trigger_table_with_asset.py +++ b/airflow-core/src/airflow/migrations/versions/0088_3_2_0_replace_asset_trigger_table_with_asset.py @@ -17,7 +17,7 @@ # under the License. """ -replace asset_trigger table with asset_watcher. +Replace asset_trigger table with asset_watcher. Revision ID: 15d84ca19038 Revises: 509b94a1042d diff --git a/airflow-core/src/airflow/migrations/versions/0100_3_2_0_add_timetable_type_to_dag_table_for_.py b/airflow-core/src/airflow/migrations/versions/0100_3_2_0_add_timetable_type_to_dag_table_for_.py index 390b9d55bfd7a..6f6817a05f8d4 100644 --- a/airflow-core/src/airflow/migrations/versions/0100_3_2_0_add_timetable_type_to_dag_table_for_.py +++ b/airflow-core/src/airflow/migrations/versions/0100_3_2_0_add_timetable_type_to_dag_table_for_.py @@ -17,7 +17,7 @@ # under the License. """ -add timetable_type to dag table for filtering. +Add timetable_type to dag table for filtering. Revision ID: e79fc784f145 Revises: 0b112f49112d diff --git a/airflow-core/src/airflow/models/asset.py b/airflow-core/src/airflow/models/asset.py index 60256f9cd8852..5a48cbd4dacd2 100644 --- a/airflow-core/src/airflow/models/asset.py +++ b/airflow-core/src/airflow/models/asset.py @@ -912,9 +912,15 @@ class AssetPartitionDagRun(Base): We can look up the AssetEvents that contribute to AssetPartitionDagRun entities with the PartitionedAssetKeyLog mapping table. - Where dag_run_id is null, the dag run has not yet been created. - We should not allow more than one like this. But to guard against - an accident, we should always work on the latest one. + Rows are never deleted from this table, so multiple records with the same + target_dag_id / partition_key are expected in general; each dag run that + gets created leaves its APDR record behind. + + Where created_dag_run_id is null, the dag run has not yet been created. + We should not allow more than one row with the same target_dag_id / + partition_key where created_dag_run_id is null, and this is what the + `_lock_asset_model` mutex control is for. In case a duplicate somehow + gets created, we always work on the latest matching APDR record. """ id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) diff --git a/airflow-core/src/airflow/models/backfill.py b/airflow-core/src/airflow/models/backfill.py index 52019fa5d984b..13b9e6d004f6a 100644 --- a/airflow-core/src/airflow/models/backfill.py +++ b/airflow-core/src/airflow/models/backfill.py @@ -36,17 +36,18 @@ Integer, String, UniqueConstraint, + delete, func, select, ) -from sqlalchemy.exc import IntegrityError +from sqlalchemy.exc import IntegrityError, OperationalError from sqlalchemy.orm import Mapped, mapped_column, relationship, validates from airflow._shared.timezones import timezone from airflow.exceptions import AirflowException, DagNotFound, DagRunTypeNotAllowed from airflow.models.base import Base, StringID from airflow.utils.session import create_session -from airflow.utils.sqlalchemy import UtcDateTime, with_row_locks +from airflow.utils.sqlalchemy import UtcDateTime, is_lock_not_available_error, with_row_locks from airflow.utils.state import DagRunState from airflow.utils.types import DagRunTriggeredByType, DagRunType @@ -123,6 +124,17 @@ class InvalidBackfillConf(AirflowException): """ +class NoBackfillRunsToCreate(ValueError): + """ + Raised when a backfill request yields no Dag runs for the given date range. + + This happens when the from/to date range falls entirely outside the Dag's + scheduled intervals (e.g. the range predates the first partition boundary). + + :meta private: + """ + + class UnknownActiveBackfills(AirflowException): """ Raised when the quantity of active backfills cannot be determined. @@ -665,7 +677,18 @@ def _create_backfill( dag_run_conf, ) - br = Backfill( + dagrun_info_list = _get_info_list( + from_date=from_date, + to_date=to_date, + reverse=reverse, + dag=dag, + ) + if not dagrun_info_list: + raise NoBackfillRunsToCreate( + f"No runs to create for Dag {dag_id} in the range [{from_date}, {to_date}]" + ) + + backfill = Backfill( dag_id=dag_id, from_date=from_date, to_date=to_date, @@ -675,42 +698,58 @@ def _create_backfill( dag_model=dag, triggering_user_name=triggering_user_name, ) - session.add(br) + session.add(backfill) + # Commit immediately so the backfill is visible to concurrent requests + # checking num_active backfills, preventing duplicate active backfills + # for the same dag. session.commit() session.scalars(select(DagModel).where(DagModel.dag_id == dag_id)).one() - dagrun_info_list = _get_info_list( - from_date=from_date, - to_date=to_date, - reverse=reverse, - dag=dag, - ) - if not dagrun_info_list: - raise RuntimeError(f"No runs to create for Dag {dag_id}") - first_info = dagrun_info_list[0] - if first_info.partition_key: - _create_runs_partitioned( - br=br, - dag=dag, - dagrun_info_list=dagrun_info_list, - session=session, - ) - else: - _create_runs_non_partitioned( - br=br, - dag=dag, - dagrun_info_list=dagrun_info_list, - run_on_latest_version=run_on_latest_version, - session=session, - ) - return br + try: + if first_info.partition_key: + _create_runs_partitioned( + backfill=backfill, + dag=dag, + dagrun_info_list=dagrun_info_list, + session=session, + ) + else: + _create_runs_non_partitioned( + backfill=backfill, + dag=dag, + dagrun_info_list=dagrun_info_list, + run_on_latest_version=run_on_latest_version, + session=session, + ) + except OperationalError as e: + if is_lock_not_available_error(e): + # Lock error: clean up the orphan so the user can retry. The + # helper is best-effort; if it fails the original error still + # surfaces and the route returns 503. + _cleanup_partial_backfill(backfill, session) + raise + return backfill + + +def _cleanup_partial_backfill(backfill: Backfill, session: Session) -> None: + """Best-effort removal of a partially-created backfill after a lock error.""" + from airflow.models.dagrun import DagRun + + try: + session.rollback() + session.execute(delete(BackfillDagRun).where(BackfillDagRun.backfill_id == backfill.id)) + session.execute(delete(DagRun).where(DagRun.backfill_id == backfill.id)) + session.delete(backfill) + session.commit() + except Exception: + session.rollback() def _create_runs_partitioned( *, - br: Backfill, + backfill: Backfill, dag: SerializedDAG, dagrun_info_list: list[DagRunInfo], session: Session, @@ -722,24 +761,24 @@ def _create_runs_partitioned( _create_backfill_dag_run_partitioned( dag=dag, info=info, - backfill_id=br.id, - dag_run_conf=br.dag_run_conf, - reprocess_behavior=ReprocessBehavior(br.reprocess_behavior), + backfill_id=backfill.id, + dag_run_conf=backfill.dag_run_conf, + reprocess_behavior=ReprocessBehavior(backfill.reprocess_behavior), backfill_sort_ordinal=backfill_sort_ordinal, - triggering_user_name=br.triggering_user_name, + triggering_user_name=backfill.triggering_user_name, session=session, ) log.info( "Created backfill Dag run.", dag_id=dag.dag_id, - backfill_id=br.id, - info=info, + backfill_id=backfill.id, + logical_date=info.logical_date, ) def _create_runs_non_partitioned( *, - br: Backfill, + backfill: Backfill, dag: SerializedDAG, dagrun_info_list: list[DagRunInfo], run_on_latest_version: bool, @@ -753,17 +792,17 @@ def _create_runs_non_partitioned( _create_backfill_dag_run_non_partitioned( dag=dag, info=info, - backfill_id=br.id, - dag_run_conf=br.dag_run_conf, - reprocess_behavior=ReprocessBehavior(br.reprocess_behavior), + backfill_id=backfill.id, + dag_run_conf=backfill.dag_run_conf, + reprocess_behavior=ReprocessBehavior(backfill.reprocess_behavior), backfill_sort_ordinal=backfill_sort_ordinal, - triggering_user_name=br.triggering_user_name, + triggering_user_name=backfill.triggering_user_name, run_on_latest_version=run_on_latest_version, session=session, ) log.info( "Created backfill Dag run.", dag_id=dag.dag_id, - backfill_id=br.id, - info=info, + backfill_id=backfill.id, + logical_date=info.logical_date, ) diff --git a/airflow-core/src/airflow/models/dagrun.py b/airflow-core/src/airflow/models/dagrun.py index f5ae6a28d5824..ba176c9edfb08 100644 --- a/airflow-core/src/airflow/models/dagrun.py +++ b/airflow-core/src/airflow/models/dagrun.py @@ -1594,16 +1594,24 @@ def _expand_mapped_task_if_needed(ti: TI) -> Iterable[TI] | None: if new_tis is not None: additional_tis.extend(new_tis) expansion_happened = True + # Expansion changes a mapped task's instance count, which invalidates the + # trigger-rule upstream-count memo on this DepContext (a downstream evaluated + # later in this same pass must see the post-expansion count). + dep_context.invalidate_upstream_task_id_counts() if new_tis is None and schedulable.state in SCHEDULEABLE_STATES: # It's enough to revise map index once per task id, # checking the map index for each mapped task significantly slows down scheduling if schedulable.task.task_id not in revised_map_index_task_ids: - ready_tis.extend( - self._revise_map_indexes_if_mapped( - schedulable.task, dag_version_id=schedulable.dag_version_id, session=session - ) + revised_tis = self._revise_map_indexes_if_mapped( + schedulable.task, dag_version_id=schedulable.dag_version_id, session=session ) + ready_tis.extend(revised_tis) revised_map_index_task_ids.add(schedulable.task.task_id) + if revised_tis: + # Revising a mapped task can add new instances, growing its instance count + # the same way expansion does. Drop the upstream-count memo so a downstream + # evaluated later in this pass recomputes it instead of reading a stale value. + dep_context.invalidate_upstream_task_id_counts() # _revise_map_indexes_if_mapped might mark the current task as REMOVED # after calculating mapped task length, so we need to re-check @@ -2225,14 +2233,24 @@ def apply_partition_date_window( timetable: Timetable, start: datetime | None, end: datetime | None, + end_exclusive: bool = False, ) -> Select: - """Filter stmt to the inclusive interval [lower, upper] on partition_date.""" + """ + Filter stmt to a partition_date window bounded by *start* and *end*. + + The lower bound is always inclusive. The upper bound is inclusive by default; + pass ``end_exclusive=True`` when *end* is the open edge of the window, as with + a date-only filter widened to the following local midnight. + """ if start is not None: lower = timetable.localize_partition_datetime(start) stmt = stmt.where(DagRun.partition_date >= lower) if end is not None: upper = timetable.localize_partition_datetime(end) - stmt = stmt.where(DagRun.partition_date <= upper) + if end_exclusive: + stmt = stmt.where(DagRun.partition_date < upper) + else: + stmt = stmt.where(DagRun.partition_date <= upper) return stmt diff --git a/airflow-core/src/airflow/models/taskinstance.py b/airflow-core/src/airflow/models/taskinstance.py index f905e4c8e3d9c..7dae21baa2ccc 100644 --- a/airflow-core/src/airflow/models/taskinstance.py +++ b/airflow-core/src/airflow/models/taskinstance.py @@ -24,7 +24,7 @@ import math import warnings from collections import defaultdict -from collections.abc import Collection, Iterable +from collections.abc import Callable, Collection, Iterable, Sequence from datetime import datetime, timedelta from typing import TYPE_CHECKING, Any, NamedTuple from urllib.parse import quote @@ -1524,14 +1524,14 @@ def register_asset_changes_in_db( outlet_events: list[dict[str, Any]], *, session: Session = NEW_SESSION, - ) -> None: + ) -> Sequence[Callable[[], None]]: # Fast path: a task with no outlets and no outlet events has nothing to # register. Returning early avoids the AssetModel lookup below (which # would run with empty IN () clauses) and all downstream work. This is # the common case -- most tasks declare no outlets -- and it sits on the # task-success path that gates scheduling the next task. if not task_outlets and not outlet_events: - return + return () from airflow.serialization.definitions.assets import ( SerializedAsset, @@ -1557,6 +1557,7 @@ def register_asset_changes_in_db( dag_run_partition_key = ti.dag_run.partition_key dag_run_partition_date = ti.dag_run.partition_date + callback_sink: list[Callable[[], None]] = [] asset_keys = { SerializedAssetUniqueKey(o.name, o.uri) for o in task_outlets @@ -1592,6 +1593,7 @@ def _register(am: AssetModel, key: SerializedAssetUniqueKey) -> None: extra=None, partition_key=dag_run_partition_key, partition_date=dag_run_partition_date, + callback_sink=callback_sink, session=session, ) return @@ -1619,6 +1621,7 @@ def _register(am: AssetModel, key: SerializedAssetUniqueKey) -> None: extra=payload.extra, partition_key=effective_pk, partition_date=payload_partition_date, + callback_sink=callback_sink, session=session, ) @@ -1703,6 +1706,7 @@ def _asset_event_extras_from_aliases() -> dict[tuple[SerializedAssetUniqueKey, s extra=asset_event_extra, partition_key=dag_run_partition_key, partition_date=dag_run_partition_date, + callback_sink=callback_sink, session=session, ) if event is None: @@ -1716,9 +1720,12 @@ def _asset_event_extras_from_aliases() -> dict[tuple[SerializedAssetUniqueKey, s extra=asset_event_extra, partition_key=dag_run_partition_key, partition_date=dag_run_partition_date, + callback_sink=callback_sink, session=session, ) + return callback_sink + @provide_session def update_rtif(self, rendered_fields, *, session: Session = NEW_SESSION): from airflow.models.renderedtifields import RenderedTaskInstanceFields @@ -2281,9 +2288,8 @@ def duration_expression_update( return query.values( { "end_date": end_date, - "duration": ( - (func.strftime("%s", end_date) - func.strftime("%s", cls.start_date)) - + func.round((func.strftime("%f", end_date) - func.strftime("%f", cls.start_date)), 3) + "duration": func.round( + (func.julianday(end_date) - func.julianday(cls.start_date)) * 86400, 3 ), } ) diff --git a/airflow-core/src/airflow/models/taskinstancehistory.py b/airflow-core/src/airflow/models/taskinstancehistory.py index b0d55114bb6b1..47cfdb68ae577 100644 --- a/airflow-core/src/airflow/models/taskinstancehistory.py +++ b/airflow-core/src/airflow/models/taskinstancehistory.py @@ -211,8 +211,11 @@ def record_ti(ti: TaskInstance, *, session: Session = NEW_SESSION) -> None: ti_history_state = ti.state if ti.state not in State.finished: ti_history_state = TaskInstanceState.FAILED - ti.end_date = timezone.utcnow() - ti.set_duration() + # Callers that know when the try actually ended (e.g. the Execution API + # retry path) pre-set end_date and duration; only stamp archive time when unset. + if ti.end_date is None: + ti.end_date = timezone.utcnow() + ti.set_duration() ti_history = TaskInstanceHistory(ti, state=ti_history_state) session.add(ti_history) diff --git a/airflow-core/src/airflow/models/trigger.py b/airflow-core/src/airflow/models/trigger.py index 6fecd4d825f09..c7039750b4eae 100644 --- a/airflow-core/src/airflow/models/trigger.py +++ b/airflow-core/src/airflow/models/trigger.py @@ -35,7 +35,7 @@ from airflow.models.asset import AssetWatcherModel from airflow.models.base import Base from airflow.models.taskinstance import TaskInstance -from airflow.serialization.enums import stringify_encoding_keys as _stringify_encoding_keys +from airflow.serialization.enums import stringify_encoding_keys from airflow.triggers.base import BaseTaskEndEvent from airflow.utils.retries import run_with_db_retries from airflow.utils.session import NEW_SESSION, provide_session @@ -158,7 +158,7 @@ def encrypt_kwargs(kwargs: dict[str, Any]) -> str: from airflow.models.crypto import get_fernet from airflow.sdk.serde import serialize - serialized_kwargs = serialize(_stringify_encoding_keys(kwargs)) + serialized_kwargs = serialize(stringify_encoding_keys(kwargs)) return get_fernet().encrypt(json.dumps(serialized_kwargs).encode("utf-8")).decode("utf-8") @staticmethod @@ -250,13 +250,12 @@ def clean_unused(cls, *, session: Session = NEW_SESSION) -> None: ) # Get all triggers that have no task instances, assets, or callbacks depending on them and delete them - ids = ( - select(cls.id) - .where(~cls.assets.any(), ~cls.callback.has()) - .join(TaskInstance, cls.id == TaskInstance.trigger_id, isouter=True) - .group_by(cls.id) - .having(func.count(TaskInstance.trigger_id) == 0) + ids = select(cls.id).where( + ~cls.assets.any(), + ~cls.callback.has(), + ~cls.task_instance.has(), ) + ids = with_row_locks(ids, session, of=cls, skip_locked=True, key_share=False) if get_dialect_name(session) == "mysql": # MySQL doesn't support DELETE with JOIN, so we need to do it in two steps ids_list = list(session.scalars(ids).all()) @@ -286,7 +285,11 @@ def submit_event(cls, trigger_id, event: TriggerEvent, *, session: Session = NEW handle_event_submit(event, task_instance=task_instance, session=session) # Send an event to assets - trigger = session.scalars(select(cls).where(cls.id == trigger_id)).one_or_none() + trigger = session.scalars( + select(cls) + .where(cls.id == trigger_id) + .options(selectinload(cls.asset_watchers).selectinload(AssetWatcherModel.asset)) + ).one_or_none() if trigger is None: # Already deleted for some reason return @@ -497,6 +500,55 @@ def get_sorted_triggers( return result +def _decode_next_kwargs(next_kwargs_raw: Any) -> dict[str, Any]: + """ + Decode the stored ``next_kwargs`` of a task instance into a plain dict. + + Deserialize with serde first to provide a compat layer if there are mixed serialized + (BaseSerialisation and serde) data, which can happen if a deferred task resumes after upgrade. + + The result is checked here rather than assumed, so callers never have to trust the shape of + what comes back out of the stored payload. + + :raise ValueError: The payload did not decode to a dict. + :raise Exception: Whatever the two decoders raise on a payload they cannot read -- the stored + blob is arbitrary, so the set is open and callers have to treat it as such. + """ + from airflow.sdk.serde import deserialize + + try: + next_kwargs = deserialize(next_kwargs_raw) + except (ImportError, KeyError, AttributeError, TypeError): + from airflow.serialization.serialized_objects import BaseSerialization + + next_kwargs = BaseSerialization.deserialize(next_kwargs_raw) + + if not isinstance(next_kwargs, dict): + raise ValueError(f"next_kwargs decoded to {type(next_kwargs).__name__}, expected a dict") + return next_kwargs + + +def _fail_unresumable_task_instance( + task_instance: TaskInstance, reason: str, exc: BaseException, *, session: Session +) -> None: + """ + Route through ``__fail__`` so a worker fails the task normally instead of stranding it. + + Mirrors ``Trigger.submit_failure``: without this the task is left with no event to resume it. + Traceback goes into ``next_kwargs`` as a list -- the only channel reaching the task log -- + since ``format_exception`` returns it that way and the runtime joins it. + """ + task_instance.next_method = TRIGGER_FAIL_REPR + task_instance.next_kwargs = { + "error": reason, + "traceback": format_exception(type(exc), exc, exc.__traceback__), + } + task_instance.trigger_id = None + task_instance.state = TaskInstanceState.SCHEDULED + task_instance.scheduled_dttm = timezone.utcnow() + session.flush() + + @singledispatch def handle_event_submit(event: TriggerEvent, *, task_instance: TaskInstance, session: Session) -> None: """ @@ -506,33 +558,66 @@ def handle_event_submit(event: TriggerEvent, *, task_instance: TaskInstance, ses as well as its state to scheduled. It also adds the event's payload into the kwargs for the task. + A task instance whose stored kwargs cannot be decoded, or which the event payload cannot be + encoded into, is failed rather than resumed. This runs in the triggerer, the scheduler and the + API processes, each of which handles every waiting task instance in one pass, so a single + unusable payload must not be able to abort the caller. The triggerer had the worst of it: an + event whose submit raised was left unconfirmed and redelivered indefinitely. + + Failing the task instance is not free for every caller: a Human-in-the-loop response whose + ``params_input`` serde cannot encode is now recorded and discarded rather than rejected, which + the submitter cannot retry. That wants validating on the write side; tracked at + https://github.com/apache/airflow/issues/71036 + :param task_instance: The task instance to handle the submit event for. :param session: The session to be used for the database callback sink. """ - from airflow.sdk.serde import deserialize, serialize - from airflow.utils.state import TaskInstanceState + from airflow.sdk.serde import serialize next_kwargs_raw = task_instance.next_kwargs or {} - # deserialize first to provide a compat layer if there are mixed serialized (BaseSerialisation and serde) data - # which can happen if a deferred task resumes after upgrade + # Decoding and re-encoding fail for different reasons and are reported separately: blaming the + # stored kwargs for a payload the trigger just yielded would point the author at DB state that + # was never the problem. try: - next_kwargs = deserialize(next_kwargs_raw) - except (ImportError, KeyError, AttributeError, TypeError): - from airflow.serialization.serialized_objects import BaseSerialization - - next_kwargs = BaseSerialization.deserialize(next_kwargs_raw) + next_kwargs = _decode_next_kwargs(next_kwargs_raw) + except Exception as exc: + log.exception( + "Could not decode the stored next_kwargs of %s; failing it instead of resuming it", + task_instance, + ) + _fail_unresumable_task_instance( + task_instance, + "Could not resume the task: its stored next_kwargs could not be decoded " + f"({type(exc).__name__}: {exc})", + exc, + session=session, + ) + return # Add event to the plain dict, then serialize everything together so nested # non-primitive values get proper serde encoding. - if TYPE_CHECKING: - assert isinstance(next_kwargs, dict) next_kwargs["event"] = event.payload + try: + # Re-serialize using serde. The Execution API version converter + # (ModifyDeferredTaskKwargsToJsonValue) handles converting this to + # BaseSerialization format when serving old workers. + serialized_next_kwargs = serialize(next_kwargs) + except Exception as exc: + log.exception( + "Could not serialize the event payload for %s; failing it instead of resuming it", + task_instance, + ) + _fail_unresumable_task_instance( + task_instance, + f"Could not resume the task: the event payload could not be serialized " + f"({type(exc).__name__}: {exc})", + exc, + session=session, + ) + return - # Re-serialize using serde. The Execution API version converter - # (ModifyDeferredTaskKwargsToJsonValue) handles converting this to - # BaseSerialization format when serving old workers. - task_instance.next_kwargs = serialize(next_kwargs) + task_instance.next_kwargs = serialized_next_kwargs # Remove ourselves as its trigger task_instance.trigger_id = None @@ -557,19 +642,41 @@ def _(event: BaseTaskEndEvent, *, task_instance: TaskInstance, session: Session) from airflow.callbacks.database_callback_sink import DatabaseCallbackSink from airflow.utils.state import TaskInstanceState - # Mark the task with terminal state and prevent it from resuming on worker + # Prevent the task from resuming on a worker. task_instance.trigger_id = None - task_instance.set_state(event.task_instance_state, session=session) + + callback_type = event.task_instance_state + should_retry = False + + if event.task_instance_state == TaskInstanceState.FAILED: + # Load the serialized task so retry eligibility matches the normal task path. + try: + from airflow.models.dagbag import DBDagBag + + dag = DBDagBag().get_dag_for_run(dag_run=task_instance.dag_run, session=session) + if dag is not None: + task_instance.task = dag.get_task(task_instance.task_id) + should_retry = task_instance.is_eligible_to_retry() + except Exception: + log.exception( + "Could not load task for %s; failing terminally without retry routing", task_instance + ) + if should_retry: + callback_type = TaskInstanceState.UP_FOR_RETRY def _submit_callback_if_necessary() -> None: - """Submit a callback request if the task state is SUCCESS or FAILED.""" - if event.task_instance_state in (TaskInstanceState.SUCCESS, TaskInstanceState.FAILED): + """Submit a callback request if the task state is SUCCESS, FAILED, or UP_FOR_RETRY.""" + if callback_type in ( + TaskInstanceState.SUCCESS, + TaskInstanceState.FAILED, + TaskInstanceState.UP_FOR_RETRY, + ): if task_instance.dag_model.relative_fileloc is None: raise RuntimeError("relative_fileloc should not be None for a finished task") request = TaskCallbackRequest( filepath=task_instance.dag_model.relative_fileloc, ti=task_instance, - task_callback_type=event.task_instance_state, + task_callback_type=callback_type, bundle_name=task_instance.dag_model.bundle_name, bundle_version=task_instance.dag_run.bundle_version, ) @@ -581,10 +688,22 @@ def _submit_callback_if_necessary() -> None: def _push_xcoms_if_necessary() -> None: """Pushes XComs to the database if they are provided.""" - if event.xcoms: + if event.xcoms and callback_type != TaskInstanceState.UP_FOR_RETRY: for key, value in event.xcoms.items(): task_instance.xcom_push(key=key, value=value) + # Send the callback before mutating task state so it reflects the retry-vs-terminal + # decision derived above. _submit_callback_if_necessary() + + if should_retry: + task_instance.end_date = timezone.utcnow() + task_instance.set_duration() + task_instance.clear_next_method_args() + task_instance.prepare_db_for_next_try(session) + task_instance.state = TaskInstanceState.UP_FOR_RETRY + else: + task_instance.set_state(event.task_instance_state, session=session) + _push_xcoms_if_necessary() session.flush() diff --git a/airflow-core/src/airflow/partition_mappers/__init__.py b/airflow-core/src/airflow/partition_mappers/__init__.py index f780603870736..fe2157ee98c56 100644 --- a/airflow-core/src/airflow/partition_mappers/__init__.py +++ b/airflow-core/src/airflow/partition_mappers/__init__.py @@ -23,6 +23,7 @@ from airflow.partition_mappers.identity import IdentityMapper from airflow.partition_mappers.product import ProductMapper from airflow.partition_mappers.temporal import ( + FanOutMapper, StartOfDayMapper, StartOfHourMapper, StartOfMonthMapper, @@ -30,6 +31,7 @@ StartOfWeekMapper, StartOfYearMapper, ) +from airflow.partition_mappers.wait_policy import MinimumCount, WaitForAll from airflow.partition_mappers.window import ( DayWindow, HourWindow, @@ -45,9 +47,11 @@ "AllowedKeyMapper", "ChainMapper", "DayWindow", + "FanOutMapper", "FixedKeyMapper", "HourWindow", "IdentityMapper", + "MinimumCount", "MonthWindow", "PartitionMapper", "ProductMapper", @@ -60,6 +64,7 @@ "StartOfQuarterMapper", "StartOfWeekMapper", "StartOfYearMapper", + "WaitForAll", "WeekWindow", "Window", "YearWindow", diff --git a/airflow-core/src/airflow/partition_mappers/base.py b/airflow-core/src/airflow/partition_mappers/base.py index b0edd02f645c6..c773ef7e86777 100644 --- a/airflow-core/src/airflow/partition_mappers/base.py +++ b/airflow-core/src/airflow/partition_mappers/base.py @@ -38,10 +38,12 @@ class PartitionMapper(ABC): is_rollup: ClassVar[bool] = False - # Class-level default so the attribute resolves even on subclasses whose - # __init__ (e.g. attrs-generated in plugins) never calls this base __init__. max_downstream_keys: int | None = None + # Declared result type of decode_downstream; RollupMapper rejects windows + # whose expected_decoded_type does not match. Temporal mappers use datetime. + expected_decoded_type: ClassVar[type] = str + def __init__(self, *, max_downstream_keys: int | None = None) -> None: if max_downstream_keys is not None and ( not isinstance(max_downstream_keys, int) or max_downstream_keys < 1 @@ -168,16 +170,13 @@ def __init__( wait_policy: WaitPolicy | None = None, max_downstream_keys: int | None = None, ) -> None: - decode_overridden = type(upstream_mapper).decode_downstream is not PartitionMapper.decode_downstream - if not decode_overridden and window.expected_decoded_type is not str: + if upstream_mapper.expected_decoded_type is not window.expected_decoded_type: raise TypeError( f"{type(window).__name__} expects decoded values of type " f"{window.expected_decoded_type.__name__!r}, but " - f"{type(upstream_mapper).__name__} does not override " - f"'decode_downstream' (base default returns str). Pair the window " - f"with an upstream mapper that decodes to " - f"{window.expected_decoded_type.__name__}, or use a window whose " - f"'expected_decoded_type' accepts str." + f"{type(upstream_mapper).__name__} decodes to " + f"{upstream_mapper.expected_decoded_type.__name__!r}. Pair a window and an " + f"upstream mapper whose 'expected_decoded_type' match." ) if wait_policy is None: wait_policy = WaitForAll() diff --git a/airflow-core/src/airflow/partition_mappers/temporal.py b/airflow-core/src/airflow/partition_mappers/temporal.py index 1938a18f84da8..09f1897a590f0 100644 --- a/airflow-core/src/airflow/partition_mappers/temporal.py +++ b/airflow-core/src/airflow/partition_mappers/temporal.py @@ -155,6 +155,8 @@ def _compile_output_format_regex( class _BaseTemporalMapper(PartitionMapper): """Base class for Temporal Partition Mappers.""" + expected_decoded_type: ClassVar[type] = datetime + default_output_format: str def __init__( @@ -469,9 +471,11 @@ class FanOutMapper(PartitionMapper): is N→1 (downstream waits until all members arrive), fan-out is 1→N (one upstream event creates one downstream Dag run per member). - For forward fan-out (emit the trailing period ending at the upstream key, - instead of the period it represents), pass ``direction=Window.Direction.FORWARD`` - to the window: + ``window``'s direction controls which period each upstream key fans out to. + The default, ``Window.Direction.FORWARD``, yields the period *starting at* + the upstream key (the period it represents); ``Window.Direction.BACKWARD`` + yields the trailing period *ending at* the upstream key. Pass + ``direction=Window.Direction.BACKWARD`` to the window for the latter: .. code-block:: python @@ -482,8 +486,8 @@ class FanOutMapper(PartitionMapper): FanOutMapper(upstream_mapper=StartOfWeekMapper(), window=WeekWindow()) # Weekly upstream → the 7 days ending at the upstream Monday (trailing period) - forward_window = WeekWindow(direction=Window.Direction.FORWARD) - FanOutMapper(upstream_mapper=StartOfWeekMapper(), window=forward_window) + backward_window = WeekWindow(direction=Window.Direction.BACKWARD) + FanOutMapper(upstream_mapper=StartOfWeekMapper(), window=backward_window) """ # Keep ``FanOutMapper.default_downstream_mapper_by_window_name`` in sync with diff --git a/airflow-core/src/airflow/secrets/environment_variables.py b/airflow-core/src/airflow/secrets/environment_variables.py index 5fb85732d712e..6eb36978d9862 100644 --- a/airflow-core/src/airflow/secrets/environment_variables.py +++ b/airflow-core/src/airflow/secrets/environment_variables.py @@ -20,19 +20,35 @@ from __future__ import annotations import os -import re +from airflow.configuration import conf from airflow.secrets import BaseSecretsBackend CONN_ENV_PREFIX = "AIRFLOW_CONN_" VAR_ENV_PREFIX = "AIRFLOW_VAR_" +# Separates the team name from the secret id in a team namespaced environment variable +# name: AIRFLOW_CONN_____. +TEAM_SEP = "___" + class EnvironmentVariablesBackend(BaseSecretsBackend): """Retrieves Connection object and Variable from environment variable.""" + @staticmethod + def _names_a_team_namespace(secret_id: str) -> bool: + """ + Whether ``secret_id`` spells out a team scoped secret name. + + Only checked in multi-team mode: ``team_name`` is never non-``None`` otherwise, so no + team scoped variable can exist to collide with. + """ + if not conf.getboolean("core", "multi_team", fallback=False): + return False + return TEAM_SEP in secret_id + def get_conn_value(self, conn_id: str, team_name: str | None = None) -> str | None: - if self._is_team_specific_accessed_as_global(conn_id, team_name): + if self._names_a_team_namespace(conn_id): return None if team_name and ( @@ -51,7 +67,7 @@ def get_variable(self, key: str, team_name: str | None = None) -> str | None: :param team_name: Team name associated to the task trying to access the variable (if any) :return: Variable Value """ - if self._is_team_specific_accessed_as_global(key, team_name): + if self._names_a_team_namespace(key): return None if team_name and ( @@ -61,7 +77,3 @@ def get_variable(self, key: str, team_name: str | None = None) -> str | None: return team_var return os.environ.get(VAR_ENV_PREFIX + key.upper()) - - @staticmethod - def _is_team_specific_accessed_as_global(secret_id: str, team_name: str | None = None) -> bool: - return team_name is None and bool(re.fullmatch(r"_[^_]+___.+", secret_id)) diff --git a/airflow-core/src/airflow/secrets/local_filesystem.py b/airflow-core/src/airflow/secrets/local_filesystem.py index dc247d969be00..8e4fe314ce1cf 100644 --- a/airflow-core/src/airflow/secrets/local_filesystem.py +++ b/airflow-core/src/airflow/secrets/local_filesystem.py @@ -316,6 +316,7 @@ class LocalFilesystemBackend(BaseSecretsBackend, LoggingMixin): :param variables_file_path: File location with variables data. :param connections_file_path: File location with connection data. + :param configs_file_path: File location with configuration data. """ def __init__( diff --git a/airflow-core/src/airflow/serialization/decoders.py b/airflow-core/src/airflow/serialization/decoders.py index 890a1296a4a00..78ae241813c24 100644 --- a/airflow-core/src/airflow/serialization/decoders.py +++ b/airflow-core/src/airflow/serialization/decoders.py @@ -90,9 +90,28 @@ def smart_decode_trigger_kwargs(d): """ from airflow.serialization.serialized_objects import BaseSerialization - if not isinstance(d, dict) or Encoding.TYPE not in d: + d = _normalize_stringified_encoding_keys(d) + if not isinstance(d, dict): return d - return BaseSerialization.deserialize(d) + if Encoding.TYPE in d and Encoding.VAR in d: + return BaseSerialization.deserialize(d) + return {k: smart_decode_trigger_kwargs(v) for k, v in d.items()} + + +def _normalize_stringified_encoding_keys(value): + if isinstance(value, list): + return [_normalize_stringified_encoding_keys(v) for v in value] + if not isinstance(value, dict): + return value + + if str(Encoding.TYPE) in value and str(Encoding.VAR) in value: + return { + Encoding.TYPE if k == str(Encoding.TYPE) else Encoding.VAR if k == str(Encoding.VAR) else k: ( + _normalize_stringified_encoding_keys(v) + ) + for k, v in value.items() + } + return {k: _normalize_stringified_encoding_keys(v) for k, v in value.items()} def _decode_asset(var: dict[str, Any]): diff --git a/airflow-core/src/airflow/serialization/definitions/taskgroup.py b/airflow-core/src/airflow/serialization/definitions/taskgroup.py index 65d59cb15f17e..0e0ae06572dc8 100644 --- a/airflow-core/src/airflow/serialization/definitions/taskgroup.py +++ b/airflow-core/src/airflow/serialization/definitions/taskgroup.py @@ -27,6 +27,7 @@ import attrs import methodtools +from airflow._shared.dagnode.node import TaskGroupMixin from airflow.serialization.definitions.node import DAGNode if TYPE_CHECKING: @@ -38,7 +39,7 @@ @attrs.define(eq=False, hash=False, kw_only=True) -class SerializedTaskGroup(DAGNode): +class SerializedTaskGroup(TaskGroupMixin, DAGNode): """Serialized representation of a TaskGroup used in protected processes.""" _group_id: str | None = attrs.field(alias="group_id") @@ -215,7 +216,9 @@ def iter_mapped_task_groups(self) -> Iterator[SerializedMappedTaskGroup]: yield group group = group.parent_group - def topological_sort(self) -> list[DAGNode]: + def topological_sort( + self, *, group_dict: dict[str | None, SerializedTaskGroup] | None = None + ) -> list[DAGNode]: """ Sort children topologically — a task always comes after its upstream dependencies. @@ -231,11 +234,13 @@ def topological_sort(self) -> list[DAGNode]: nodes = list(children.values()) n = len(nodes) id_to_idx = {nid: i for i, nid in enumerate(children)} + if group_dict is None: + group_dict = self.dag.task_group.get_task_group_dict() projected: list[tuple[int, ...]] = [()] * n nodes_with_back_edge = 0 for i, child in enumerate(nodes): - deps = self._project_child_deps(i, child, id_to_idx) + deps = self._project_child_deps(i, child, id_to_idx, group_dict) if deps: projected[i] = deps if any(d > i for d in deps): @@ -248,9 +253,13 @@ def topological_sort(self) -> list[DAGNode]: return self._sweep_projection(nodes, projected) def _project_child_deps( - self, child_idx: int, child: DAGNode, id_to_idx: dict[str, int] + self, + child_idx: int, + child: DAGNode, + id_to_idx: dict[str, int], + group_dict: dict[str | None, SerializedTaskGroup], ) -> tuple[int, ...]: - upstream_ids = child.upstream_task_ids + upstream_ids = child._topological_upstream_ids if not upstream_ids: return () sib_deps: set[int] = set() @@ -260,8 +269,10 @@ def _project_child_deps( if j != child_idx: sib_deps.add(j) continue - edge = self.dag.get_task(edge_id) - tg = edge.task_group + tg = group_dict.get(edge_id) + if tg is None: + edge = self.dag.get_task(edge_id) + tg = edge.task_group while tg is not None: anc_idx = id_to_idx.get(tg.node_id) if anc_idx is not None: diff --git a/airflow-core/src/airflow/serialization/serialized_objects.py b/airflow-core/src/airflow/serialization/serialized_objects.py index 54bc3389c64ce..f42e51e28f7d0 100644 --- a/airflow-core/src/airflow/serialization/serialized_objects.py +++ b/airflow-core/src/airflow/serialization/serialized_objects.py @@ -41,7 +41,7 @@ from dateutil import relativedelta from pendulum.tz.timezone import FixedTimezone, Timezone -from airflow._shared.module_loading import import_string, qualname +from airflow._shared.module_loading import qualname from airflow._shared.timezones.timezone import from_timestamp, parse_timezone, utcnow from airflow.callbacks.callback_requests import DagCallbackRequest, TaskCallbackRequest from airflow.exceptions import AirflowException, DeserializationError, SerializationError @@ -242,6 +242,31 @@ def _decode_priority_weight_strategy(var: str) -> PriorityWeightStrategy: return priority_weight_strategy_class() +# Builtin exceptions a BASE_EXC_SER node can rebuild into. A user defined subclass +# (e.g. a custom KeyError) serializes to a name absent here and won't round-trip -- +# unchanged from before, since builtins never held it either. +_DESERIALIZABLE_BUILTIN_EXCEPTIONS: dict[str, type[BaseException]] = { + "KeyError": KeyError, + "AttributeError": AttributeError, +} + + +def _resolve_airflow_exception(exc_cls_name: str) -> type[AirflowException]: + """ + Resolve a stored ``AirflowException`` name without importing it. + + Read via ``vars()`` rather than ``getattr`` -- a module's deprecation-shim + ``__getattr__`` can still import on access -- which also lets pre-3.2.0 blobs + naming the old ``airflow.exceptions`` path keep resolving. + """ + module_name, _, attr_name = exc_cls_name.rpartition(".") + module = sys.modules.get(module_name) + exc_cls = vars(module).get(attr_name) if module is not None else None + if not (isinstance(exc_cls, type) and issubclass(exc_cls, AirflowException)): + raise DeserializationError(f"Refusing to deserialize unknown exception class {exc_cls_name!r}") + return exc_cls + + def _encode_start_trigger_args(var: StartTriggerArgs) -> dict[str, Any]: """Encode a StartTriggerArgs.""" @@ -664,9 +689,14 @@ def deserialize(cls, encoded_var: Any) -> Any: kwargs = deser["kwargs"] del deser if type_ == DAT.AIRFLOW_EXC_SER: - exc_cls = import_string(exc_cls_name) + exc_cls: type[BaseException] = _resolve_airflow_exception(exc_cls_name) else: - exc_cls = import_string(f"builtins.{exc_cls_name}") + builtin_exc_cls = _DESERIALIZABLE_BUILTIN_EXCEPTIONS.get(exc_cls_name) + if builtin_exc_cls is None: + raise DeserializationError( + f"Refusing to deserialize unsupported builtin exception {exc_cls_name!r}" + ) + exc_cls = builtin_exc_cls return exc_cls(*args, **kwargs) elif type_ == DAT.SET: return {cls.deserialize(v) for v in var} diff --git a/airflow-core/src/airflow/ti_deps/dep_context.py b/airflow-core/src/airflow/ti_deps/dep_context.py index 1feafdd041ae1..3f0d6e8b46fbb 100644 --- a/airflow-core/src/airflow/ti_deps/dep_context.py +++ b/airflow-core/src/airflow/ti_deps/dep_context.py @@ -85,6 +85,28 @@ class DepContext: have_changed_ti_states: bool = False """Have any of the TIs state's been changed as a result of evaluating dependencies""" + upstream_task_id_counts: dict[tuple[str, str, frozenset[str]], list[tuple[str, int]]] = attr.ib( + factory=dict, repr=False + ) + """ + Per-pass memo of the trigger-rule upstream task-instance counts, keyed by + ``(dag_id, run_id, frozenset of direct-upstream task_ids)``. + + Only populated for the "simple" case where the count-query predicate is exactly + ``task_id IN (upstream_ids)`` and is therefore identical for every downstream sharing the same + direct upstreams; the mapped-task-group case uses per-ti map-index predicates and is not cached. + + Lifetime is one scheduling pass, like ``finished_tis``, but note it is not a snapshot handed in + by the caller: it is filled in as dependencies are evaluated, and invalidated via + :meth:`invalidate_upstream_task_id_counts` when a mapped task's instance count changes mid-pass. + + This is deliberately an ``init=True`` field even though callers never pass it. ``attrs.evolve`` + only carries over fields that ``__init__`` accepts, and + :meth:`~airflow.models.taskinstance.TaskInstance.are_dependencies_met` evolves the context for + every ``UP_FOR_RESCHEDULE`` task instance. With ``init=False`` those instances would each get a + fresh empty dict, so they would neither read the memo nor warm it for anything else. + """ + def ensure_finished_tis(self, dag_run: DagRun, session: Session) -> list[TaskInstance]: """ Ensure finished_tis is populated if it's currently None, which allows running tasks without dag_run. @@ -103,3 +125,12 @@ def ensure_finished_tis(self, dag_run: DagRun, session: Session) -> list[TaskIns else: finished_tis = self.finished_tis return finished_tis + + def invalidate_upstream_task_id_counts(self) -> None: + """ + Drop the memoized trigger-rule upstream counts. + + Call this whenever a mapped task's instance count changes mid-pass, so a downstream evaluated + later in the same pass recomputes the count instead of reading a stale one. + """ + self.upstream_task_id_counts.clear() diff --git a/airflow-core/src/airflow/ti_deps/deps/trigger_rule_dep.py b/airflow-core/src/airflow/ti_deps/deps/trigger_rule_dep.py index 54d5a4d930920..f49b71f7ca9a2 100644 --- a/airflow-core/src/airflow/ti_deps/deps/trigger_rule_dep.py +++ b/airflow-core/src/airflow/ti_deps/deps/trigger_rule_dep.py @@ -20,7 +20,7 @@ import collections.abc import functools from collections import Counter -from collections.abc import Iterator, KeysView, Mapping, Sequence +from collections.abc import Iterator, KeysView, Mapping from typing import TYPE_CHECKING, NamedTuple from sqlalchemy import and_, func, or_, select @@ -31,16 +31,14 @@ from airflow.utils.state import TaskInstanceState if TYPE_CHECKING: - from sqlalchemy.engine import Row from sqlalchemy.orm import Session from sqlalchemy.sql import ColumnElement from airflow.models.taskinstance import TaskInstance from airflow.serialization.definitions.mappedoperator import Operator - from airflow.serialization.definitions.taskgroup import SerializedMappedTaskGroup + from airflow.serialization.definitions.taskgroup import SerializedTaskGroup from airflow.ti_deps.dep_context import DepContext from airflow.ti_deps.deps.base_ti_dep import TIDepStatus - from airflow.typing_compat import Unpack class _UpstreamTIStates(NamedTuple): @@ -152,7 +150,7 @@ def _get_expanded_ti_count() -> int: return get_mapped_ti_count(task, ti.run_id, session=session) - def _iter_expansion_dependencies(task_group: SerializedMappedTaskGroup | None) -> Iterator[str]: + def _iter_expansion_dependencies(task_group: SerializedTaskGroup | None) -> Iterator[str]: if is_mapped(task): for op in task.iter_mapped_dependencies(): yield op.task_id @@ -177,14 +175,22 @@ def _get_relevant_upstream_map_indexes(upstream_id: str) -> int | range | None: assert task.task_group # Only the not-yet-expanded summary ti (map_index < 0) needs the broad - # "depend on every upstream ti" behavior, so a fast-triggered rule - # (ONE_SUCCESS / ONE_FAILED / ONE_DONE) does not skip it before the - # mapped task group has expanded (see #34023). Once the ti is expanded, - # each instance must depend on the upstream instance(s) that share its - # map index, otherwise a single upstream failure would wrongly trigger - # every expanded instance (see #50210). - if is_mapped(task.task_group) and ti.map_index < 0: - is_fast_triggered = task.trigger_rule in (TR.ONE_SUCCESS, TR.ONE_FAILED, TR.ONE_DONE) + # "depend on every upstream ti" behavior, so a rule that can be satisfied + # by a subset of upstreams (ONE_SUCCESS / ONE_FAILED / ONE_DONE / + # NONE_FAILED_MIN_ONE_SUCCESS) does not skip it before the mapped task + # group has expanded (see #34023, #39801). Once the ti is expanded, each + # instance must depend on the upstream instance(s) that share its map + # index, otherwise a single upstream failure would wrongly trigger every + # expanded instance (see #50210). The task may be nested in plain task + # groups inside the mapped one (see #39801), so check the closest mapped + # ancestor rather than only the immediate parent group. + if ti.map_index < 0 and task.get_closest_mapped_task_group() is not None: + is_fast_triggered = task.trigger_rule in ( + TR.ONE_SUCCESS, + TR.ONE_FAILED, + TR.ONE_DONE, + TR.NONE_FAILED_MIN_ONE_SUCCESS, + ) if is_fast_triggered and upstream_id not in set( _iter_expansion_dependencies(task_group=task.task_group) ): @@ -382,13 +388,37 @@ def _evaluate_direct_relatives() -> Iterator[TIDepStatus]: upstream = len(upstream_tasks) upstream_setup = sum(1 for x in upstream_tasks.values() if x.is_setup) else: - # The below type annotation is acceptable on SQLA2.1, but not on 2.0 - task_id_counts: Sequence[Row[Unpack[tuple[str, int]]]] = session.execute( # type: ignore[type-arg] - select(TaskInstance.task_id, func.count(TaskInstance.task_id)) - .where(TaskInstance.dag_id == ti.dag_id, TaskInstance.run_id == ti.run_id) - .where(or_(*_iter_upstream_conditions(relevant_tasks=upstream_tasks))) - .group_by(TaskInstance.task_id) - ).all() + # In the simple case, `_iter_upstream_conditions` emits exactly + # `task_id IN (upstream_task_ids)` (the matching `get_closest_mapped_task_group() + # is None` branch). That predicate, and therefore the resulting counts, are + # identical for every downstream that shares the same set of direct upstreams, so + # we memoize them on the DepContext and run the query once per pass instead of + # once per downstream. The mapped-task-group case uses per-ti map-index predicates + # and is left un-memoized. The cache lives for one scheduling pass, and + # DagRun._get_ready_tis invalidates it for both of the things that change a mapped + # task's instance count mid-pass: expanding an unexpanded task, and + # _revise_map_indexes_if_mapped growing an already-expanded one. State-only changes + # (a task finishing, instances marked REMOVED) leave the row count alone, so they + # need no invalidation. + cache_key: tuple[str, str, frozenset[str]] | None = None + task_id_counts: list[tuple[str, int]] | None = None + if task.get_closest_mapped_task_group() is None: + cache_key = (ti.dag_id, ti.run_id, frozenset(upstream_tasks)) + task_id_counts = dep_context.upstream_task_id_counts.get(cache_key) + if task_id_counts is None: + task_id_counts = [ + (task_id, count) + for task_id, count in session.execute( + select(TaskInstance.task_id, func.count(TaskInstance.task_id)) + .where(TaskInstance.dag_id == ti.dag_id, TaskInstance.run_id == ti.run_id) + .where(or_(*_iter_upstream_conditions(relevant_tasks=upstream_tasks))) + .group_by(TaskInstance.task_id) + ) + ] + if cache_key is not None: + dep_context.upstream_task_id_counts[cache_key] = task_id_counts + # `task_id_counts` only contains task_ids matched by `task_id IN (upstream_tasks)`, + # so every key is present in `upstream_tasks`; is_setup is re-derived locally. upstream = sum(count for _, count in task_id_counts) upstream_setup = sum(c for t, c in task_id_counts if upstream_tasks[t].is_setup) diff --git a/airflow-core/src/airflow/timetables/interval.py b/airflow-core/src/airflow/timetables/interval.py index 5064ee9be508f..30a7f5033faac 100644 --- a/airflow-core/src/airflow/timetables/interval.py +++ b/airflow-core/src/airflow/timetables/interval.py @@ -224,8 +224,26 @@ def _relativedelta_in_seconds(delta: relativedelta) -> int: + delta.seconds ) - def _round(self, dt: DateTime) -> DateTime: - """Round the given time to the nearest interval.""" + def _round(self, dt: DateTime, anchor: DateTime) -> DateTime: + """ + Floor ``dt`` to the latest schedule boundary at or before it. + + Months/years have no fixed second count, so the epoch-grid rounding + used for fixed deltas would drift. For them we anchor on ``anchor`` + (the start_date) and advance one period at a time, so boundaries match + the catchup=True grid -- relativedelta day-clamping is path-dependent + (e.g. Jan 31 -> Feb 28 -> Mar 28), so a multiplied jump would land + elsewhere. Fixed deltas keep the historical epoch rounding and ignore + ``anchor``. + + ``anchor`` must be at or before ``dt``; otherwise the forward stepping + cannot reach ``dt`` and the result is meaningless. + """ + if isinstance(self._delta, relativedelta) and (self._delta.months or self._delta.years): + boundary = anchor + while self._get_next(boundary) <= dt: + boundary = self._get_next(boundary) + return boundary if isinstance(self._delta, datetime.timedelta): delta_in_seconds = self._delta.total_seconds() else: @@ -243,8 +261,8 @@ def _skip_to_latest(self, earliest: DateTime | None) -> DateTime: This is slightly different from the cron version at terminal values. """ - round_current_time = self._round(coerce_datetime(utcnow())) - new_start = self._get_prev(round_current_time) + now = coerce_datetime(utcnow()) + new_start = self._get_prev(self._round(now, earliest or now)) if earliest is None: return new_start return max(new_start, earliest) diff --git a/airflow-core/src/airflow/ui/eslint.config.js b/airflow-core/src/airflow/ui/eslint.config.js index d85f4fde83c93..ecc7708995a50 100644 --- a/airflow-core/src/airflow/ui/eslint.config.js +++ b/airflow-core/src/airflow/ui/eslint.config.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts index b72cc90eb300b..5caf5b3c3cb6d 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts @@ -147,7 +147,7 @@ export const UseDagRunServiceGetDagRunKeyFn = ({ dagId, dagRunId }: { export type DagRunServiceGetDagRunsDefaultResponse = Awaited>; export type DagRunServiceGetDagRunsQueryResult = UseQueryResult; export const useDagRunServiceGetDagRunsKey = "DagRunServiceGetDagRuns"; -export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { bundleVersion?: string; confContains?: string; consumingAssetPattern?: string; @@ -171,6 +171,8 @@ export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, c logicalDateLte?: string; offset?: number; orderBy?: string[]; + partitionDateGte?: string; + partitionDateLte?: string; partitionKeyPattern?: string; partitionKeyPrefixPattern?: string; runAfterGt?: string; @@ -191,7 +193,7 @@ export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, c updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}, queryKey?: Array) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])]; +}, queryKey?: Array) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])]; export type DagRunServiceGetUpstreamAssetEventsDefaultResponse = Awaited>; export type DagRunServiceGetUpstreamAssetEventsQueryResult = UseQueryResult; export const useDagRunServiceGetUpstreamAssetEventsKey = "DagRunServiceGetUpstreamAssetEvents"; @@ -326,7 +328,7 @@ export const UseDagServiceGetDagTagsKeyFn = ({ limit, offset, orderBy, tagNamePa export type DagServiceGetDagsUiDefaultResponse = Awaited>; export type DagServiceGetDagsUiQueryResult = UseQueryResult; export const useDagServiceGetDagsUiKey = "DagServiceGetDagsUi"; -export const UseDagServiceGetDagsUiKeyFn = ({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { +export const UseDagServiceGetDagsUiKeyFn = ({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { assetDependency?: string; bundleName?: string; bundleVersion?: string; @@ -336,6 +338,7 @@ export const UseDagServiceGetDagsUiKeyFn = ({ assetDependency, bundleName, bundl dagIdPrefixPattern?: string; dagIds?: string[]; dagRunsLimit?: number; + dagRunState?: DagRunState; excludeStale?: boolean; hasAssetSchedule?: boolean; hasImportErrors?: boolean; @@ -349,7 +352,7 @@ export const UseDagServiceGetDagsUiKeyFn = ({ assetDependency, bundleName, bundl paused?: boolean; tags?: string[]; tagsMatchMode?: "any" | "all"; -} = {}, queryKey?: Array) => [useDagServiceGetDagsUiKey, ...(queryKey ?? [{ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }])]; +} = {}, queryKey?: Array) => [useDagServiceGetDagsUiKey, ...(queryKey ?? [{ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }])]; export type DagServiceGetLatestRunInfoDefaultResponse = Awaited>; export type DagServiceGetLatestRunInfoQueryResult = UseQueryResult; export const useDagServiceGetLatestRunInfoKey = "DagServiceGetLatestRunInfo"; @@ -942,12 +945,13 @@ export const UseDeadlinesServiceGetDeadlinesKeyFn = ({ dagId, dagRunId, deadline export type DeadlinesServiceGetDagDeadlineAlertsDefaultResponse = Awaited>; export type DeadlinesServiceGetDagDeadlineAlertsQueryResult = UseQueryResult; export const useDeadlinesServiceGetDagDeadlineAlertsKey = "DeadlinesServiceGetDagDeadlineAlerts"; -export const UseDeadlinesServiceGetDagDeadlineAlertsKeyFn = ({ dagId, limit, offset, orderBy }: { +export const UseDeadlinesServiceGetDagDeadlineAlertsKeyFn = ({ dagId, limit, offset, orderBy, versionNumber }: { dagId: string; limit?: number; offset?: number; orderBy?: string[]; -}, queryKey?: Array) => [useDeadlinesServiceGetDagDeadlineAlertsKey, ...(queryKey ?? [{ dagId, limit, offset, orderBy }])]; + versionNumber?: number; +}, queryKey?: Array) => [useDeadlinesServiceGetDagDeadlineAlertsKey, ...(queryKey ?? [{ dagId, limit, offset, orderBy, versionNumber }])]; export type StructureServiceStructureDataDefaultResponse = Awaited>; export type StructureServiceStructureDataQueryResult = UseQueryResult; export const useStructureServiceStructureDataKey = "StructureServiceStructureData"; diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts index 74a833b2ccfdc..1c5d5e7e5355f 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts @@ -10,14 +10,10 @@ import * as Common from "./common"; * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``uri_prefix_pattern`` parameter when possible. -* @param data.uriPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.uriPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `uri_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.uriPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.dagIds * @param data.onlyActive * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` @@ -41,10 +37,8 @@ export const ensureUseAssetServiceGetAssetsData = (queryClient: QueryClient, { d * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name` * @returns AssetAliasCollectionResponse Successful Response * @throws ApiError @@ -79,10 +73,8 @@ export const ensureUseAssetServiceGetAssetAliasData = (queryClient: QueryClient, * @param data.sourceTaskId * @param data.sourceRunId * @param data.sourceMapIndex -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.timestampGte * @param data.timestampGt * @param data.timestampLte @@ -241,10 +233,8 @@ export const ensureUseConnectionServiceGetConnectionTestData = (queryClient: Que * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `conn_id, conn_type, description, host, port, id, team_name, connection_id` -* @param data.connectionIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``connection_id_prefix_pattern`` parameter when possible. -* @param data.connectionIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.connectionIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `connection_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.connectionIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns ConnectionCollectionResponse Successful Response * @throws ApiError */ @@ -290,6 +280,8 @@ export const ensureUseDagRunServiceGetDagRunData = (queryClient: QueryClient, { * on the first page. * @param data The data for the request. * @param data.dagId +* @param data.partitionDateGte Inclusive lower bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. Runs from the start of this day onwards match. +* @param data.partitionDateLte Inclusive upper bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. The whole day is included: runs up to the end of this day match. * @param data.cursor Cursor for keyset-based pagination. Pass an empty string for the first page, then use ``next_cursor`` from the response. When ``cursor`` is provided, ``offset`` is ignored. * @param data.limit * @param data.offset @@ -322,28 +314,20 @@ export const ensureUseDagRunServiceGetDagRunData = (queryClient: QueryClient, { * @param data.state * @param data.dagVersion * @param data.bundleVersion -* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user_name_prefix_pattern`` parameter when possible. -* @param data.triggeringUserNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.partitionKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). The pipe `|` is matched literally, not as an OR separator. Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``partition_key_prefix_pattern`` parameter when possible. -* @param data.partitionKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). The pipe `|` is part of the prefix, not an OR separator. Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.consumingAssetPattern Filter by consuming asset name or URI using pattern matching +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.triggeringUserNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.partitionKeyPattern Case-insensitive substring match (SQL `ILIKE`). Here `|` is matched literally, not as OR. Slower than `partition_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.partitionKeyPrefixPattern Case-sensitive, index-friendly prefix match. Here `|` is matched literally, not as OR. See "Filtering with pattern parameters". +* @param data.consumingAssetPattern Case-insensitive substring match against the consuming asset name or URI. Unlike the wildcard `*_pattern` parameters, `%` and `_` are matched literally, `|` is not an OR separator, and `~` does not match everything. * @returns DAGRunCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { bundleVersion?: string; confContains?: string; consumingAssetPattern?: string; @@ -367,6 +351,8 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { logicalDateLte?: string; offset?: number; orderBy?: string[]; + partitionDateGte?: string; + partitionDateLte?: string; partitionKeyPattern?: string; partitionKeyPrefixPattern?: string; runAfterGt?: string; @@ -387,7 +373,7 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); +}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Get Upstream Asset Events * If dag run is asset-triggered, return the asset events that triggered it. @@ -535,14 +521,10 @@ export const ensureUseDagWarningServiceListDagWarningsData = (queryClient: Query * @param data.tags * @param data.tagsMatchMode * @param data.owners -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.excludeStale * @param data.paused * @param data.hasImportErrors Filter Dags by having import errors. Only Dags that have been successfully loaded before will be returned. @@ -626,10 +608,8 @@ export const ensureUseDagServiceGetDagDetailsData = (queryClient: QueryClient, { * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` -* @param data.tagNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``tag_name_prefix_pattern`` parameter when possible. -* @param data.tagNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.tagNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `tag_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.tagNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns DAGTagCollectionResponse Successful Response * @throws ApiError */ @@ -651,18 +631,15 @@ export const ensureUseDagServiceGetDagTagsData = (queryClient: QueryClient, { li * @param data.tagsMatchMode * @param data.owners * @param data.dagIds -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.excludeStale * @param data.paused * @param data.hasImportErrors Filter Dags by having import errors. Only Dags that have been successfully loaded before will be returned. * @param data.lastDagRunState +* @param data.dagRunState Filter Dags that have any DagRun in the given state. * @param data.bundleName * @param data.bundleVersion * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` @@ -673,7 +650,7 @@ export const ensureUseDagServiceGetDagTagsData = (queryClient: QueryClient, { li * @returns DAGWithLatestDagRunsCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseDagServiceGetDagsUiData = (queryClient: QueryClient, { assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { +export const ensureUseDagServiceGetDagsUiData = (queryClient: QueryClient, { assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { assetDependency?: string; bundleName?: string; bundleVersion?: string; @@ -683,6 +660,7 @@ export const ensureUseDagServiceGetDagsUiData = (queryClient: QueryClient, { ass dagIdPrefixPattern?: string; dagIds?: string[]; dagRunsLimit?: number; + dagRunState?: DagRunState; excludeStale?: boolean; hasAssetSchedule?: boolean; hasImportErrors?: boolean; @@ -696,7 +674,7 @@ export const ensureUseDagServiceGetDagsUiData = (queryClient: QueryClient, { ass paused?: boolean; tags?: string[]; tagsMatchMode?: "any" | "all"; -} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) }); +} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) }); /** * Get Latest Run Info * Get latest run. @@ -736,26 +714,16 @@ export const ensureUseEventLogServiceGetEventLogData = (queryClient: QueryClient * @param data.includedEvents * @param data.before * @param data.after -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.ownerPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``owner_prefix_pattern`` parameter when possible. -* @param data.eventPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``event_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.ownerPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.eventPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.ownerPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `owner_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.eventPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `event_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.ownerPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.eventPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns EventLogCollectionResponse Successful Response * @throws ApiError */ @@ -871,28 +839,20 @@ export const ensureUseTaskInstanceServiceGetTaskInstanceData = (queryClient: Que * @param data.durationLt * @param data.state * @param data.pool -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.queue -* @param data.queueNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. -* @param data.queueNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.queueNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.queueNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.executor * @param data.versionNumber * @param data.tryNumber * @param data.operator -* @param data.operatorNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. -* @param data.operatorNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.operatorNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.operatorNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex -* @param data.renderedMapIndexPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. -* @param data.renderedMapIndexPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.renderedMapIndexPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.renderedMapIndexPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator` @@ -1075,43 +1035,29 @@ export const ensureUseTaskInstanceServiceGetMappedTaskInstanceData = (queryClien * @param data.durationGt * @param data.durationLte * @param data.durationLt -* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_display_name_prefix_pattern`` parameter when possible. -* @param data.taskDisplayNamePrefixPattern Prefix match on task display name: optional ``_task_display_property_value`` else ``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly alternative to ``task_display_name_pattern``. On large databases, combine with ``dag_id_prefix_pattern`` (or a specific Dag in the path) so ``(dag_id, task_id, ...)`` indexes apply. Use ``|`` for OR. Use ``~`` to match all. Trailing non-alphanumeric characters in the term are stripped before matching so the range scan stays index-compatible under locale-aware collations. +* @param data.taskDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskDisplayNamePrefixPattern Case-sensitive prefix match on task display name (`_task_display_property_value` else `task_id`). Index-friendly alternative to `task_display_name_pattern`; on large databases combine with `dag_id_prefix_pattern` (or a specific Dag in the path) so composite indexes apply. See "Filtering with pattern parameters". * @param data.taskGroupId Filter by exact task group ID. Returns all tasks within the specified task group. -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.state * @param data.pool -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.queue -* @param data.queueNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. -* @param data.queueNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.queueNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.queueNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.executor * @param data.versionNumber * @param data.tryNumber * @param data.operator -* @param data.operatorNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. -* @param data.operatorNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.operatorNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.operatorNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex -* @param data.renderedMapIndexPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. -* @param data.renderedMapIndexPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.renderedMapIndexPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.renderedMapIndexPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator` @@ -1300,26 +1246,18 @@ export const ensureUseTaskInstanceServiceGetHitlDetailTryDetailData = (queryClie * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, task_display_name, run_after, rendered_map_index, task_instance_operator, task_instance_state` -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex * @param data.state * @param data.responseReceived * @param data.respondedByUserId * @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``subject_search`` parameter when possible. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``body_search`` parameter when possible. +* @param data.subjectSearch Case-insensitive substring match (SQL `ILIKE`). Slower than `subject_search` on large tables — see "Filtering with pattern parameters". +* @param data.bodySearch Case-insensitive substring match (SQL `ILIKE`). Slower than `body_search` on large tables — see "Filtering with pattern parameters". * @param data.createdAtGte * @param data.createdAtGt * @param data.createdAtLte @@ -1368,10 +1306,8 @@ export const ensureUseImportErrorServiceGetImportErrorData = (queryClient: Query * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` -* @param data.filenamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``filename_prefix_pattern`` parameter when possible. -* @param data.filenamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.filenamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `filename_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.filenamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.filename Exact filename match. Returns only the import error for this specific file path. * @param data.bundleName Exact bundle name match. Returns only import errors from this specific bundle. * @returns ImportErrorCollectionResponse Successful Response @@ -1463,10 +1399,8 @@ export const ensureUsePoolServiceGetPoolData = (queryClient: QueryClient, { pool * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns PoolCollectionResponse Successful Response * @throws ApiError */ @@ -1594,22 +1528,14 @@ export const ensureUseXcomServiceGetXcomEntryData = (queryClient: QueryClient, { * @param data.mapIndex * @param data.limit * @param data.offset -* @param data.xcomKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``xcom_key_prefix_pattern`` parameter when possible. -* @param data.xcomKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.xcomKeyPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `xcom_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.xcomKeyPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndexFilter * @param data.logicalDateGte * @param data.logicalDateGt @@ -1694,10 +1620,8 @@ export const ensureUseVariableServiceGetVariableData = (queryClient: QueryClient * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted, team_name` -* @param data.variableKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``variable_key_prefix_pattern`` parameter when possible. -* @param data.variableKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.variableKeyPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `variable_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.variableKeyPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns VariableCollectionResponse Successful Response * @throws ApiError */ @@ -1894,18 +1818,20 @@ export const ensureUseDeadlinesServiceGetDeadlinesData = (queryClient: QueryClie * Get all deadline alerts defined on a Dag. * @param data The data for the request. * @param data.dagId +* @param data.versionNumber * @param data.limit * @param data.offset -* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name, interval` +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name` * @returns DeadlineAlertCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseDeadlinesServiceGetDagDeadlineAlertsData = (queryClient: QueryClient, { dagId, limit, offset, orderBy }: { +export const ensureUseDeadlinesServiceGetDagDeadlineAlertsData = (queryClient: QueryClient, { dagId, limit, offset, orderBy, versionNumber }: { dagId: string; limit?: number; offset?: number; orderBy?: string[]; -}) => queryClient.ensureQueryData({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy }), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy }) }); + versionNumber?: number; +}) => queryClient.ensureQueryData({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy, versionNumber }) }); /** * Structure Data * Get Structure Data. @@ -1947,10 +1873,8 @@ export const ensureUseStructureServiceStructureDataData = (queryClient: QueryCli * @param data.runAfterLt * @param data.runType * @param data.state -* @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. -* @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridNodeResponse Successful Response * @throws ApiError */ @@ -1986,10 +1910,8 @@ export const ensureUseGridServiceGetDagStructureData = (queryClient: QueryClient * @param data.runAfterLt * @param data.runType * @param data.state -* @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. -* @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridRunsResponse Successful Response * @throws ApiError */ diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts index 9db58a9676cc6..fa35a01bdf717 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts @@ -10,14 +10,10 @@ import * as Common from "./common"; * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``uri_prefix_pattern`` parameter when possible. -* @param data.uriPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.uriPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `uri_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.uriPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.dagIds * @param data.onlyActive * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` @@ -41,10 +37,8 @@ export const prefetchUseAssetServiceGetAssets = (queryClient: QueryClient, { dag * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name` * @returns AssetAliasCollectionResponse Successful Response * @throws ApiError @@ -79,10 +73,8 @@ export const prefetchUseAssetServiceGetAssetAlias = (queryClient: QueryClient, { * @param data.sourceTaskId * @param data.sourceRunId * @param data.sourceMapIndex -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.timestampGte * @param data.timestampGt * @param data.timestampLte @@ -241,10 +233,8 @@ export const prefetchUseConnectionServiceGetConnectionTest = (queryClient: Query * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `conn_id, conn_type, description, host, port, id, team_name, connection_id` -* @param data.connectionIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``connection_id_prefix_pattern`` parameter when possible. -* @param data.connectionIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.connectionIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `connection_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.connectionIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns ConnectionCollectionResponse Successful Response * @throws ApiError */ @@ -290,6 +280,8 @@ export const prefetchUseDagRunServiceGetDagRun = (queryClient: QueryClient, { da * on the first page. * @param data The data for the request. * @param data.dagId +* @param data.partitionDateGte Inclusive lower bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. Runs from the start of this day onwards match. +* @param data.partitionDateLte Inclusive upper bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. The whole day is included: runs up to the end of this day match. * @param data.cursor Cursor for keyset-based pagination. Pass an empty string for the first page, then use ``next_cursor`` from the response. When ``cursor`` is provided, ``offset`` is ignored. * @param data.limit * @param data.offset @@ -322,28 +314,20 @@ export const prefetchUseDagRunServiceGetDagRun = (queryClient: QueryClient, { da * @param data.state * @param data.dagVersion * @param data.bundleVersion -* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.triggeringUserNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user_name_prefix_pattern`` parameter when possible. -* @param data.triggeringUserNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.partitionKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). The pipe `|` is matched literally, not as an OR separator. Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``partition_key_prefix_pattern`` parameter when possible. -* @param data.partitionKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). The pipe `|` is part of the prefix, not an OR separator. Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.consumingAssetPattern Filter by consuming asset name or URI using pattern matching +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.triggeringUserNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.partitionKeyPattern Case-insensitive substring match (SQL `ILIKE`). Here `|` is matched literally, not as OR. Slower than `partition_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.partitionKeyPrefixPattern Case-sensitive, index-friendly prefix match. Here `|` is matched literally, not as OR. See "Filtering with pattern parameters". +* @param data.consumingAssetPattern Case-insensitive substring match against the consuming asset name or URI. Unlike the wildcard `*_pattern` parameters, `%` and `_` are matched literally, `|` is not an OR separator, and `~` does not match everything. * @returns DAGRunCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { bundleVersion?: string; confContains?: string; consumingAssetPattern?: string; @@ -367,6 +351,8 @@ export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { b logicalDateLte?: string; offset?: number; orderBy?: string[]; + partitionDateGte?: string; + partitionDateLte?: string; partitionKeyPattern?: string; partitionKeyPrefixPattern?: string; runAfterGt?: string; @@ -387,7 +373,7 @@ export const prefetchUseDagRunServiceGetDagRuns = (queryClient: QueryClient, { b updatedAtGte?: string; updatedAtLt?: string; updatedAtLte?: string; -}) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); +}) => queryClient.prefetchQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) }); /** * Get Upstream Asset Events * If dag run is asset-triggered, return the asset events that triggered it. @@ -535,14 +521,10 @@ export const prefetchUseDagWarningServiceListDagWarnings = (queryClient: QueryCl * @param data.tags * @param data.tagsMatchMode * @param data.owners -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.excludeStale * @param data.paused * @param data.hasImportErrors Filter Dags by having import errors. Only Dags that have been successfully loaded before will be returned. @@ -626,10 +608,8 @@ export const prefetchUseDagServiceGetDagDetails = (queryClient: QueryClient, { d * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `name` -* @param data.tagNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``tag_name_prefix_pattern`` parameter when possible. -* @param data.tagNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.tagNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `tag_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.tagNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns DAGTagCollectionResponse Successful Response * @throws ApiError */ @@ -651,18 +631,15 @@ export const prefetchUseDagServiceGetDagTags = (queryClient: QueryClient, { limi * @param data.tagsMatchMode * @param data.owners * @param data.dagIds -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.excludeStale * @param data.paused * @param data.hasImportErrors Filter Dags by having import errors. Only Dags that have been successfully loaded before will be returned. * @param data.lastDagRunState +* @param data.dagRunState Filter Dags that have any DagRun in the given state. * @param data.bundleName * @param data.bundleVersion * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `dag_id, dag_display_name, next_dagrun, state, start_date, last_run_state, last_run_start_date` @@ -673,7 +650,7 @@ export const prefetchUseDagServiceGetDagTags = (queryClient: QueryClient, { limi * @returns DAGWithLatestDagRunsCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseDagServiceGetDagsUi = (queryClient: QueryClient, { assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { +export const prefetchUseDagServiceGetDagsUi = (queryClient: QueryClient, { assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { assetDependency?: string; bundleName?: string; bundleVersion?: string; @@ -683,6 +660,7 @@ export const prefetchUseDagServiceGetDagsUi = (queryClient: QueryClient, { asset dagIdPrefixPattern?: string; dagIds?: string[]; dagRunsLimit?: number; + dagRunState?: DagRunState; excludeStale?: boolean; hasAssetSchedule?: boolean; hasImportErrors?: boolean; @@ -696,7 +674,7 @@ export const prefetchUseDagServiceGetDagsUi = (queryClient: QueryClient, { asset paused?: boolean; tags?: string[]; tagsMatchMode?: "any" | "all"; -} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) }); +} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) }); /** * Get Latest Run Info * Get latest run. @@ -736,26 +714,16 @@ export const prefetchUseEventLogServiceGetEventLog = (queryClient: QueryClient, * @param data.includedEvents * @param data.before * @param data.after -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.ownerPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``owner_prefix_pattern`` parameter when possible. -* @param data.eventPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``event_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.ownerPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.eventPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.ownerPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `owner_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.eventPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `event_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.ownerPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.eventPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns EventLogCollectionResponse Successful Response * @throws ApiError */ @@ -871,28 +839,20 @@ export const prefetchUseTaskInstanceServiceGetTaskInstance = (queryClient: Query * @param data.durationLt * @param data.state * @param data.pool -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.queue -* @param data.queueNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. -* @param data.queueNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.queueNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.queueNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.executor * @param data.versionNumber * @param data.tryNumber * @param data.operator -* @param data.operatorNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. -* @param data.operatorNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.operatorNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.operatorNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex -* @param data.renderedMapIndexPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. -* @param data.renderedMapIndexPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.renderedMapIndexPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.renderedMapIndexPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator` @@ -1075,43 +1035,29 @@ export const prefetchUseTaskInstanceServiceGetMappedTaskInstance = (queryClient: * @param data.durationGt * @param data.durationLte * @param data.durationLt -* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_display_name_prefix_pattern`` parameter when possible. -* @param data.taskDisplayNamePrefixPattern Prefix match on task display name: optional ``_task_display_property_value`` else ``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly alternative to ``task_display_name_pattern``. On large databases, combine with ``dag_id_prefix_pattern`` (or a specific Dag in the path) so ``(dag_id, task_id, ...)`` indexes apply. Use ``|`` for OR. Use ``~`` to match all. Trailing non-alphanumeric characters in the term are stripped before matching so the range scan stays index-compatible under locale-aware collations. +* @param data.taskDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskDisplayNamePrefixPattern Case-sensitive prefix match on task display name (`_task_display_property_value` else `task_id`). Index-friendly alternative to `task_display_name_pattern`; on large databases combine with `dag_id_prefix_pattern` (or a specific Dag in the path) so composite indexes apply. See "Filtering with pattern parameters". * @param data.taskGroupId Filter by exact task group ID. Returns all tasks within the specified task group. -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.state * @param data.pool -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.queue -* @param data.queueNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. -* @param data.queueNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.queueNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.queueNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.executor * @param data.versionNumber * @param data.tryNumber * @param data.operator -* @param data.operatorNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. -* @param data.operatorNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.operatorNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.operatorNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex -* @param data.renderedMapIndexPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. -* @param data.renderedMapIndexPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.renderedMapIndexPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.renderedMapIndexPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, duration, start_date, end_date, map_index, try_number, logical_date, run_after, data_interval_start, data_interval_end, rendered_map_index, operator` @@ -1300,26 +1246,18 @@ export const prefetchUseTaskInstanceServiceGetHitlDetailTryDetail = (queryClient * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `ti_id, subject, responded_at, created_at, responded_by_user_id, responded_by_user_name, dag_id, run_id, task_display_name, run_after, rendered_map_index, task_instance_operator, task_instance_state` -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. -* @param data.dagIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.dagIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndex * @param data.state * @param data.responseReceived * @param data.respondedByUserId * @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``subject_search`` parameter when possible. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``body_search`` parameter when possible. +* @param data.subjectSearch Case-insensitive substring match (SQL `ILIKE`). Slower than `subject_search` on large tables — see "Filtering with pattern parameters". +* @param data.bodySearch Case-insensitive substring match (SQL `ILIKE`). Slower than `body_search` on large tables — see "Filtering with pattern parameters". * @param data.createdAtGte * @param data.createdAtGt * @param data.createdAtLte @@ -1368,10 +1306,8 @@ export const prefetchUseImportErrorServiceGetImportError = (queryClient: QueryCl * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, timestamp, filename, bundle_name, stacktrace, import_error_id` -* @param data.filenamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``filename_prefix_pattern`` parameter when possible. -* @param data.filenamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.filenamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `filename_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.filenamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.filename Exact filename match. Returns only the import error for this specific file path. * @param data.bundleName Exact bundle name match. Returns only import errors from this specific bundle. * @returns ImportErrorCollectionResponse Successful Response @@ -1463,10 +1399,8 @@ export const prefetchUsePoolServiceGetPool = (queryClient: QueryClient, { poolNa * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, pool, name` -* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. -* @param data.poolNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.poolNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.poolNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns PoolCollectionResponse Successful Response * @throws ApiError */ @@ -1594,22 +1528,14 @@ export const prefetchUseXcomServiceGetXcomEntry = (queryClient: QueryClient, { d * @param data.mapIndex * @param data.limit * @param data.offset -* @param data.xcomKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``xcom_key_prefix_pattern`` parameter when possible. -* @param data.xcomKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.dagDisplayNamePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. -* @param data.dagDisplayNamePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. -* @param data.runIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. -* @param data.taskIdPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.xcomKeyPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `xcom_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.xcomKeyPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.dagDisplayNamePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.dagDisplayNamePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.runIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.runIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.taskIdPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.taskIdPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.mapIndexFilter * @param data.logicalDateGte * @param data.logicalDateGt @@ -1694,10 +1620,8 @@ export const prefetchUseVariableServiceGetVariable = (queryClient: QueryClient, * @param data.limit * @param data.offset * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `key, id, _val, description, is_encrypted, team_name` -* @param data.variableKeyPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``variable_key_prefix_pattern`` parameter when possible. -* @param data.variableKeyPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.variableKeyPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `variable_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.variableKeyPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns VariableCollectionResponse Successful Response * @throws ApiError */ @@ -1894,18 +1818,20 @@ export const prefetchUseDeadlinesServiceGetDeadlines = (queryClient: QueryClient * Get all deadline alerts defined on a Dag. * @param data The data for the request. * @param data.dagId +* @param data.versionNumber * @param data.limit * @param data.offset -* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name, interval` +* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name` * @returns DeadlineAlertCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseDeadlinesServiceGetDagDeadlineAlerts = (queryClient: QueryClient, { dagId, limit, offset, orderBy }: { +export const prefetchUseDeadlinesServiceGetDagDeadlineAlerts = (queryClient: QueryClient, { dagId, limit, offset, orderBy, versionNumber }: { dagId: string; limit?: number; offset?: number; orderBy?: string[]; -}) => queryClient.prefetchQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy }), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy }) }); + versionNumber?: number; +}) => queryClient.prefetchQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy, versionNumber }) }); /** * Structure Data * Get Structure Data. @@ -1947,10 +1873,8 @@ export const prefetchUseStructureServiceStructureData = (queryClient: QueryClien * @param data.runAfterLt * @param data.runType * @param data.state -* @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. -* @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridNodeResponse Successful Response * @throws ApiError */ @@ -1986,10 +1910,8 @@ export const prefetchUseGridServiceGetDagStructure = (queryClient: QueryClient, * @param data.runAfterLt * @param data.runType * @param data.state -* @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. -* @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". +* @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridRunsResponse Successful Response * @throws ApiError */ diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts index c10c963570653..f40372e303e69 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts @@ -10,14 +10,10 @@ import * as Common from "./common"; * @param data The data for the request. * @param data.limit * @param data.offset -* @param data.namePattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. -* @param data.namePrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. -* @param data.uriPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. -* -* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``uri_prefix_pattern`` parameter when possible. -* @param data.uriPrefixPattern Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. +* @param data.namePattern Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.namePrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". +* @param data.uriPattern Case-insensitive substring match (SQL `ILIKE`). Slower than `uri_prefix_pattern` on large tables — see "Filtering with pattern parameters". +* @param data.uriPrefixPattern Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @param data.dagIds * @param data.onlyActive * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, name, uri, created_at, updated_at` @@ -41,10 +37,8 @@ export const useAssetServiceGetAssets = = unknown[]>({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const useDagRunServiceGetDagRuns = = unknown[]>({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { bundleVersion?: string; confContains?: string; consumingAssetPattern?: string; @@ -367,6 +351,8 @@ export const useDagRunServiceGetDagRuns = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Get Upstream Asset Events * If dag run is asset-triggered, return the asset events that triggered it. @@ -535,14 +521,10 @@ export const useDagWarningServiceListDagWarnings = = unknown[]>({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { +export const useDagServiceGetDagsUi = = unknown[]>({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { assetDependency?: string; bundleName?: string; bundleVersion?: string; @@ -683,6 +660,7 @@ export const useDagServiceGetDagsUi = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }, queryKey), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }, queryKey), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) as TData, ...options }); /** * Get Latest Run Info * Get latest run. @@ -736,26 +714,16 @@ export const useEventLogServiceGetEventLog = = unknown[]>({ dagId, limit, offset, orderBy }: { +export const useDeadlinesServiceGetDagDeadlineAlerts = = unknown[]>({ dagId, limit, offset, orderBy, versionNumber }: { dagId: string; limit?: number; offset?: number; orderBy?: string[]; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy }, queryKey), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy }) as TData, ...options }); + versionNumber?: number; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** * Structure Data * Get Structure Data. @@ -1947,10 +1873,8 @@ export const useStructureServiceStructureData = = unknown[]>({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { +export const useDagRunServiceGetDagRunsSuspense = = unknown[]>({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: { bundleVersion?: string; confContains?: string; consumingAssetPattern?: string; @@ -367,6 +351,8 @@ export const useDagRunServiceGetDagRunsSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }, queryKey), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) as TData, ...options }); /** * Get Upstream Asset Events * If dag run is asset-triggered, return the asset events that triggered it. @@ -535,14 +521,10 @@ export const useDagWarningServiceListDagWarningsSuspense = = unknown[]>({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { +export const useDagServiceGetDagsUiSuspense = = unknown[]>({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }: { assetDependency?: string; bundleName?: string; bundleVersion?: string; @@ -683,6 +660,7 @@ export const useDagServiceGetDagsUiSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }, queryKey), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDagServiceGetDagsUiKeyFn({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }, queryKey), queryFn: () => DagService.getDagsUi({ assetDependency, bundleName, bundleVersion, dagDisplayNamePattern, dagDisplayNamePrefixPattern, dagIdPattern, dagIdPrefixPattern, dagIds, dagRunsLimit, dagRunState, excludeStale, hasAssetSchedule, hasImportErrors, hasPendingActions, isFavorite, lastDagRunState, limit, offset, orderBy, owners, paused, tags, tagsMatchMode }) as TData, ...options }); /** * Get Latest Run Info * Get latest run. @@ -736,26 +714,16 @@ export const useEventLogServiceGetEventLogSuspense = = unknown[]>({ dagId, limit, offset, orderBy }: { +export const useDeadlinesServiceGetDagDeadlineAlertsSuspense = = unknown[]>({ dagId, limit, offset, orderBy, versionNumber }: { dagId: string; limit?: number; offset?: number; orderBy?: string[]; -}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy }, queryKey), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy }) as TData, ...options }); + versionNumber?: number; +}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseDeadlinesServiceGetDagDeadlineAlertsKeyFn({ dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DeadlinesService.getDagDeadlineAlerts({ dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** * Structure Data * Get Structure Data. @@ -1947,10 +1873,8 @@ export const useStructureServiceStructureDataSuspense = { return __request(OpenAPI, { method: 'GET', - url: '/ui/pending_partitioned_dag_run/{dag_id}/{partition_key}', + url: '/ui/pending_partitioned_dag_run/{dag_id}', path: { - dag_id: data.dagId, + dag_id: data.dagId + }, + query: { partition_key: data.partitionKey }, errors: { @@ -4834,9 +4761,10 @@ export class DeadlinesService { * Get all deadline alerts defined on a Dag. * @param data The data for the request. * @param data.dagId + * @param data.versionNumber * @param data.limit * @param data.offset - * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name, interval` + * @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name` * @returns DeadlineAlertCollectionResponse Successful Response * @throws ApiError */ @@ -4848,6 +4776,7 @@ export class DeadlinesService { dag_id: data.dagId }, query: { + version_number: data.versionNumber, limit: data.limit, offset: data.offset, order_by: data.orderBy @@ -4918,10 +4847,8 @@ export class GridService { * @param data.runAfterLt * @param data.runType * @param data.state - * @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. - * @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". + * @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridNodeResponse Successful Response * @throws ApiError */ @@ -4971,10 +4898,8 @@ export class GridService { * @param data.runAfterLt * @param data.runType * @param data.state - * @param data.triggeringUser SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. - * @param data.triggeringUserPrefix Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * @param data.triggeringUser Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". + * @param data.triggeringUserPrefix Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". * @returns GridRunsResponse Successful Response * @throws ApiError */ diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts index 7bd02c5597926..975c7cc99bc00 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts @@ -2312,9 +2312,9 @@ export type DeadlineAlertResponse = { name?: string | null; reference_type: string; /** - * Interval in seconds between deadline evaluations. + * Interval in seconds between the reference time and the deadline. Null for a dynamic interval (e.g. a VariableInterval) whose value is only resolved at scheduler evaluation time. */ - interval: number; + interval?: number | null; created_at: string; }; @@ -2438,6 +2438,7 @@ export type GridRunsResponse = { run_type: DagRunType; dag_versions?: Array; has_missed_deadline: boolean; + has_note: boolean; readonly duration: number; }; @@ -2456,7 +2457,8 @@ export type GridTISummaries = { export type HistoricalMetricDataResponse = { dag_run_states: DAGRunStates; task_instance_states: TaskInstanceStateCount; - state_count_limit: number; + dag_run_counts_are_lower_bounds?: boolean; + task_instance_counts_are_lower_bounds?: boolean; }; /** @@ -2472,6 +2474,7 @@ export type LightGridTaskInstanceSummary = { min_start_date: string | null; max_end_date: string | null; dag_version_number?: number | null; + has_note?: boolean; }; /** @@ -2707,13 +2710,11 @@ export type GetAssetsData = { dagIds?: Array<(string)>; limit?: number; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ namePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ namePrefixPattern?: string | null; offset?: number; @@ -2723,13 +2724,11 @@ export type GetAssetsData = { */ orderBy?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``uri_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `uri_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ uriPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ uriPrefixPattern?: string | null; }; @@ -2739,13 +2738,11 @@ export type GetAssetsResponse = AssetCollectionResponse; export type GetAssetAliasesData = { limit?: number; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ namePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ namePrefixPattern?: string | null; offset?: number; @@ -2767,13 +2764,11 @@ export type GetAssetEventsData = { assetId?: number | null; limit?: number; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ namePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ namePrefixPattern?: string | null; offset?: number; @@ -2957,13 +2952,11 @@ export type EnqueueConnectionTestResponse = ConnectionTestQueuedResponse; export type GetConnectionsData = { /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``connection_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `connection_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ connectionIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ connectionIdPrefixPattern?: string | null; limit?: number; @@ -3032,7 +3025,7 @@ export type GetDagRunsData = { bundleVersion?: string | null; confContains?: string; /** - * Filter by consuming asset name or URI using pattern matching + * Case-insensitive substring match against the consuming asset name or URI. Unlike the wildcard `*_pattern` parameters, `%` and `_` are matched literally, `|` is not an OR separator, and `~` does not match everything. */ consumingAssetPattern?: string | null; /** @@ -3041,13 +3034,11 @@ export type GetDagRunsData = { cursor?: string | null; dagId: string; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; dagVersion?: Array<(number)>; @@ -3066,17 +3057,23 @@ export type GetDagRunsData = { logicalDateLte?: string | null; offset?: number; /** - * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id` */ orderBy?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). The pipe `|` is matched literally, not as an OR separator. Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``partition_key_prefix_pattern`` parameter when possible. + * Inclusive lower bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. Runs from the start of this day onwards match. + */ + partitionDateGte?: string | null; + /** + * Inclusive upper bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. The whole day is included: runs up to the end of this day match. + */ + partitionDateLte?: string | null; + /** + * Case-insensitive substring match (SQL `ILIKE`). Here `|` is matched literally, not as OR. Slower than `partition_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ partitionKeyPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). The pipe `|` is part of the prefix, not an OR separator. Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. Here `|` is matched literally, not as OR. See "Filtering with pattern parameters". */ partitionKeyPrefixPattern?: string | null; runAfterGt?: string | null; @@ -3084,13 +3081,11 @@ export type GetDagRunsData = { runAfterLt?: string | null; runAfterLte?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ runIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ runIdPrefixPattern?: string | null; runType?: Array<(string)>; @@ -3100,13 +3095,11 @@ export type GetDagRunsData = { startDateLte?: string | null; state?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ triggeringUserNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ triggeringUserNamePrefixPattern?: string | null; updatedAtGt?: string | null; @@ -3234,23 +3227,19 @@ export type GetDagsData = { bundleName?: string | null; bundleVersion?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagDisplayNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagDisplayNamePrefixPattern?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; dagRunEndDateGt?: string | null; @@ -3290,13 +3279,11 @@ export type GetDagsResponse = DAGCollectionResponse; export type PatchDagsData = { /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; excludeStale?: boolean; @@ -3358,13 +3345,11 @@ export type GetDagTagsData = { */ orderBy?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``tag_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `tag_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ tagNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ tagNamePrefixPattern?: string | null; }; @@ -3379,27 +3364,27 @@ export type GetDagsUiData = { bundleName?: string | null; bundleVersion?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagDisplayNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagDisplayNamePrefixPattern?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; dagIds?: Array<(string)> | null; dagRunsLimit?: number; + /** + * Filter Dags that have any DagRun in the given state. + */ + dagRunState?: DagRunState | null; excludeStale?: boolean; /** * Filter Dags with asset-based scheduling @@ -3443,24 +3428,20 @@ export type GetEventLogsData = { before?: string | null; dagId?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; event?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``event_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `event_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ eventPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ eventPrefixPattern?: string | null; excludedEvents?: Array<(string)> | null; @@ -3474,35 +3455,29 @@ export type GetEventLogsData = { orderBy?: Array<(string)>; owner?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``owner_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `owner_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ ownerPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ ownerPrefixPattern?: string | null; runId?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ runIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ runIdPrefixPattern?: string | null; taskId?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ taskIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ taskIdPrefixPattern?: string | null; tryNumber?: number | null; @@ -3569,13 +3544,11 @@ export type GetMappedTaskInstancesData = { offset?: number; operator?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ operatorNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ operatorNamePrefixPattern?: string | null; /** @@ -3584,34 +3557,28 @@ export type GetMappedTaskInstancesData = { orderBy?: Array<(string)>; pool?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ poolNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ poolNamePrefixPattern?: string | null; queue?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ queueNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ queueNamePrefixPattern?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ renderedMapIndexPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ renderedMapIndexPrefixPattern?: string | null; runAfterGt?: string | null; @@ -3697,13 +3664,11 @@ export type GetTaskInstancesData = { cursor?: string | null; dagId: string; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; dagRunId: string; @@ -3725,13 +3690,11 @@ export type GetTaskInstancesData = { offset?: number; operator?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``operator_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `operator_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ operatorNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ operatorNamePrefixPattern?: string | null; /** @@ -3740,34 +3703,28 @@ export type GetTaskInstancesData = { orderBy?: Array<(string)>; pool?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ poolNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ poolNamePrefixPattern?: string | null; queue?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``queue_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `queue_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ queueNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ queueNamePrefixPattern?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``rendered_map_index_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `rendered_map_index_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ renderedMapIndexPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ renderedMapIndexPrefixPattern?: string | null; runAfterGt?: string | null; @@ -3775,13 +3732,11 @@ export type GetTaskInstancesData = { runAfterLt?: string | null; runAfterLte?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ runIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ runIdPrefixPattern?: string | null; startDateGt?: string | null; @@ -3790,13 +3745,11 @@ export type GetTaskInstancesData = { startDateLte?: string | null; state?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_display_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `task_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ taskDisplayNamePattern?: string | null; /** - * Prefix match on task display name: optional ``_task_display_property_value`` else ``task_id`` (same as ``coalesce``). Case-sensitive. Index-friendly alternative to ``task_display_name_pattern``. On large databases, combine with ``dag_id_prefix_pattern`` (or a specific Dag in the path) so ``(dag_id, task_id, ...)`` indexes apply. Use ``|`` for OR. Use ``~`` to match all. Trailing non-alphanumeric characters in the term are stripped before matching so the range scan stays index-compatible under locale-aware collations. + * Case-sensitive prefix match on task display name (`_task_display_property_value` else `task_id`). Index-friendly alternative to `task_display_name_pattern`; on large databases combine with `dag_id_prefix_pattern` (or a specific Dag in the path) so composite indexes apply. See "Filtering with pattern parameters". */ taskDisplayNamePrefixPattern?: string | null; /** @@ -3952,9 +3905,7 @@ export type GetHitlDetailTryDetailResponse = HITLDetailHistory; export type GetHitlDetailsData = { /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``body_search`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `body_search` on large tables — see "Filtering with pattern parameters". */ bodySearch?: string | null; createdAtGt?: string | null; @@ -3963,13 +3914,11 @@ export type GetHitlDetailsData = { createdAtLte?: string | null; dagId: string; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagIdPrefixPattern?: string | null; dagRunId: string; @@ -3985,20 +3934,16 @@ export type GetHitlDetailsData = { responseReceived?: boolean | null; state?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``subject_search`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `subject_search` on large tables — see "Filtering with pattern parameters". */ subjectSearch?: string | null; taskId?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ taskIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ taskIdPrefixPattern?: string | null; }; @@ -4021,13 +3966,11 @@ export type GetImportErrorsData = { */ filename?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``filename_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `filename_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ filenamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ filenamePrefixPattern?: string | null; limit?: number; @@ -4101,13 +4044,11 @@ export type GetPoolsData = { */ orderBy?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``pool_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `pool_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ poolNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ poolNamePrefixPattern?: string | null; }; @@ -4266,13 +4207,11 @@ export type DeleteXcomEntryResponse = void; export type GetXcomEntriesData = { /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``dag_display_name_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `dag_display_name_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ dagDisplayNamePattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ dagDisplayNamePrefixPattern?: string | null; dagId: string; @@ -4294,35 +4233,29 @@ export type GetXcomEntriesData = { runAfterLt?: string | null; runAfterLte?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `run_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ runIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ runIdPrefixPattern?: string | null; taskId: string; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``task_id_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `task_id_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ taskIdPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ taskIdPrefixPattern?: string | null; xcomKey?: string | null; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``xcom_key_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `xcom_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ xcomKeyPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ xcomKeyPrefixPattern?: string | null; }; @@ -4380,13 +4313,11 @@ export type GetVariablesData = { */ orderBy?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``variable_key_prefix_pattern`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `variable_key_prefix_pattern` on large tables — see "Filtering with pattern parameters". */ variableKeyPattern?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ variableKeyPrefixPattern?: string | null; }; @@ -4512,9 +4443,10 @@ export type GetDagDeadlineAlertsData = { limit?: number; offset?: number; /** - * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name, interval` + * Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, created_at, name` */ orderBy?: Array<(string)>; + versionNumber?: number | null; }; export type GetDagDeadlineAlertsResponse = DeadlineAlertCollectionResponse; @@ -4550,13 +4482,11 @@ export type GetDagStructureData = { runType?: Array<(string)>; state?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". */ triggeringUser?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ triggeringUserPrefix?: string | null; }; @@ -4578,13 +4508,11 @@ export type GetGridRunsData = { runType?: Array<(string)>; state?: Array<(string)>; /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported. - * - * **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``triggering_user`` parameter when possible. + * Case-insensitive substring match (SQL `ILIKE`). Slower than `triggering_user` on large tables — see "Filtering with pattern parameters". */ triggeringUser?: string | null; /** - * Prefix match — returns items whose value starts with the given string (case-sensitive, index-friendly). Use the pipe `|` operator for OR logic (e.g. `dag1|dag2`). Use `~` to match all. Wildcard characters (`%`, `_`) are treated as literal characters. Trailing non-alphanumeric characters in the prefix are stripped before matching so the range scan stays index-compatible under locale-aware collations — e.g. `test_` effectively matches items starting with `test`, and `s3://` matches items starting with `s3`. + * Case-sensitive, index-friendly prefix match. See "Filtering with pattern parameters". */ triggeringUserPrefix?: string | null; }; @@ -5051,6 +4979,10 @@ export type $OpenApiTs = { * Validation Error */ 422: HTTPValidationError; + /** + * Service Unavailable + */ + 503: HTTPExceptionResponse; }; }; }; @@ -5202,6 +5134,10 @@ export type $OpenApiTs = { * Validation Error */ 422: HTTPValidationError; + /** + * Service Unavailable + */ + 503: HTTPExceptionResponse; }; }; }; @@ -7821,6 +7757,10 @@ export type $OpenApiTs = { * Not Found */ 404: HTTPExceptionResponse; + /** + * Conflict + */ + 409: HTTPExceptionResponse; /** * Validation Error */ @@ -8228,7 +8168,7 @@ export type $OpenApiTs = { }; }; }; - '/ui/pending_partitioned_dag_run/{dag_id}/{partition_key}': { + '/ui/pending_partitioned_dag_run/{dag_id}': { get: { req: GetPendingPartitionedDagRunData; res: { diff --git a/airflow-core/src/airflow/ui/package.json b/airflow-core/src/airflow/ui/package.json index 611013f07fb3b..9a7bdc06dfbc3 100644 --- a/airflow-core/src/airflow/ui/package.json +++ b/airflow-core/src/airflow/ui/package.json @@ -26,96 +26,96 @@ }, "dependencies": { "@chakra-ui/anatomy": "^2.3.4", - "@chakra-ui/react": "~3.34.0", + "@chakra-ui/react": "~3.36.1", "@emotion/react": "^11.14.0", - "@guanmingchiu/sqlparser-ts": "^0.61.1", + "@guanmingchiu/sqlparser-ts": "^0.62.0", "@lezer/highlight": "^1.2.3", "@monaco-editor/react": "^4.7.0", - "@tanstack/react-query": "^5.90.21", + "@tanstack/react-query": "^5.101.4", "@tanstack/react-table": "^8.21.3", - "@tanstack/react-virtual": "^3.13.21", - "@visx/group": "^3.12.0", - "@visx/shape": "^3.12.0", - "@xyflow/react": "^12.10.1", + "@tanstack/react-virtual": "^3.14.8", + "@visx/group": "^4.0.0", + "@visx/shape": "^4.0.0", + "@xyflow/react": "^12.11.2", "anser": "^2.3.5", - "axios": "^1.16.0", - "chakra-react-select": "^6.1.1", + "axios": "^1.18.1", + "chakra-react-select": "^6.1.3", "chart.js": "^4.5.1", "chartjs-adapter-dayjs-4": "^1.0.4", "chartjs-plugin-annotation": "^3.1.0", "culori": "^4.0.2", - "dayjs": "^1.11.19", + "dayjs": "^1.11.21", "elkjs": "^0.11.1", "html-to-image": "^1.11.13", - "i18next": "^25.8.16", + "i18next": "^26.3.6", "i18next-browser-languagedetector": "^8.2.1", - "i18next-http-backend": "^3.0.5", - "monaco-editor": "^0.52.2", + "i18next-http-backend": "^4.0.1", + "monaco-editor": "^0.55.1", "next-themes": "^0.4.6", - "react": "^19.2.6", + "react": "^19.2.7", "react-chartjs-2": "^5.3.1", - "react-dom": "^19.2.6", - "react-hook-form": "^7.71.2", - "react-hotkeys-hook": "^4.6.1", - "react-i18next": "^16.6.5", - "react-icons": "^5.6.0", + "react-dom": "^19.2.7", + "react-hook-form": "^7.83.0", + "react-hotkeys-hook": "^4.6.2", + "react-i18next": "^17.0.11", + "react-icons": "^5.7.0", "react-innertext": "^1.1.5", - "react-markdown": "^9.1.0", + "react-markdown": "^10.1.0", "react-resizable-panels": "^3.0.6", - "react-router-dom": "^7.13.1", - "react-syntax-highlighter": "^15.6.1", + "react-router-dom": "^7.18.1", + "react-syntax-highlighter": "^16.1.1", "remark-gfm": "^4.0.1", - "use-debounce": "^10.1.0", + "use-debounce": "^10.1.1", "usehooks-ts": "^3.1.1", - "yaml": "^2.8.2", - "zustand": "^5.0.11" + "yaml": "^2.9.0", + "zustand": "^5.0.14" }, "devDependencies": { "@7nohe/openapi-react-query-codegen": "^1.6.2", - "@eslint/compat": "^2.0.5", + "@eslint/compat": "^2.1.0", "@eslint/js": "^10.0.1", - "@playwright/test": "^1.60.0", - "@rolldown/plugin-babel": "^0.2.2", + "@playwright/test": "^1.62.0", + "@rolldown/plugin-babel": "^0.2.3", "@stylistic/eslint-plugin": "^2.13.0", - "@tanstack/eslint-plugin-query": "^5.91.4", - "@testing-library/jest-dom": "^6.9.1", + "@tanstack/eslint-plugin-query": "^5.101.4", + "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.3.2", - "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/culori": "^4.0.1", - "@types/node": "^24.10.1", - "@types/react": "^19.2.15", + "@types/node": "^26.1.1", + "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", - "@typescript-eslint/eslint-plugin": "^8.60.0", - "@typescript-eslint/parser": "^8.60.0", - "@typescript-eslint/utils": "^8.60.0", - "@vitejs/plugin-react": "^6.0.1", - "@vitejs/plugin-react-swc": "^4.2.3", - "@vitest/coverage-v8": "^4.1.4", + "@typescript-eslint/eslint-plugin": "^8.65.0", + "@typescript-eslint/parser": "^8.65.0", + "@typescript-eslint/utils": "^8.65.0", + "@vitejs/plugin-react": "^6.0.4", + "@vitejs/plugin-react-swc": "^4.3.2", + "@vitest/coverage-v8": "^4.1.10", "babel-plugin-react-compiler": "^1.0.0", - "eslint": "^10.3.0", + "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-i18next": "^6.1.4", - "eslint-plugin-jsonc": "^3.1.2", + "eslint-plugin-i18next": "^6.1.5", + "eslint-plugin-jsonc": "^3.3.0", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-perfectionist": "^5.9.0", - "eslint-plugin-prettier": "^5.5.5", + "eslint-plugin-perfectionist": "^5.10.0", + "eslint-plugin-prettier": "^5.5.6", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.1.1", - "eslint-plugin-react-refresh": "^0.5.2", - "eslint-plugin-unicorn": "^64.0.0", - "globals": "^15.15.0", - "happy-dom": "^20.8.3", - "jsonc-eslint-parser": "^2.4.0", - "msw": "^2.12.10", + "eslint-plugin-react-refresh": "^0.5.3", + "eslint-plugin-unicorn": "^72.0.0", + "globals": "^17.8.0", + "happy-dom": "^20.11.1", + "jsonc-eslint-parser": "^3.1.0", + "msw": "^2.15.0", "openapi-merge-cli": "^1.3.2", - "prettier": "^3.8.1", + "prettier": "^3.9.6", "ts-morph": "^27.0.2", "typescript": "^6.0.3", - "typescript-eslint": "^8.60.0", - "vite": "^8.0.16", - "vite-plugin-css-injected-by-js": "^3.5.2", - "vitest": "^4.1.4", + "typescript-eslint": "^8.65.0", + "vite": "^8.1.5", + "vite-plugin-css-injected-by-js": "^5.0.2", + "vitest": "^4.1.10", "web-worker": "^1.5.0" }, "pnpm": { diff --git a/airflow-core/src/airflow/ui/pnpm-lock.yaml b/airflow-core/src/airflow/ui/pnpm-lock.yaml index 256fa44174f5c..67be072e7ee6d 100644 --- a/airflow-core/src/airflow/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/ui/pnpm-lock.yaml @@ -42,53 +42,53 @@ importers: specifier: ^2.3.4 version: 2.3.4 '@chakra-ui/react': - specifier: ~3.34.0 - version: 3.34.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ~3.36.1 + version: 3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.2.15)(react@19.2.6) + version: 11.14.0(@types/react@19.2.17)(react@19.2.7) '@guanmingchiu/sqlparser-ts': - specifier: ^0.61.1 - version: 0.61.1 + specifier: ^0.62.0 + version: 0.62.0 '@lezer/highlight': specifier: ^1.2.3 version: 1.2.3 '@monaco-editor/react': specifier: ^4.7.0 - version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-query': - specifier: ^5.90.21 - version: 5.90.21(react@19.2.6) + specifier: ^5.101.4 + version: 5.101.4(react@19.2.7) '@tanstack/react-table': specifier: ^8.21.3 - version: 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 8.21.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-virtual': - specifier: ^3.13.21 - version: 3.13.21(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^3.14.8 + version: 3.14.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@visx/group': - specifier: ^3.12.0 - version: 3.12.0(react@19.2.6) + specifier: ^4.0.0 + version: 4.0.0(@types/react@19.2.17)(react@19.2.7) '@visx/shape': - specifier: ^3.12.0 - version: 3.12.0(react@19.2.6) + specifier: ^4.0.0 + version: 4.0.0(@types/react@19.2.17)(react@19.2.7) '@xyflow/react': - specifier: ^12.10.1 - version: 12.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^12.11.2 + version: 12.11.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) anser: specifier: ^2.3.5 version: 2.3.5 axios: - specifier: ^1.16.0 - version: 1.16.1 + specifier: ^1.18.1 + version: 1.18.1 chakra-react-select: - specifier: ^6.1.1 - version: 6.1.1(@chakra-ui/react@3.34.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.15)(next-themes@0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^6.1.3 + version: 6.1.3(@chakra-ui/react@3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react@19.2.17)(next-themes@0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) chart.js: specifier: ^4.5.1 version: 4.5.1 chartjs-adapter-dayjs-4: specifier: ^1.0.4 - version: 1.0.4(chart.js@4.5.1)(dayjs@1.11.19) + version: 1.0.4(chart.js@4.5.1)(dayjs@1.11.21) chartjs-plugin-annotation: specifier: ^3.1.0 version: 3.1.0(chart.js@4.5.1) @@ -96,8 +96,8 @@ importers: specifier: ^4.0.2 version: 4.0.2 dayjs: - specifier: ^1.11.19 - version: 1.11.19 + specifier: ^1.11.21 + version: 1.11.21 elkjs: specifier: ^0.11.1 version: 0.11.1 @@ -105,189 +105,189 @@ importers: specifier: ^1.11.13 version: 1.11.13 i18next: - specifier: ^25.8.16 - version: 25.8.16(typescript@6.0.3) + specifier: ^26.3.6 + version: 26.3.6(typescript@6.0.3) i18next-browser-languagedetector: specifier: ^8.2.1 version: 8.2.1 i18next-http-backend: - specifier: ^3.0.5 - version: 3.0.5 + specifier: ^4.0.1 + version: 4.0.1 monaco-editor: - specifier: ^0.52.2 - version: 0.52.2 + specifier: ^0.55.1 + version: 0.55.1 next-themes: specifier: ^0.4.6 - version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react: - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.7 + version: 19.2.7 react-chartjs-2: specifier: ^5.3.1 - version: 5.3.1(chart.js@4.5.1)(react@19.2.6) + version: 5.3.1(chart.js@4.5.1)(react@19.2.7) react-dom: - specifier: ^19.2.6 - version: 19.2.6(react@19.2.6) + specifier: ^19.2.7 + version: 19.2.7(react@19.2.7) react-hook-form: - specifier: ^7.71.2 - version: 7.71.2(react@19.2.6) + specifier: ^7.83.0 + version: 7.83.0(react@19.2.7) react-hotkeys-hook: - specifier: ^4.6.1 - version: 4.6.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^4.6.2 + version: 4.6.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-i18next: - specifier: ^16.6.5 - version: 16.6.5(i18next@25.8.16(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + specifier: ^17.0.11 + version: 17.0.11(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react-icons: - specifier: ^5.6.0 - version: 5.6.0(react@19.2.6) + specifier: ^5.7.0 + version: 5.7.0(react@19.2.7) react-innertext: specifier: ^1.1.5 - version: 1.1.5(@types/react@19.2.15)(react@19.2.6) + version: 1.1.5(@types/react@19.2.17)(react@19.2.7) react-markdown: - specifier: ^9.1.0 - version: 9.1.0(@types/react@19.2.15)(react@19.2.6) + specifier: ^10.1.0 + version: 10.1.0(@types/react@19.2.17)(react@19.2.7) react-resizable-panels: specifier: ^3.0.6 - version: 3.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.0.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-router-dom: - specifier: ^7.13.1 - version: 7.13.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^7.18.1 + version: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-syntax-highlighter: - specifier: ^15.6.1 - version: 15.6.1(react@19.2.6) + specifier: ^16.1.1 + version: 16.1.1(react@19.2.7) remark-gfm: specifier: ^4.0.1 version: 4.0.1 use-debounce: - specifier: ^10.1.0 - version: 10.1.0(react@19.2.6) + specifier: ^10.1.1 + version: 10.1.1(react@19.2.7) usehooks-ts: specifier: ^3.1.1 - version: 3.1.1(react@19.2.6) + version: 3.1.1(react@19.2.7) yaml: - specifier: '>=2.8.3' - version: 2.8.3 + specifier: ^2.9.0 + version: 2.9.0 zustand: - specifier: ^5.0.11 - version: 5.0.11(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) + specifier: ^5.0.14 + version: 5.0.14(@types/react@19.2.17)(react@19.2.7)(use-sync-external-store@1.6.0(react@19.2.7)) devDependencies: '@7nohe/openapi-react-query-codegen': specifier: ^1.6.2 version: 1.6.2(commander@12.1.0)(glob@11.1.0)(magicast@0.3.5)(ts-morph@27.0.2)(typescript@6.0.3) '@eslint/compat': - specifier: ^2.0.5 - version: 2.0.5(eslint@10.3.0(jiti@1.21.7)) + specifier: ^2.1.0 + version: 2.1.0(eslint@10.8.0(jiti@1.21.7)) '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.3.0(jiti@1.21.7)) + version: 10.0.1(eslint@10.8.0(jiti@1.21.7)) '@playwright/test': - specifier: ^1.60.0 - version: 1.60.0 + specifier: ^1.62.0 + version: 1.62.1 '@rolldown/plugin-babel': - specifier: ^0.2.2 - version: 0.2.2(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + specifier: ^0.2.3 + version: 0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.2.1)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) '@stylistic/eslint-plugin': specifier: ^2.13.0 - version: 2.13.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + version: 2.13.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) '@tanstack/eslint-plugin-query': - specifier: ^5.91.4 - version: 5.91.4(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^5.101.4 + version: 5.101.4(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) '@testing-library/jest-dom': - specifier: ^6.9.1 - version: 6.9.1 + specifier: ^7.0.0 + version: 7.0.0(@testing-library/dom@10.4.0) '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@trivago/prettier-plugin-sort-imports': - specifier: ^4.3.0 - version: 4.3.0(prettier@3.8.1) + specifier: ^6.0.2 + version: 6.0.2(prettier@3.9.6) '@types/culori': specifier: ^4.0.1 version: 4.0.1 '@types/node': - specifier: ^24.10.1 - version: 24.10.3 + specifier: ^26.1.1 + version: 26.1.2 '@types/react': - specifier: ^19.2.15 - version: 19.2.15 + specifier: ^19.2.17 + version: 19.2.17 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.15) + version: 19.2.3(@types/react@19.2.17) '@types/react-syntax-highlighter': specifier: ^15.5.13 version: 15.5.13 '@typescript-eslint/eslint-plugin': - specifier: ^8.60.0 - version: 8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: ^8.60.0 - version: 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) '@typescript-eslint/utils': - specifier: ^8.60.0 - version: 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) '@vitejs/plugin-react': - specifier: ^6.0.1 - version: 6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + specifier: ^6.0.4 + version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.2.1)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) '@vitejs/plugin-react-swc': - specifier: ^4.2.3 - version: 4.2.3(@swc/helpers@0.5.19)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + specifier: ^4.3.2 + version: 4.3.3(@swc/helpers@0.5.23)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) '@vitest/coverage-v8': - specifier: ^4.1.4 - version: 4.1.4(vitest@4.1.4) + specifier: ^4.1.10 + version: 4.1.10(vitest@4.1.10) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 eslint: - specifier: ^10.3.0 - version: 10.3.0(jiti@1.21.7) + specifier: ^10.8.0 + version: 10.8.0(jiti@1.21.7) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.3.0(jiti@1.21.7)) + version: 10.1.8(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-i18next: - specifier: ^6.1.4 - version: 6.1.4 + specifier: ^6.1.5 + version: 6.1.5 eslint-plugin-jsonc: - specifier: ^3.1.2 - version: 3.1.2(eslint@10.3.0(jiti@1.21.7)) + specifier: ^3.3.0 + version: 3.3.0(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@10.3.0(jiti@1.21.7)) + version: 6.10.2(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-perfectionist: - specifier: ^5.9.0 - version: 5.9.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^5.10.0 + version: 5.10.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) eslint-plugin-prettier: - specifier: ^5.5.5 - version: 5.5.5(eslint-config-prettier@10.1.8(eslint@10.3.0(jiti@1.21.7)))(eslint@10.3.0(jiti@1.21.7))(prettier@3.8.1) + specifier: ^5.5.6 + version: 5.5.6(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@1.21.7)))(eslint@10.8.0(jiti@1.21.7))(prettier@3.9.6) eslint-plugin-react: specifier: ^7.37.5 - version: 7.37.5(eslint@10.3.0(jiti@1.21.7)) + version: 7.37.5(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-react-hooks: specifier: ^7.1.1 - version: 7.1.1(eslint@10.3.0(jiti@1.21.7)) + version: 7.1.1(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-react-refresh: - specifier: ^0.5.2 - version: 0.5.2(eslint@10.3.0(jiti@1.21.7)) + specifier: ^0.5.3 + version: 0.5.3(eslint@10.8.0(jiti@1.21.7)) eslint-plugin-unicorn: - specifier: ^64.0.0 - version: 64.0.0(eslint@10.3.0(jiti@1.21.7)) + specifier: ^72.0.0 + version: 72.0.0(eslint@10.8.0(jiti@1.21.7)) globals: - specifier: ^15.15.0 - version: 15.15.0 + specifier: ^17.8.0 + version: 17.8.0 happy-dom: - specifier: '>=20.8.8' - version: 20.8.9 + specifier: ^20.11.1 + version: 20.11.1 jsonc-eslint-parser: - specifier: ^2.4.0 - version: 2.4.1 + specifier: ^3.1.0 + version: 3.1.0 msw: - specifier: ^2.12.10 - version: 2.12.10(@types/node@24.10.3)(typescript@6.0.3) + specifier: ^2.15.0 + version: 2.15.0(@types/node@26.1.2)(typescript@6.0.3) openapi-merge-cli: specifier: ^1.3.2 version: 1.3.2 prettier: - specifier: ^3.8.1 - version: 3.8.1 + specifier: ^3.9.6 + version: 3.9.6 ts-morph: specifier: ^27.0.2 version: 27.0.2 @@ -295,17 +295,17 @@ importers: specifier: ^6.0.3 version: 6.0.3 typescript-eslint: - specifier: ^8.60.0 - version: 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + specifier: ^8.65.0 + version: 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) vite: - specifier: ^8.0.16 - version: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + specifier: ^8.1.5 + version: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) vite-plugin-css-injected-by-js: - specifier: ^3.5.2 - version: 3.5.2(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + specifier: ^5.0.2 + version: 5.0.2(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) vitest: - specifier: ^4.1.4 - version: 4.1.4(@types/node@24.10.3)(@vitest/coverage-v8@4.1.4)(happy-dom@20.8.9)(msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3))(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + specifier: ^4.1.10 + version: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3))(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) web-worker: specifier: ^1.5.0 version: 1.5.0 @@ -329,16 +329,12 @@ packages: resolution: {integrity: sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==} engines: {node: '>= 16'} - '@ark-ui/react@5.34.1': - resolution: {integrity: sha512-RJlXCvsHzbK9LVxUVtaSD5pyF1PL8IUR1rHHkf0H0Sa397l6kOFE4EH7MCSj3pDumj2NsmKDVeVgfkfG0KCuEw==} + '@ark-ui/react@5.37.2': + resolution: {integrity: sha512-Q0R2Ah50kUhup0Ljxg65zGJq5yBV52BLm1coRkjHHid40d1yclaDGfhPL48kcF/xtjAFlGLkL6SiENkGvfh+mw==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -355,14 +351,6 @@ packages: resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.17.7': - resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.26.10': - resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} @@ -371,22 +359,10 @@ packages: resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.24.7': - resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-function-name@7.24.7': - resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} - engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.24.7': - resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} @@ -401,10 +377,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-split-export-declaration@7.24.7': - resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} @@ -433,11 +405,6 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.29.2': resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} @@ -456,10 +423,6 @@ packages: resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} - engines: {node: '>=6.9.0'} - '@babel/runtime@7.29.7': resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} @@ -468,18 +431,10 @@ packages: resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.23.2': - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.17.0': - resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} - engines: {node: '>=6.9.0'} - '@babel/types@7.26.10': resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} engines: {node: '>=6.9.0'} @@ -499,21 +454,21 @@ packages: '@chakra-ui/anatomy@2.3.4': resolution: {integrity: sha512-fFIYN7L276gw0Q7/ikMMlZxP7mvnjRaWJ7f3Jsf9VtDOi6eAYIBRrhQe6+SZ0PGmoOkRaBc7gSE5oeIbgFFyrw==} - '@chakra-ui/react@3.34.0': - resolution: {integrity: sha512-VLhpVwv5IVxhwajO10KnS1VQT4hDqQMQP/A796Ya+uVu8AdoSX+5HHyTLTkYIeXIDMe0xLqJfov04OBKbBchJA==} + '@chakra-ui/react@3.36.1': + resolution: {integrity: sha512-8uPVBdkw9CfwDQSGGmNqx8jLygUanV9virh2dwbj3x02Cu5bmw12ZCRdD/RZ+00+KrklJZlVnmG20y7PwLhyqg==} peerDependencies: '@emotion/react': '>=11' react: '>=18' react-dom: '>=18' - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@2.0.0-alpha.3': + resolution: {integrity: sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==} - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@2.0.0-alpha.3': + resolution: {integrity: sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@2.0.1': + resolution: {integrity: sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==} '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -569,8 +524,8 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@2.0.5': - resolution: {integrity: sha512-IbHDbHJfkVNv6xjlET8AIVo/K1NQt7YT4Rp6ok/clyBGcpRx1l6gv0Rq3vBvYfPJIZt6ODf66Zq08FJNDpnzgg==} + '@eslint/compat@2.1.0': + resolution: {integrity: sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^8.40 || 9 || 10 @@ -582,14 +537,18 @@ packages: resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.5.5': - resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/core@1.2.1': resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/css-tree@4.0.5': + resolution: {integrity: sha512-iPmijIAq4hlIJB86PYmY/fcZORHtjphSqICDbwuw32A/JmkhZQ/K/6TjHE03zqf3n5yABpVcbRAMG8Mi9ojy8g==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@eslint/js@10.0.1': resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -603,34 +562,30 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.6.1': - resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@floating-ui/core@1.7.1': - resolution: {integrity: sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==} - '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@floating-ui/dom@1.7.1': - resolution: {integrity: sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==} + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} '@floating-ui/dom@1.7.6': resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} - '@floating-ui/utils@0.2.9': - resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} - '@guanmingchiu/sqlparser-ts@0.61.1': - resolution: {integrity: sha512-5RA05UHDkcm4cyhBNz2oJqU+8+fhCZvseSGtAvuVcwM1EEh2FfRaU1qdPygpriGqsQRT3Cn1PK5YShJffQjmXg==} + '@guanmingchiu/sqlparser-ts@0.62.0': + resolution: {integrity: sha512-m0YUe1oPzaixw0YX8Es2B8tA8UDPwT6uMIsKocTfyOcpb8tQIYWrP5Im70LT3p8tARLm718M6SObAxNYc0Wi3A==} engines: {node: '>=16.0.0'} '@hey-api/openapi-ts@0.52.0': @@ -660,46 +615,46 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@1.0.2': - resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} - engines: {node: '>=18'} + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/confirm@5.1.21': - resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} - engines: {node: '>=18'} + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/core@10.3.2': - resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} - engines: {node: '>=18'} + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/figures@1.0.15': - resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} - engines: {node: '>=18'} + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/type@3.0.10': - resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} - engines: {node: '>=18'} + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@internationalized/date@3.11.0': - resolution: {integrity: sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q==} + '@internationalized/date@3.12.2': + resolution: {integrity: sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==} - '@internationalized/number@3.6.5': - resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==} + '@internationalized/number@3.6.6': + resolution: {integrity: sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==} '@isaacs/cliui@9.0.0': resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} @@ -712,10 +667,6 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} - '@jridgewell/remapping@2.3.5': resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} @@ -723,19 +674,9 @@ packages: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -761,19 +702,23 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@mswjs/interceptors@0.41.3': - resolution: {integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==} + '@mswjs/interceptors@0.41.9': + resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} engines: {node: '>=18'} - '@napi-rs/wasm-runtime@1.1.5': - resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + '@napi-rs/wasm-runtime@1.2.2': + resolution: {integrity: sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.3 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.3 '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@open-draft/deferred-promise@3.0.0': + resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} + '@open-draft/logger@0.3.0': resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} @@ -784,118 +729,112 @@ packages: resolution: {integrity: sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@oxc-project/types@0.142.0': + resolution: {integrity: sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==} - '@pandacss/is-valid-prop@1.9.0': - resolution: {integrity: sha512-AZvpXWGyjbHc8TC+YVloQ31Z2c4j2xMvYj6UfVxuZdB5w4c9+4N8wy5R7I/XswNh8e4cfUlkvsEGDXjhJRgypw==} + '@pandacss/is-valid-prop@1.11.5': + resolution: {integrity: sha512-8m1/gG0wSRMa1QypCkWzeKUeMKY7k14nxsJCHs7Z1g1fI9I7WsLjW/VI58bLZdJxAxtoreMtm6TfIITda8P4zQ==} + engines: {node: '>=20'} - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pkgr/core@0.3.6': + resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} + engines: {node: ^14.18.0 || >=16.0.0} - '@playwright/test@1.60.0': - resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==} - engines: {node: '>=18'} + '@playwright/test@1.62.1': + resolution: {integrity: sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==} + engines: {node: '>=20'} hasBin: true - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + '@rolldown/binding-android-arm64@1.2.1': + resolution: {integrity: sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + '@rolldown/binding-darwin-arm64@1.2.1': + resolution: {integrity: sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + '@rolldown/binding-darwin-x64@1.2.1': + resolution: {integrity: sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + '@rolldown/binding-freebsd-x64@1.2.1': + resolution: {integrity: sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.1': + resolution: {integrity: sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + '@rolldown/binding-linux-arm64-gnu@1.2.1': + resolution: {integrity: sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + '@rolldown/binding-linux-arm64-musl@1.2.1': + resolution: {integrity: sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + '@rolldown/binding-linux-ppc64-gnu@1.2.1': + resolution: {integrity: sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + '@rolldown/binding-linux-s390x-gnu@1.2.1': + resolution: {integrity: sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + '@rolldown/binding-linux-x64-gnu@1.2.1': + resolution: {integrity: sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + '@rolldown/binding-linux-x64-musl@1.2.1': + resolution: {integrity: sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + '@rolldown/binding-openharmony-arm64@1.2.1': + resolution: {integrity: sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.2.1': + resolution: {integrity: sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + '@rolldown/binding-win32-arm64-msvc@1.2.1': + resolution: {integrity: sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + '@rolldown/binding-win32-x64-msvc@1.2.1': + resolution: {integrity: sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/plugin-babel@0.2.2': - resolution: {integrity: sha512-q9pE8+47bQNHb5eWVcE6oXppA+JTSwvnrhH53m0ZuHuK5MLvwsLoWrWzBTFQqQ06BVxz1gp0HblLsch8o6pvZw==} + '@rolldown/plugin-babel@0.2.3': + resolution: {integrity: sha512-+zEk16yGlz1F9STiRr6uG9hmIXb6nprjLczV/htGptYuLoCuxb+itZ03RKCEeOhBpDDd1NU7qF6x1VLMUp62bw==} engines: {node: '>=22.12.0 || ^24.0.0'} peerDependencies: '@babel/core': ^7.29.0 || ^8.0.0-rc.1 @@ -911,12 +850,6 @@ packages: vite: optional: true - '@rolldown/pluginutils@1.0.0-rc.2': - resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} - - '@rolldown/pluginutils@1.0.0-rc.7': - resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} - '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} @@ -929,72 +862,80 @@ packages: peerDependencies: eslint: '>=8.40.0' - '@swc/core-darwin-arm64@1.15.18': - resolution: {integrity: sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==} + '@swc/core-darwin-arm64@1.15.47': + resolution: {integrity: sha512-GsoMtan3ojGGMGFbl31mmRu5ctZ56re8grGE8mO/OHJ8O+JRkzod02fe7X6ZQ8JvamA3imkEkx/h3u+vsOgPgA==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.18': - resolution: {integrity: sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==} + '@swc/core-darwin-x64@1.15.47': + resolution: {integrity: sha512-leTi7Rx3KF4zcC637iqWgk9SoV8VXAD8ppQYXsep63px5A/UftOcxLN1pmr8Z1si/YvX90ompP/rHgpYkgwXWg==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.18': - resolution: {integrity: sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==} + '@swc/core-linux-arm-gnueabihf@1.15.47': + resolution: {integrity: sha512-hBqHuoWKKIsKmDBn9qVeWqj5GWZhtlcczVaqQmNRXsDfq+voR5CxKRfamA367QjJXtceYuliLFfEL8QsskRM2g==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.18': - resolution: {integrity: sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==} + '@swc/core-linux-arm64-gnu@1.15.47': + resolution: {integrity: sha512-TBxvRz+B4K205TWHHZxWVxkC2RFNP/Mz3PNcECBos5PsKwxjg3QSJzdoebr0VCf0Bfh8HOPldKxAP/8XkFe9gA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [glibc] - '@swc/core-linux-arm64-musl@1.15.18': - resolution: {integrity: sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==} + '@swc/core-linux-arm64-musl@1.15.47': + resolution: {integrity: sha512-3Yu3Uq/VgytqsPjTMbkPU1ExADytbdWbruJYhA584E9jrpE2Ki+R6VVPoZCeAVk1Cb7QxcRTgblw6bSa6a/R+w==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [musl] - '@swc/core-linux-x64-gnu@1.15.18': - resolution: {integrity: sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==} + '@swc/core-linux-ppc64-gnu@1.15.47': + resolution: {integrity: sha512-wfdMi5IaOaNtmh2/6geRoxIdNfqylUZFdtzTKS655y1axWfIWyx7As74vv0wVdjeCIZ3WmCI9odDd4rUttXOSQ==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + + '@swc/core-linux-s390x-gnu@1.15.47': + resolution: {integrity: sha512-3hHYBY0yx8Ez7GMRrkhXHQzMdR5IZA6Wq5Ee4svlgwvSECLpnAJ9+0AimEGUFDvuLwE7nV/2+PYe8+Nm4rvNcQ==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + + '@swc/core-linux-x64-gnu@1.15.47': + resolution: {integrity: sha512-TjfhjgP/jGCfFHYC3JQPhJA1HwErbIJ9JfREDc1KNkvY6P0LodCgKVIlQ5deeTbkG7ih3bF5PHJLuLpaZjdRyQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [glibc] - '@swc/core-linux-x64-musl@1.15.18': - resolution: {integrity: sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==} + '@swc/core-linux-x64-musl@1.15.47': + resolution: {integrity: sha512-CQpS8Ge/avfjZd0UEwG/sds83Uu32deQXcV1Jo3jD0mmvQQqtYAjpsDZXugmheeAwmt+YIuoVtVHro8LMYHqsQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [musl] - '@swc/core-win32-arm64-msvc@1.15.18': - resolution: {integrity: sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==} + '@swc/core-win32-arm64-msvc@1.15.47': + resolution: {integrity: sha512-0W8IKHsUTYiT7G2RqtOoVWk+89yzZikIiDUb/sCK6BmQDBhN91hQSfyUtW12jhEWLzYgcfmisfsZrmZE+84U1A==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.18': - resolution: {integrity: sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==} + '@swc/core-win32-ia32-msvc@1.15.47': + resolution: {integrity: sha512-ZIp49d2Z4/ka2jO9otOg4hDvTdPmp86kVOgS2M5FCPI7eKKZ1W0boxWn+8XeZrfERtFGW0AlMRm4JhlJa7l3NA==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.18': - resolution: {integrity: sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==} + '@swc/core-win32-x64-msvc@1.15.47': + resolution: {integrity: sha512-2h8Iek95vnixkBRCo+H8p09+Q5ll2NgSMFrWTy0iKt7+/t+8/T5mBpiT6c0ZxSS7wcWjwZ9sGZkK70tTSYHdDw==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.18': - resolution: {integrity: sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==} + '@swc/core@1.15.47': + resolution: {integrity: sha512-FbsO5JcfOjfH38W/rohBRBweJeERsAuIP4f377lmkmxTcq9exjtx4SkRuZY5CdfhR2CBVwDIJegBpJDffwNsOg==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -1005,26 +946,26 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.19': - resolution: {integrity: sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==} + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} - '@swc/types@0.1.25': - resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + '@swc/types@0.1.27': + resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==} - '@tanstack/eslint-plugin-query@5.91.4': - resolution: {integrity: sha512-8a+GAeR7oxJ5laNyYBQ6miPK09Hi18o5Oie/jx8zioXODv/AUFLZQecKabPdpQSLmuDXEBPKFh+W5DKbWlahjQ==} + '@tanstack/eslint-plugin-query@5.101.4': + resolution: {integrity: sha512-jqAZJWXGd5PthJYH9wmC2O5Ry5xAN2/7zxi9qcANQ+Xix8V5JkqNRjZ8Fh+rYzqzVYGiHqbrHekt+uh38OZVpw==} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ^5.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ^5.4.0 || ^6.0.0 peerDependenciesMeta: typescript: optional: true - '@tanstack/query-core@5.90.20': - resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} + '@tanstack/query-core@5.101.4': + resolution: {integrity: sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw==} - '@tanstack/react-query@5.90.21': - resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} + '@tanstack/react-query@5.101.4': + resolution: {integrity: sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA==} peerDependencies: react: ^18 || ^19 @@ -1035,8 +976,8 @@ packages: react: '>=16.8' react-dom: '>=16.8' - '@tanstack/react-virtual@3.13.21': - resolution: {integrity: sha512-SYXFrmrbPgXBvf+HsOsKhFgqSe4M6B29VHOsX9Jih9TlNkNkDWx0hWMiMLUghMEzyUz772ndzdEeCEBx+3GIZw==} + '@tanstack/react-virtual@3.14.9': + resolution: {integrity: sha512-qZyr0FZDP8rDC4WBhsryIZmAd9bveJvFGUJJtskWaew6/0dTRS6wZxnR6VQ5bY2KwL3LjerrHqQLk3a0GKcPXQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -1045,16 +986,18 @@ packages: resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} engines: {node: '>=12'} - '@tanstack/virtual-core@3.13.21': - resolution: {integrity: sha512-ww+fmLHyCbPSf7JNbWZP3g7wl6SdNo3ah5Aiw+0e9FDErkVHLKprYUrwTm7dF646FtEkN/KkAKPYezxpmvOjxw==} + '@tanstack/virtual-core@3.17.7': + resolution: {integrity: sha512-bp+v10y65sp2H7WpWfIMyxTNfl8ZVfxFTLRjPIFRryi6FV/J33z4IS53WO4pTk36KlvJ4iLiQz+oaydDC1xbcA==} '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/jest-dom@7.0.0': + resolution: {integrity: sha512-HKAH9C6mBo5yBG6yRO5i43L2iisencAo5z+o5P/saHUoY+miC5ivXRxHBJcFyB5ypPNxHJdK3BoF/3O4DIptMg==} + engines: {node: '>=22', npm: '>=6', yarn: '>=1'} + peerDependencies: + '@testing-library/dom': '>=10 <11' '@testing-library/react@16.3.2': resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} @@ -1071,26 +1014,36 @@ packages: '@types/react-dom': optional: true - '@trivago/prettier-plugin-sort-imports@4.3.0': - resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==} + '@trivago/prettier-plugin-sort-imports@6.0.2': + resolution: {integrity: sha512-3DgfkukFyC/sE/VuYjaUUWoFfuVjPK55vOFDsxD56XXynFMCZDYFogH2l/hDfOsQAm1myoU/1xByJ3tWqtulXA==} + engines: {node: '>= 20'} peerDependencies: '@vue/compiler-sfc': 3.x prettier: 2.x - 3.x + prettier-plugin-ember-template-tag: '>= 2.0.0' + prettier-plugin-svelte: 3.x + svelte: 4.x || 5.x peerDependenciesMeta: '@vue/compiler-sfc': optional: true + prettier-plugin-ember-template-tag: + optional: true + prettier-plugin-svelte: + optional: true + svelte: + optional: true '@ts-morph/common@0.28.1': resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==} - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/culori@4.0.1': resolution: {integrity: sha512-43M51r/22CjhbOXyGT361GZ9vncSVQ39u62x5eJdBQFviI8zWp2X5jzqg7k4M6PVgDQAClpy2bUe2dtwEgEDVQ==} @@ -1122,8 +1075,8 @@ packages: '@types/d3-interpolate@3.0.4': resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} - '@types/d3-path@1.0.11': - resolution: {integrity: sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw==} + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} '@types/d3-scale@4.0.2': resolution: {integrity: sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==} @@ -1131,8 +1084,8 @@ packages: '@types/d3-selection@3.0.11': resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} - '@types/d3-shape@1.3.12': - resolution: {integrity: sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==} + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} '@types/d3-time-format@2.1.0': resolution: {integrity: sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==} @@ -1164,30 +1117,27 @@ packages: '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} - '@types/hast@2.3.10': - resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} - '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.10.3': - resolution: {integrity: sha512-gqkrWUsS8hcm0r44yn7/xZeV1ERva/nLgrLxFRUGb7aoNMIJfZJ3AC261zDQuOAKC7MiXai1WCpYc48jAHoShQ==} + '@types/node@26.1.2': + resolution: {integrity: sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/prismjs@1.26.6': + resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -1201,12 +1151,18 @@ packages: peerDependencies: '@types/react': '*' - '@types/react@19.2.15': - resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + + '@types/set-cookie-parser@2.4.10': + resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1219,96 +1175,104 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.60.0': - resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} + '@typescript-eslint/eslint-plugin@8.65.0': + resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.0 + '@typescript-eslint/parser': ^8.65.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.60.0': - resolution: {integrity: sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==} + '@typescript-eslint/parser@8.65.0': + resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.60.0': - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + '@typescript-eslint/project-service@8.65.0': + resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.60.0': - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + '@typescript-eslint/scope-manager@8.65.0': + resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.60.0': - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + '@typescript-eslint/tsconfig-utils@8.65.0': + resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.60.0': - resolution: {integrity: sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==} + '@typescript-eslint/type-utils@8.65.0': + resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.60.0': - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} + '@typescript-eslint/types@8.65.0': + resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.60.0': - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + '@typescript-eslint/typescript-estree@8.65.0': + resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.60.0': - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + '@typescript-eslint/utils@8.65.0': + resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.60.0': - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + '@typescript-eslint/visitor-keys@8.65.0': + resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} deprecated: Potential CWE-502 - Update to 1.3.1 or higher - '@visx/curve@3.12.0': - resolution: {integrity: sha512-Ng1mefXIzoIoAivw7dJ+ZZYYUbfuwXgZCgQynShr6ZIVw7P4q4HeQfJP3W24ON+1uCSrzoycHSXRelhR9SBPcw==} + '@visx/curve@4.0.0': + resolution: {integrity: sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==} - '@visx/group@3.12.0': - resolution: {integrity: sha512-Dye8iS1alVXPv7nj/7M37gJe6sSKqJLH7x6sEWAsRQ9clI0kFvjbKcKgF+U3aAVQr0NCohheFV+DtR8trfK/Ag==} + '@visx/group@4.0.0': + resolution: {integrity: sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==} peerDependencies: - react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@visx/scale@3.12.0': - resolution: {integrity: sha512-+ubijrZ2AwWCsNey0HGLJ0YKNeC/XImEFsr9rM+Uef1CM3PNM43NDdNTrdBejSlzRq0lcfQPWYMYQFSlkLcPOg==} + '@visx/scale@4.0.0': + resolution: {integrity: sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==} - '@visx/shape@3.12.0': - resolution: {integrity: sha512-/1l0lrpX9tPic6SJEalryBKWjP/ilDRnQA+BGJTI1tj7i23mJ/J0t4nJHyA1GrL4QA/bM/qTJ35eyz5dEhJc4g==} + '@visx/shape@4.0.0': + resolution: {integrity: sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==} peerDependencies: - react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@visx/vendor@3.12.0': - resolution: {integrity: sha512-SVO+G0xtnL9dsNpGDcjCgoiCnlB3iLSM9KLz1sLbSrV7RaVXwY3/BTm2X9OWN1jH2a9M+eHt6DJ6sE6CXm4cUg==} + '@visx/vendor@4.0.0': + resolution: {integrity: sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==} - '@vitejs/plugin-react-swc@4.2.3': - resolution: {integrity: sha512-QIluDil2prhY1gdA3GGwxZzTAmLdi8cQ2CcuMW4PB/Wu4e/1pzqrwhYWVd09LInCRlDUidQjd0B70QWbjWtLxA==} + '@vitejs/plugin-react-swc@4.3.3': + resolution: {integrity: sha512-bti8ZAcvz4Lh6/e4Uk2k3aa1TiUXbbMsahuqOHvd3MveFTkKDZOA6wQVkpj7J/+tepX/wGfe+lsGh/t24HTXMQ==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^4 || ^5 || ^6 || ^7 + vite: ^4 || ^5 || ^6 || ^7 || ^8 - '@vitejs/plugin-react@6.0.1': - resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + '@vitejs/plugin-react@6.0.5': + resolution: {integrity: sha512-BOVzne/NL162sMdResB25mUv+vWMF5NoAjNf09TeGlE7ZpszZWSD3winycicLJw72yeVsoCn/2kOhEuCvEShMA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 @@ -1320,20 +1284,20 @@ packages: babel-plugin-react-compiler: optional: true - '@vitest/coverage-v8@4.1.4': - resolution: {integrity: sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w==} + '@vitest/coverage-v8@4.1.10': + resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} peerDependencies: - '@vitest/browser': 4.1.4 - vitest: 4.1.4 + '@vitest/browser': 4.1.10 + vitest: 4.1.10 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.4': - resolution: {integrity: sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==} + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} - '@vitest/mocker@4.1.4': - resolution: {integrity: sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==} + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1343,258 +1307,270 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.4': - resolution: {integrity: sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==} + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} - '@vitest/runner@4.1.4': - resolution: {integrity: sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==} + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} - '@vitest/snapshot@4.1.4': - resolution: {integrity: sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==} + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} - '@vitest/spy@4.1.4': - resolution: {integrity: sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==} + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} - '@vitest/utils@4.1.4': - resolution: {integrity: sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==} + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} - '@xyflow/react@12.10.1': - resolution: {integrity: sha512-5eSWtIK/+rkldOuFbOOz44CRgQRjtS9v5nufk77DV+XBnfCGL9HAQ8PG00o2ZYKqkEU/Ak6wrKC95Tu+2zuK3Q==} + '@xyflow/react@12.11.2': + resolution: {integrity: sha512-eLAlDWJfWnQEhJwGMjlWdAXO9eYllKpliUmPQlAmOLxz6mExXuzMVDUKLMquixgkrtmMFFtug3jGKmYYld12cA==} peerDependencies: + '@types/react': '>=17' + '@types/react-dom': '>=17' react: '>=17' react-dom: '>=17' + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@xyflow/system@0.0.79': + resolution: {integrity: sha512-czLyOh91NF0hIzbNzwi8I6GlqG23BHh2435OddfI6uiaLH3xdrdygO93gqgH1Bv9mhy8XPFQJOBn1FTq4LvEWA==} - '@xyflow/system@0.0.75': - resolution: {integrity: sha512-iXs+AGFLi8w/VlAoc/iSxk+CxfT6o64Uw/k0CKASOPqjqz6E0rb5jFZgJtXGZCpfQI6OQpu5EnumP5fGxQheaQ==} + '@zag-js/accordion@1.41.2': + resolution: {integrity: sha512-7G//V7svGGT8k5avw7bbQvbRC0Q/9QtX51b4iyAB1alR9E5mFd6Ch8q4njwcXClMQ7xePS3jUfVnzVGiRInEiQ==} - '@zag-js/accordion@1.35.3': - resolution: {integrity: sha512-wmw6yo5Zr6ShiKGTc5ICEOJCurWAOSGubIpGISiHi3cZ4tlxKF/vpATIUT3eq8xzdB56YK57yKCujs/WmwqqoA==} + '@zag-js/anatomy@1.41.2': + resolution: {integrity: sha512-Fm9hqdrvaCzCsdcf19G8WZxYtHElKltkGHdhqMEt4XU+ULTr1DK7KbOtDDv9J27CuzqSLALUz5QfRjPftoKHwg==} - '@zag-js/anatomy@1.35.3': - resolution: {integrity: sha512-oqU9iLNNylrtJMBX5Xu4DsxnPNvtZLiobryv2oNtsDI1mi1Fca/XHghQC9K5aYT0qNsmHj1M3W5WAWTaOtPLkQ==} + '@zag-js/angle-slider@1.41.2': + resolution: {integrity: sha512-+7bZHAZx0MEbjTMr2tD+meFJ0EJwFfUEcTqmdLzFGr/ySAMCWlcadDBz+ZmrSn03aKLps8FxliVLzsFJNgUqIQ==} - '@zag-js/angle-slider@1.35.3': - resolution: {integrity: sha512-HXRlmsbNEJSBT53fq9XQKL/vwZWwJC3nprskI7s4f/jy8a4uXPTlv7N7zuBYjew+ScTMzZah6fLWzUztBehmSg==} + '@zag-js/aria-hidden@1.41.2': + resolution: {integrity: sha512-qEcYmwlQr3qjA0T/IZ5a/o7fRUxfQ14tXjAFhR3GXCtxBKaqS+wnq/LN09Xw4bin3QWTINU+Z0oXFs9spWtNwA==} - '@zag-js/aria-hidden@1.35.3': - resolution: {integrity: sha512-dk5POebn10WneQfLrEgbTzwolaXWpCSHL6F3jCTinW9IbOx7BXghzJD21iU5Iun+y9CorqJPW3p7LplYNUMO5Q==} + '@zag-js/async-list@1.41.2': + resolution: {integrity: sha512-NZZEIGFdeDp2uHjsLVegLAGJOYGwI9HPJI1V2c/P1TQmfmrfWyWELAvnnW4kWYVUKYD9TxKQkm6LvqpHrQzgfQ==} - '@zag-js/async-list@1.35.3': - resolution: {integrity: sha512-SXX3wGzLK/maKS1PJ3XfLIGWbu0022f/OhcFsT1PbiHnoFZTH7h2fBhirrCBfy2TYFQ6r5uxgjkhPUNkuaeYnA==} + '@zag-js/auto-resize@1.41.2': + resolution: {integrity: sha512-CYq+JQ1TTkEiK7OcNcMTS0f4wFvtmManvUltije5o50gDQ7vFYA81oQh4A9pAB1keUi9Zv06CNefFARaTcne5w==} - '@zag-js/auto-resize@1.35.3': - resolution: {integrity: sha512-ufG8HSqzLd9h5rnos8aumj8iORlRskeR/gbpJu1NHrnHBWIrpuXm6KJJR2oZhTFY1BUMMk8eYIBA2QkVuiJzWA==} + '@zag-js/avatar@1.41.2': + resolution: {integrity: sha512-+4K0tRtIQysMGuERh5JRmn46uq7gJ6IjJd5DKj74VBtVVY8T6HGk0D0DZxmOIgADHP1qSvowLDoOX8kUyBHarQ==} - '@zag-js/avatar@1.35.3': - resolution: {integrity: sha512-lbQ2Q4Va8AAScKULOHw2tCQez+0JRYGHSMFq6i+dJmeT3dlSgRanm69ra6K2po6hM9E4v6pRe+xOVE+9QMDnuA==} + '@zag-js/carousel@1.41.2': + resolution: {integrity: sha512-H6sDxyWIzkvtHN4M/BYvFy7pi8j+kLEtfPZvgNl2+gRnfAHVK9/XqpoUsjw1DAo5Fh25pPuaTnh52Kml9OK0iA==} - '@zag-js/carousel@1.35.3': - resolution: {integrity: sha512-F+b8HzUeZfB+xUkAkLG4r0Ubui8pj7pSgZhi26ZiWgsM7tsd7cD+xRMXkvPEITN5Fd5QCe3KlVBuE00w5byjmg==} + '@zag-js/cascade-select@1.41.2': + resolution: {integrity: sha512-dBByZmIAJU/B+YIAzczng05lCJXEwEm4df6GmUZtioKHZdeN+WEKUP4qzFDFZdytXympGfJCIBvtgf87gACYVQ==} - '@zag-js/cascade-select@1.35.3': - resolution: {integrity: sha512-Nifdx77hEuAdXqr1wpZSPjLXqygRhq/WvnPjGhCeSqFPpy62uT4JZ3avyjUZ4I0UhvIpkleUcXtFwQ3cSMh4ww==} + '@zag-js/checkbox@1.41.2': + resolution: {integrity: sha512-aQ5dZWHUHRIw4cbLtzrR+dc8M0N6wSiiCml/zbU3ciHOTBXSrs2rKnp/L99xhi97Lj2uCEhpIZ704Ou/MjGuCg==} - '@zag-js/checkbox@1.35.3': - resolution: {integrity: sha512-8XBt/Wg2zSQWqV2ZFqZBQUjYRkOYHA2O3IEi0VVYtds3S1n7Pu/HqkZT5qDw+E/SY2+X9Uyx4hO7h2XrlsiZQQ==} + '@zag-js/clipboard@1.41.2': + resolution: {integrity: sha512-FM+PNGEeY+YpF1dVr9d8kg3DQM66LRnkR4Mva1oprqnrCXTYWj+k7uig893ubSG2xw1GO5b/WJd27kSmNoKnmw==} - '@zag-js/clipboard@1.35.3': - resolution: {integrity: sha512-obTwynBpp6c17fLHe5tg//FQ497QsyCEry+K3bTdlrivWW200wvfHxZ6RKVbKwDAwhH+ye0bI1xkYAId8j7sdA==} + '@zag-js/collapsible@1.41.2': + resolution: {integrity: sha512-uMIp4rqd3iI6VFPMAOcbu9dh9WV4l85nNPYQiBtMKRHgbkfaZdfzF+E+NX3KquIeHW6JiBFUiIyCU0Sf2Cscdw==} - '@zag-js/collapsible@1.35.3': - resolution: {integrity: sha512-IweG8JOBCerJwLO6QzTZGEMlsYUmQfQSeD0jniFguMM8vcunvGVSrM+AaL8pDbmXd+snXokaGyJpGO3vzMW6Fw==} + '@zag-js/collection@1.41.2': + resolution: {integrity: sha512-ZZWuvfPZI8ccWd4aLpuU47k1jSc9eO+F3FM3iBJuvgegCH6g3+HDEwGN6wdePHnYfv7zyIKCGKr816zXcIWQbw==} - '@zag-js/collection@1.35.3': - resolution: {integrity: sha512-BYoWJ4b7ma2PgiuQbRSnP603f2DlK6se5JtViUHTamZScLLLWnWHuQ6zFa1KS5kiIkbb7CFM6/bJ3WNYLch8Ig==} + '@zag-js/color-picker@1.41.2': + resolution: {integrity: sha512-UynyJ/bTBeSlq6ziHr9GVrFycDjVxfLFIb8Aivu/XvihrAAvkhXUxwy+1ax+hj7peGlTY590xoQAvQixV+McBA==} - '@zag-js/color-picker@1.35.3': - resolution: {integrity: sha512-i9roSgtqeA1b4Q+jWqnxjXB//BQXMP5m1FQ4YcZVq/0yT14A53JIknchuqrh3wC3yPsJMXFqCoKg+NET2+OVig==} + '@zag-js/color-utils@1.41.2': + resolution: {integrity: sha512-Lsi5c2ztGZqud0oeDtAn3xFhgrYMaeaz1zi4p+mr0zXOuQNuZzfsrJ0stQ45s8L/xT8UJtGhYyEVy1+xjE4ARA==} - '@zag-js/color-utils@1.35.3': - resolution: {integrity: sha512-vxkEVgz4YdSbdaPvjiRI1VsJAdwzu/dUNvzqOaiVcPDrHr/FFgmUbv0SOFjnfSb2QWGI8EDEMn02RW9ym+BzGw==} + '@zag-js/combobox@1.41.2': + resolution: {integrity: sha512-V9jQteyQHs8ZNQx/FcA98P1NVZas/yjiW1V7s4L+h8MnRS3AK97+FAHAT83KCiZ34/vkpLF6ZEHI2zkcQpNXcg==} - '@zag-js/combobox@1.35.3': - resolution: {integrity: sha512-s1qmttTGJTMjlDakL+uvWSEggpafKr1vhOeZCh8j+N4eFt9bLAwaffjuh/1JzWBvzovw7WoMVkizdTXPlN8oYg==} + '@zag-js/core@1.41.2': + resolution: {integrity: sha512-xXTN3zKwOtMI4+5dG2cG+T1B4WR3X9alXiYaPJKaGd4N2eYRj9JEPte3Hv9gtFm+RM0b9VIwksHEg25rqE4apw==} - '@zag-js/core@1.35.3': - resolution: {integrity: sha512-fGAHyqOYSEFmo52t7wI4dvbFfLyJmUlyf7wknsiUlzUHlrn3yv5PAZYZ2TibpOD1hwXIp4AoCjbiIPPZBxirZw==} + '@zag-js/date-input@1.41.2': + resolution: {integrity: sha512-J8PdpEpM9TBxZBEE8/Nxi39LNJOZY7lilTbgcDABR5uiviZUk5++5GSdUTspcjFUIXx5SvqmdCk2RF7hsUEHVQ==} + peerDependencies: + '@internationalized/date': '>=3.0.0' - '@zag-js/date-picker@1.35.3': - resolution: {integrity: sha512-4G10h6pzzLbd84SE2CKtqi6Z9wEBhSyx4GRSxxy3tsf5wAxnz4anRFat9CGwn2YVUYcUJpD+umYgBMPt6zGDnA==} + '@zag-js/date-picker@1.41.2': + resolution: {integrity: sha512-j9LaznCV4QCfrq/y/mNAN9XgIRFFg+414TxGT4TK8mfWouIaFvxEoKdGP0l/LL4DFv1NRDaRdSBBcw3eXtMVnA==} peerDependencies: '@internationalized/date': '>=3.0.0' - '@zag-js/date-utils@1.35.3': - resolution: {integrity: sha512-1co0FPpZ6nO5dN8sZtECkMYaf+3E5zu0KSIJZpZiXb4TgsZMDyHu7K7IsiKFHk9qmhuF6AdPpNxBju91pSXMFg==} + '@zag-js/date-utils@1.41.2': + resolution: {integrity: sha512-jdcWLa5fYLTsvGWJkx4v/9Hzqf6UHdvJDeP6NxHpwoEmzYy7+AghYKBNSnRrJIBCQJgl1vM9OkpMvYrLNHr9jw==} peerDependencies: '@internationalized/date': '>=3.0.0' - '@zag-js/dialog@1.35.3': - resolution: {integrity: sha512-byosV+aBHH5LoFKnjEgC7WdqJid7bP9UhgWLSC7+IXbxrif9Czg1YVp6ZlQM6Nx6uD1vnty4touI3P7D7CTKcw==} + '@zag-js/dialog@1.41.2': + resolution: {integrity: sha512-t1N72snpFGiKj7cg2PivPdsy+X1YdgXPv7bzovpqjMLy0kN+gYTPoV1Iy/hQA+g021dz9XGgXzkDuU45sJqsFA==} - '@zag-js/dismissable@1.35.3': - resolution: {integrity: sha512-XPk+lqmsZp2Z1yMb5K1yj/e7Sobv4D7zK66B1GS97lk9Xzz8vuSgsimcLy0p7RXQl3KL6H5L69inSuQa2exybQ==} + '@zag-js/dismissable@1.41.2': + resolution: {integrity: sha512-hO/tFhRZ7S+LOOljGOQJIubbc3MXg41+iWR1yUXKl76cAenbxaCit1LZmUCwQPvRN0GndK6bDQo5ETjHZz/k7A==} - '@zag-js/dom-query@1.35.3': - resolution: {integrity: sha512-1RbFZoT4CjlHN9TUNse1++ZVOyKo45ktucTIT349o6HMsoWWKmTJDPvFkMBbmu/qY6XXn4dT+LJEp4bL3DR+Qw==} + '@zag-js/dom-query@1.41.2': + resolution: {integrity: sha512-+eBk1nlJA312mNmY/GSThLRwcCRqMIL+A1pLsWvTlQLQjmH1/UxoAuv6l2yvRCT33XmC8FBlBIKnXhOCpDvIZA==} - '@zag-js/drawer@1.35.3': - resolution: {integrity: sha512-DN5bwa7bDCDaUSbNzFxMc2U/WmbLcXvPSQjyOpKI6CC3VbW2kKaOnjJ5qQG+W5YBO0FpmJBtaxRV7lke4sZH2w==} + '@zag-js/drawer@1.41.2': + resolution: {integrity: sha512-aJql6L0cfHd1wXbemfLcNnjqTA/CbwVgQdWEVn5Qci6zhy4UJXPQeBBfxfgPgEOAbW60gL/gaaXG3d9Vx6+6oA==} - '@zag-js/editable@1.35.3': - resolution: {integrity: sha512-HcjeacS61vQXfNT9IalZj/+oS45yW5bIDO2NjJWV7zNe5AG29NCceUnvBhy+hrUKPnKcjfDocdW5rCL+Lvs/CQ==} + '@zag-js/editable@1.41.2': + resolution: {integrity: sha512-loTM1lrHBBqYfR8SJZrYayVdWHMpXCLVir+aDTQ8/d4bb/Gfl/L8CJNs3BRj3yt9zvLoWTLO+4LOY3hLyQSR2w==} - '@zag-js/file-upload@1.35.3': - resolution: {integrity: sha512-oIYwnDct4ERo2mfmcxsBIJnlmpzjrzYx82SQsXWD3NGKx3cgdh2lwBX+ebItaLH1jkgzBa3z0TWxc6rfvcUXbw==} + '@zag-js/file-upload@1.41.2': + resolution: {integrity: sha512-WFwIaKvHpCUjyYMvp42VoydT1WIP5DhDlpmG/nrF4i0ro7pLGb1A4dvyBrAfGcozCB88yR1y1iZKPDY1I9/uUw==} - '@zag-js/file-utils@1.35.3': - resolution: {integrity: sha512-Tb05RCzx4swc156hd4jLiO7z+Gxg/HQ+JCds03jgTbrFJAz2D56YaMeI7gSDc1m4Xre3nyqQpSo9AeX5nzbE/w==} + '@zag-js/file-utils@1.41.2': + resolution: {integrity: sha512-Ih+8ULbId0M+CFR4IsqG5y/0VLCk2l+1rgPH+21L40dlSB6z6qKSP2tG7W69Cj2/3vryZsn67ibn26iCPG/vOw==} - '@zag-js/floating-panel@1.35.3': - resolution: {integrity: sha512-nTZypcS0X46Oo1kpCQTnP5UlzjhypOAj3B4dq2z/3bAOC0TntYTnFkj8PbEJtExk7364xfMyxfgZOiv7Aqq01w==} + '@zag-js/floating-panel@1.41.2': + resolution: {integrity: sha512-nJP3oZ4YrJh+7H5YdwNccSzPGXFqjQN1ujZ/xGDhegjz4XtL48QMFnAasxlRI8VGjse9Tj8VXlQZxXPrASGzlA==} - '@zag-js/focus-trap@1.35.3': - resolution: {integrity: sha512-evErLlGFdDVCI8xipNS5k0rAvO+KFRA9g273bbfWAL1+mT54mcB/XHa85nC3QpPgMNrSh+6LUNq9fapyOGoyYg==} + '@zag-js/focus-trap@1.41.2': + resolution: {integrity: sha512-3QTtGUjFU2OLbyrDlyoYWvKZecCmtn/+bsfsHW159jJHiEGHVYK6CY8AI1ePsMk9gVay48bXh008j+lVli7gAw==} - '@zag-js/focus-visible@1.35.3': - resolution: {integrity: sha512-g4F8PRGIoFoKBrHiQ1HQh5AjCS7brFRXHvpbDNb9+T11FGlF5Turb+6OVRoNV8MmiuqMltO2I28l36YsGc//uQ==} + '@zag-js/focus-visible@1.41.2': + resolution: {integrity: sha512-oRjwtgafUdGVwLJUN6mKsnBQbez/CHYAPkPg1FxOnr5GFpEpr8oMTOZJ3wdPM2U1ynS9QnUUu/sXc3KQv/jX0Q==} - '@zag-js/highlight-word@1.35.3': - resolution: {integrity: sha512-K+mvEBbf3SUFjQeMeJQYb3cjri3x6sPaPhcKWayalelSLB/StWEGqcpmz+a6uUYrCUAK5kEi3Hn0YLGfn0GOig==} + '@zag-js/highlight-word@1.41.2': + resolution: {integrity: sha512-95zcZKqNrL7JlqAckfzHa+LRbnfoz1lj6skUhq/uHSnni1vH6+8fNWT8ruo9G7vpGopbyRmmcie5p41SbAwQjQ==} - '@zag-js/hover-card@1.35.3': - resolution: {integrity: sha512-xVoKOtvrnzhYzciZ1csgiV76IQ4DRtx1lsJeFSrfg5MH0kYWeC/pcmm3yCd2+Qh/45J7DbSXeZneqxpyiF5Vvw==} + '@zag-js/hover-card@1.41.2': + resolution: {integrity: sha512-Xn9RVzgTkKaVzyJTDdBJiXmCleNi1/hmW8z73tC0vOiQvSSvPejg/JkzqTOLFODvQHK3NOw54QHZvmjYp9Mubw==} - '@zag-js/i18n-utils@1.35.3': - resolution: {integrity: sha512-k7UcNxbnC2jvGwCoHYAkFD3ZaRSMQNVHfuy8TujZQ+ci3IJovwgWLveZoRfFbXHkTLfhmbpE2tFXBdpwOVZutg==} + '@zag-js/i18n-utils@1.41.2': + resolution: {integrity: sha512-f1xqaEY79awBxgUyjFso0UEpIoEHZq+zRvB0nUVFHJRW7Ds/QhaFHKSRnf2QBTlP/ObvCT225R+piNAAc17Aaw==} - '@zag-js/image-cropper@1.35.3': - resolution: {integrity: sha512-1PH6bg8JAQESHzNqjka2TJ0QGNBGBAO6rb7AZ+9CaCCLw0pIzbUJhqPMkwd9GhdWGKGP+e7wFitnjcT4W5Js8g==} + '@zag-js/image-cropper@1.41.2': + resolution: {integrity: sha512-750aT4U+J/TJw/Z1QVoLU9JG0luCtf9CyvShtJFIxeS+i25aUoBI9pOKgSFABsOutIqNJTPq4gYpqtuxFjSxRw==} - '@zag-js/interact-outside@1.35.3': - resolution: {integrity: sha512-tOcuo/IztzpU7UKXtjVrLZtXzzcbhP4n2WynKwDRkTkq3mRCp61xXJp1csIBycI3JHm/CMeAEcPdRIioxIT/Zw==} + '@zag-js/interact-outside@1.41.2': + resolution: {integrity: sha512-dM4Fn9iyqQeqkCMRYZP+bAgWEPKRVQRqMmcPsN0OXBhhFKC31Em15LTIZXaOtVKAjH+iwx+UvSYFRiWwEjkOEA==} - '@zag-js/json-tree-utils@1.35.3': - resolution: {integrity: sha512-nOv2dPJf+1mxsobYiSlYt96hR1MK7iHKG1iDLoO5wLggS6GQA3ix1BerHJK0zdehoEZ71R45el5ghCG1HB9VzQ==} + '@zag-js/json-tree-utils@1.41.2': + resolution: {integrity: sha512-gNaOzsbCwmTd2HM3/u0xQdWX5UDBfl8tCXFavzbamkFH0iYQOXJb7cqUXBVuI4KScIbHPCKwrzZjqA5Sg9qzAQ==} - '@zag-js/listbox@1.35.3': - resolution: {integrity: sha512-FE6FOuBr6aWtOb8U8oDvAvcUzD6JKLXAe8WngiLFG+b2yyW4nlaz2AcKRG1bjjB066UMxMo9/+2p4D0Kf5Id1Q==} + '@zag-js/listbox@1.41.2': + resolution: {integrity: sha512-iDGrZleP3ui2Q6Jgmr9RYlbd7njdJHs8Qb3IJrSIZBIeYyYmFvVUfAFjk0g/z/amjTx6uYxRASWSPy/RETd4ug==} - '@zag-js/live-region@1.35.3': - resolution: {integrity: sha512-64rWcfggYpyr2Fn4pdrB/lljMgm3quwn9is+vdDN85Vv3WShKWoz08T4njidm0hwcIbzas0bRqQYWDLLsAoSJQ==} + '@zag-js/live-region@1.41.2': + resolution: {integrity: sha512-7ubIW5AQt1wx9S/gFN+rU4TyvuFWJrL/DhnDWPNlH5g3luDVHSNeYGeeqf4d4tkcibtpYZa0pg9CbXxRxrfwVA==} - '@zag-js/marquee@1.35.3': - resolution: {integrity: sha512-bKZVpmAJWPDORP7WOWnS+65W5ZQBQmRs8zvV33ZfCpFbkXjhRiqKSzIj223/VOc2NEDjyWagz2vioAxrFYVzww==} + '@zag-js/marquee@1.41.2': + resolution: {integrity: sha512-cT77aMhrtAK3oe2O6+X3TLtQs8wupdPUtZgHMWVxCcQOwagrk7RUBEQwU3Cx7cTswpBdTKSuDYgUggfgCs96wg==} - '@zag-js/menu@1.35.3': - resolution: {integrity: sha512-KyY0EZXkIU57Mjt+Lg+pupiePk3LcnQcB3Gl05Vva61bNjBjdKV71qwCQru/OxPZEwYgPo46L7TDIb56kfK/VQ==} + '@zag-js/menu@1.41.2': + resolution: {integrity: sha512-wwix8hcAUSi0scpWXCiDppfdZV01Za8nN0gqLt9GdhCiVSlr0rs9pK1ROgPKJTyc43UZfyFPqtTWVHvEHMM70w==} - '@zag-js/navigation-menu@1.35.3': - resolution: {integrity: sha512-8cCHx0X/KjEpr2BaMOxJS5LiA6fs/CNqVTF/sTTgZAv7Dm+MH0yNuKm4kpPvcLaVeBpVE09bnyCHrNKzZes+Fw==} + '@zag-js/navigation-menu@1.41.2': + resolution: {integrity: sha512-aROB9CHzskZpnoFuGFkp7dbkZdsXvp2nxQgsgld02I1sDqiwcQd+YMdB0/6Ik0oz6X8I70RKdUuQM9WQFQfDnA==} - '@zag-js/number-input@1.35.3': - resolution: {integrity: sha512-uqawVybAcLcefVEHMVONuAA5kDSDPP5TsROr5PnAyFlhM1iD85+r3KAfCueoDX5w2X4ibbu9o2tdV6zTFKD/nQ==} + '@zag-js/number-input@1.41.2': + resolution: {integrity: sha512-QoQWCiVHO+ciUbq8uL8Kxhtk4o3UpwzYpJkfsOfitzsZoYpPc7V/A6+n5yABV2SOwpqBODwNASZdxiEa60kfow==} - '@zag-js/pagination@1.35.3': - resolution: {integrity: sha512-fKm4s5KAd12RiCI/EDmmGKjPQ+i2qS/UsJPdMe65yb/4mY5OibwV2zyHcVeFsOD4gBZpnU6kYlDAGSttmLWLlQ==} + '@zag-js/pagination@1.41.2': + resolution: {integrity: sha512-vZTxz4DrIDfedMcTjDeEkOc1iXD9wkP8eKuEcDieHOodnjSnNNwtmoFw5DCWv+yEa/TByIamXBZ8ZxHY144JgA==} - '@zag-js/password-input@1.35.3': - resolution: {integrity: sha512-etd0gm6ELAm3y+cFhPU+TYm8khm9cL5Mg5m2DcZxu1Mqpj7JY0LsXZ8SFOdCZgTIHuMEhKBiYfnuyMAd4CJztA==} + '@zag-js/password-input@1.41.2': + resolution: {integrity: sha512-OWKFl0S12Qnlf4R4WbMCJ/YU0kGfezm5tP0UiyubMO/Fixv6H0twDFaJSPg2F6POv5uomCcGubc1H7gO+fIhsQ==} - '@zag-js/pin-input@1.35.3': - resolution: {integrity: sha512-ZFt+WIHMdVlSg29BrQLFq5ijabiUO3tXMhoKhjjzTSe/tLqfNeu3UxFB6y/FYpn8+Cvn6xwvhu3lgnORYmI0zQ==} + '@zag-js/pin-input@1.41.2': + resolution: {integrity: sha512-Wrn3YDbmWL3qvUIzN4QyLO7PzEhunX7z8DwBpmrK04p7HxR9pniTLVIPk27xk2MzyAPYcl4mwd9/Mc88tBxHsg==} - '@zag-js/popover@1.35.3': - resolution: {integrity: sha512-+MIEENPsbKPxzoNuDI/C5d5ZN9uxnfZ+MBDc5C5XSgjjg9FcvMXClNq7IFM1aZi24peRXg9cMNf//lApVRT37w==} + '@zag-js/popover@1.41.2': + resolution: {integrity: sha512-h/LlVMIERM+NWzYV0ZHURlJuaqkT8XxwyEV96XfVzjknDRFNoPSl5IttVYtoaPoUqC0p/Y4oTSiee4mUZKOLHw==} - '@zag-js/popper@1.35.3': - resolution: {integrity: sha512-gpB7Xn9WtlfrUsIVbSgNQGDwgNOL/cSGt0Id3wEQKArmqVC704EWtPvXzOMMybBEdm8YW2hQrXuo+o66abI1Sg==} + '@zag-js/popper@1.41.2': + resolution: {integrity: sha512-Iz4D5YAIiIPn4IHGjhX3QatR/RyGaDt43lBSZv0RYcPQYtFg9sUuek3wizjW9qXgdvItevvNMqRdpl7f3es09g==} - '@zag-js/presence@1.35.3': - resolution: {integrity: sha512-ev5E7+U9IZAGvEaflpdVLHaZl8ZaQMhGB3ypd0yKhPwXeM51obV8w3+5HjzTqHPl8TKuoHWL31YaiUBd5EuS6w==} + '@zag-js/presence@1.41.2': + resolution: {integrity: sha512-OhOLPAf/DYPmgoEntrlrf3LOrkwA+Y0J3K03NXHXPnkRB7h8jyIbHqzHS0jRTb1pvsO2P/yowRyoYtptY2Zmog==} - '@zag-js/progress@1.35.3': - resolution: {integrity: sha512-u0GxQN1AfXMAgzYOUMxKQA12DyuAP0svh2S//KvOorTSv7d5hAa8nZXi2cEv5abYsyfKJ6/bc1Z56byzW1jVZw==} + '@zag-js/progress@1.41.2': + resolution: {integrity: sha512-SnzrqN+Z568NoO4rrgjrIc/S4EXMEne5CDgWwt2kQ8yq9VysdH8TtHAjyciFRIio7cdgEZNHKw9jSccpMWgRwA==} - '@zag-js/qr-code@1.35.3': - resolution: {integrity: sha512-t0Ehwogr49vTNtWyNdQU2tYex7uJyfAn7N/5LgD7FXw8aa+RBMWZWlqjCUvHqJ929tVMrn+LIrQnZCcwNunalA==} + '@zag-js/qr-code@1.41.2': + resolution: {integrity: sha512-+JLswCNnzf58aQTaX0SMUA9wRC8Hb/a/ZveJIXTz6853Siemay2HqOqB2WQIeF33HNldUFD/a4+4Q8ugg93ubA==} - '@zag-js/radio-group@1.35.3': - resolution: {integrity: sha512-kOzocjqWk3dXuRfyfsHwfw63Z99NHbc7rvVUutSsfXANXi+DFYZHuqdPUwMt+29LfaL15XTOfuGV+yUXDCgQHQ==} + '@zag-js/radio-group@1.41.2': + resolution: {integrity: sha512-EZjos61jKHZlNw8ez80vG2T9gUwpooxcVpYOKS2hyhuEXn3wEoefS5v1WFbmpoA/8TUpUQnYxisAeNuQfEQCuQ==} - '@zag-js/rating-group@1.35.3': - resolution: {integrity: sha512-BmhJZdbaTnd3nFWMY+nR+HF952UhWXfaXXxiBWptSLMBfAYImQTWBMrLgTHCSnVfmFATj4Gb7xQe79FQU8T5fA==} + '@zag-js/rating-group@1.41.2': + resolution: {integrity: sha512-SbJP4HiK5XRy/oC3xRowjZOCThq1n/QA2Z/XAkvKLJArVQCYjrH3MoWwWvMVNfNC5+ZJluborR2AGF7tlVLzxA==} - '@zag-js/react@1.35.3': - resolution: {integrity: sha512-x2PxYUCQ6OgOpUdmSkG5tbL9JWVqYRh42r4V2UeAdMh0MRwjAJtxjvAy50DZ8Sfia5o4UGdZMXJyDY2O7Pdhyw==} + '@zag-js/react@1.41.2': + resolution: {integrity: sha512-5Bx7mQAron4LFWI8Hhs/uw5kwQ19s2Tn30HhctozLqmCu4nnJSTSh7GRvX+uwRZnztGXBXoOrgBWIepU4RXFGg==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' - '@zag-js/rect-utils@1.35.3': - resolution: {integrity: sha512-mt/oD3RXdyaX6ZPSd8BO13vvPBJ7QpVWieubE3O0WM3OPhU7ykDMRp/tR7cYMQrzUm04GlY9pbkmSSw2uABxlA==} + '@zag-js/rect-utils@1.41.2': + resolution: {integrity: sha512-GWBTamaMLMG1p7Fe6V0dsXeTEmk+tqG3ciovzmjxURCJ3Yq2EkAMRhS0v5DG0oo+PyrPEIzEWukGBQkh/XRgYQ==} - '@zag-js/remove-scroll@1.35.3': - resolution: {integrity: sha512-e59z9SbEpPiw0qwNQa2cB5/h30ZCLREaHsCw1TKTANFhwg7v85k9Lq1H/G/49li1CAjmiaOU9BNGlDvbzpNETQ==} + '@zag-js/remove-scroll@1.41.2': + resolution: {integrity: sha512-ieIrOgPKlCikAGEBIboQJoU7oxrL5BEY670tDOu7Eg7rNOdAwGXLEKPX2A/q+lREhOiVYjx0D3//vHTvdte80Q==} - '@zag-js/scroll-area@1.35.3': - resolution: {integrity: sha512-IQwdUws/AckRIHK1z/wHdHurnOeGd8h8Dmspfh3VT7NkwTnxeJ4SW9di9smuD+d25eXkJRuX5zGEDHAyx2IaPQ==} + '@zag-js/scroll-area@1.41.2': + resolution: {integrity: sha512-hJFAwfIFuS7XmNsS3nB5rPm9OWXfB4d98sID7fjurcaZtDH5LqFriqfXhceNvs7rz7K4f/u8rufXrb6tcvATIA==} - '@zag-js/scroll-snap@1.35.3': - resolution: {integrity: sha512-NVa2yRm2DQnF6hTV9k7Xz7l8YCZBagZTiqSwNvWKUulKD1csjt2fpBxvUt2cK+1iQnLOey2ydhs7MMsAnXPbJA==} + '@zag-js/scroll-snap@1.41.2': + resolution: {integrity: sha512-+70Al6LSASyEZtFyyffUJlDbE88KgYJDud05z8oZTqyEOLlTqnlSNkXq/P3siO7r3sNykg9H+TmAKn+/dVSKuw==} - '@zag-js/select@1.35.3': - resolution: {integrity: sha512-ztszGHWvlbBDE0YT5LYPH+sMd6VH1ct5pH/M9VSzIUO6C5PARkW0NwSVQ1rCQJMj4sfvSE1gC1/r7urRzqEcUQ==} + '@zag-js/select@1.41.2': + resolution: {integrity: sha512-3wGaKABILexoNBJ1bJiHqLLTctR/VMZaNA4cyKiqZeBEWtAkdMhgyY2xKobrP6KtUTqAeUFNVSTu4yCDrAQnUw==} - '@zag-js/signature-pad@1.35.3': - resolution: {integrity: sha512-jvtxxzAQ8fre11zWUh6HflG4Ycr5z83Wba4pONRJbUE/vNgkJQ7yJgfyUl1QTlkn8Arfg2Zwoxu9GIq80HLZWg==} + '@zag-js/signature-pad@1.41.2': + resolution: {integrity: sha512-iNrOxY4gtqhsZdXYvlhF7s+LiOvwV7/kBpNnq8tJ1oYhgTs8wvKtJHrP86/CR05irEXQTaLfmeAJZuBEys9iRA==} - '@zag-js/slider@1.35.3': - resolution: {integrity: sha512-Th142JO4Fqla5AWhGrTW6CQicwvTw87PdVpur/WotQ7brlZIww5HipzEMh5eQJSWfwpKD4PI2bYK9V/ZE/mpXA==} + '@zag-js/slider@1.41.2': + resolution: {integrity: sha512-mKK2BwoDbIGxAdkdKkPZJA1SHtEQt3lS9hJ6WghefYU2vyd0BXoIKvcDV3xJOzly5LXYhH5cJITn6JtGK8353A==} - '@zag-js/splitter@1.35.3': - resolution: {integrity: sha512-IsIbRwzjr5amGANEDsZDSToaSn8wHUWvS2l0XHmf3BiiguVApaZgQTlfqthVQC9hBHMOaGIXIW1CFUOrQYkvUQ==} + '@zag-js/splitter@1.41.2': + resolution: {integrity: sha512-Ubp4hkmzvVysU31jCINYbBXVqruu7rEPGqugWMzeXC5Hwda648aHpbg4Jix/wRtaGLjsyh6KOVEwAmoJU9NwhQ==} - '@zag-js/steps@1.35.3': - resolution: {integrity: sha512-TYIrqV+v9/ULhvrTRBtQFFvJQPPTWOmjFXxlIxDwozek5R4dCIyeUYt1/ChJEc2mNETocbfDVSTxRO1dwCFpwQ==} + '@zag-js/steps@1.41.2': + resolution: {integrity: sha512-m0t2r8+FWwa2b2aU5JiNrHVdYHyNZYHK0G3Tq9lCOSQoDeoJIkyta+sIVehLVSY+0Ba9kOlkRUmYLbsnfXaW+Q==} - '@zag-js/store@1.35.3': - resolution: {integrity: sha512-7kEV4T/20DU36UIfVMzuDlLhWSSEy/vabmpiB700tcdD9BBBODTiSg3ZeljW17dQbvE545vZOFEjVf/cQ5LVGA==} + '@zag-js/store@1.41.2': + resolution: {integrity: sha512-dVZF7E1ezXzynrKhMH3rfSr2rBbCfvTjvXbXz7//1PNULuq58UU5dG93V+9l834npCZxI2+PrpY45wZLJPTsIA==} - '@zag-js/switch@1.35.3': - resolution: {integrity: sha512-EP/2cJ46sd+6C5x5+89jn/9NOpM05CRESYB4RMhOnTe/WFtcS4IpiYtVHFhikdXkvJoibm67O2EHep2Pm/Xj4w==} + '@zag-js/switch@1.41.2': + resolution: {integrity: sha512-qHbQK95UUHN0tj+bf9LLphLcMo/uTg2Pvs0c1Gs03Zh4g3NtHf0uYIhMZKYlCH0hNVlKrmdzLKWgeoDxv9gySw==} - '@zag-js/tabs@1.35.3': - resolution: {integrity: sha512-lZKlDmxE25miCikj9QZCCnL02SVV2K14KZy5bn7+XDgrWlfSNTpNTj8r5E3zGlSgio5pkTGou57ASqS7WaPDWg==} + '@zag-js/tabs@1.41.2': + resolution: {integrity: sha512-7YVj2mCcxRbn1wMXP9anaTOVf+J0fa5uaPScr8e4+e2xc+/1WKzqN6V8IDeKS5wV/xzi1r3Ny307sX7Xz4ZJVQ==} - '@zag-js/tags-input@1.35.3': - resolution: {integrity: sha512-HqyoQ3DZFhByOGnDShFfxi6u0bIf7aSVTlwmAvcL+b2ZhyU6/wIMGc4WJE7BMx1NYWM/jNLHedvGExAI8R0kXQ==} + '@zag-js/tags-input@1.41.2': + resolution: {integrity: sha512-aIPEndSO+9LHxyoXLUr0Uttxw2cYMyDuii5w50wn/N7lFJD49U3Sj+6XaB/oJSbDAwn10WrsRDtb7Gs2kmU+Qw==} - '@zag-js/timer@1.35.3': - resolution: {integrity: sha512-edmgitbRgsq+msxvVB4wc17Q5d5k63zMWaLJnWjUdDGAgEtM6/HNxwGb3riv46S2U3RgYxaaHTNZ/M7EE5mvYw==} + '@zag-js/timer@1.41.2': + resolution: {integrity: sha512-PRYLWaip0+1FeVGEMNk5wMGAAIYgBIWwulZ4U5I+2Ayjohzp2NUAfwJ3sqoYvRrfjNYUNAPdU4eGu1zetC+oVQ==} - '@zag-js/toast@1.35.3': - resolution: {integrity: sha512-whlR791GHdnMD21nNPsl2Dbql8+qu1wBZl75QzwYrjR8FlKjp8bhr3gXKzQEddcBXe9GPEFGvUs4iCyXsuTbpg==} + '@zag-js/toast@1.41.2': + resolution: {integrity: sha512-+F3PsAo6EIz4rh73IOMCb/+FOUp7e3VjUY2q5sdU4IbfOzJBIbVSJxn0PQmHkuxkzWdCom0Lv0qSPFg/UTplnQ==} - '@zag-js/toggle-group@1.35.3': - resolution: {integrity: sha512-Gn6JHzkQ4tlttjZcE0ZjIdxYkFeVp9VHrcMVizjJTkGZRmQ+kPZ5G/wOsZhIrvLX3Dw6Y0NkuBcP+jDHz/o3TA==} + '@zag-js/toggle-group@1.41.2': + resolution: {integrity: sha512-C6wn3A89h24hTs0BN9ryEuKatfR493u7QqxS06TeK9oI/KZBvm5Rwm8FPHSUJvsUTkAkow4PsXC0Ra19duzEdQ==} - '@zag-js/toggle@1.35.3': - resolution: {integrity: sha512-aFfHKuR4sKzglhkmWLA+0RTNPs9dfeqwtc96qljawGYfAYWJXkEPYK9dFfVa+arZ7L84xBi24QSLiTg7LGSFLw==} + '@zag-js/toggle@1.41.2': + resolution: {integrity: sha512-EFB9pb3pEtwXt7RSivVLWXV64dKUF8gsn75tt8TbYBgfy+zW85MsRLu8U48TXZN5teQWAKKNujr9bxQsW/CWvQ==} - '@zag-js/tooltip@1.35.3': - resolution: {integrity: sha512-/pImDGYl79MfLdvEphj3rSvNdj2tLW4GwGEncgdLM/GKwQiEUjfi/9EJOfLYP23M4lOOnoW7orehJ9xeaXOAkA==} + '@zag-js/tooltip@1.41.2': + resolution: {integrity: sha512-68okWJCFXfW8r0h97kEcU2yKPkq6e0S6QkiYh09ifMXoYjrQw/shPol8PgrS1poqKJigUWtsKm+bw73abhMn3w==} - '@zag-js/tour@1.35.3': - resolution: {integrity: sha512-DI2aCXmZaE9KcPZDs9itc2BO7ixLApJ/yVRfM69pXwVOrucdSeDDNPFkfbhj5XwB+9VjjZEkqWFHKntRIyPl5g==} + '@zag-js/tour@1.41.2': + resolution: {integrity: sha512-Q7UsvuHYYBo1Cs4b4OS0e/D8lxd2GpSRII93s5BQPi5HTcBjaWhVysAykmCFbat6Z56z0NBmFHNdhZ8oVPls1A==} - '@zag-js/tree-view@1.35.3': - resolution: {integrity: sha512-DbHaLxSNa1goE3o3IsXxEdzp8P5dvmkk1rVWgNUUIhpA+44idEjSSNXJkHPl18Mk5blqSMVjK1EX91oqai01Vw==} + '@zag-js/tree-view@1.41.2': + resolution: {integrity: sha512-QNi0VpV+RyzF4NP72+kSleUpauF9SMAzOAe59nxvs8jAUHqV5diDCInnbQos4+cyFDXFzGq3lElot26A1yI+7Q==} - '@zag-js/types@1.35.3': - resolution: {integrity: sha512-Fnm3AMs1lfb55hlkip/eJeWHOjFB3gSi1JkZlkkdltG2l7y/zsHkumPSe6jIKy+DRRIFKRCyXVTatbPN27bO3w==} + '@zag-js/types@1.41.2': + resolution: {integrity: sha512-L6CNvK06lIVpy0X8eG3kbDIx8Uuv+3KHElxXYSzRXSJ7/OLCv1sTRgEvnxNtdIWOrksGgxF4JtT7PXtoClGqNQ==} - '@zag-js/utils@1.35.3': - resolution: {integrity: sha512-LHcC+9y6TFhDsIz9I3koYxONl2JFfx5yQDzc6ZEQO2cqzXedRcN0R9IPqNGCX7JuhGt14ctDkVCm1JWGP2J6Wg==} + '@zag-js/utils@1.41.2': + resolution: {integrity: sha512-Yj8FSrR7vGA6ahUhjrThfHAF+PM2Y1Yv2lkXkqZZd60mPBhixcot1+SHOfEMV63JimQcWrmQ8QbeYYMmF+ZpLQ==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1606,13 +1582,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1686,11 +1657,15 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@1.0.0: - resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==} + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -1711,8 +1686,8 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios@1.16.1: - resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -1740,6 +1715,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + baseline-browser-mapping@2.11.4: + resolution: {integrity: sha512-s4+sLr9mZ/CyqeRritFeYV/Zx73OAtmaHn6kkBS1XRoJn1hrg3xIDUcpicAEX68tkcIN0iBCgti31C8zxtkhsQ==} + engines: {node: '>=6.0.0'} + hasBin: true + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1747,8 +1727,11 @@ packages: brace-expansion@1.1.13: resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + brace-expansion@2.1.4: + resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -1760,6 +1743,15 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.28.7: + resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-image-size@0.6.4: + resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==} + engines: {node: '>=4.0'} + builtin-modules@5.1.0: resolution: {integrity: sha512-c5JxaDrzwRjq3WyJkI1AGR5xy6Gr6udlt7sQPbl09+3ckB+Zo2qqQ2KhCTBr7Q8dHB43bENGYEk4xddrFH/b7A==} engines: {node: '>=18.20'} @@ -1795,6 +1787,9 @@ packages: caniuse-lite@1.0.30001790: resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} + caniuse-lite@1.0.30001806: + resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1802,8 +1797,8 @@ packages: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} - chakra-react-select@6.1.1: - resolution: {integrity: sha512-ztKr8VIXtDsRDB3exXmAdBf2JG2yWMUsxyUDMH9mIVaNFo+hBIq1RMbKYu212MeYnLaoYHMekzgQeoZupfP4kQ==} + chakra-react-select@6.1.3: + resolution: {integrity: sha512-U02sJqqM4rEBdzje1IXUY3Of6W+u6r+hln+a1+hOhKsj9KWGwJOb6Yxlpdblsgp+K52WAoKW8PkrJIcm2p82dw==} peerDependencies: '@chakra-ui/react': 3.x next-themes: 0.x @@ -1819,21 +1814,12 @@ packages: character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} @@ -1874,10 +1860,6 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} - clean-regexp@1.0.0: - resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} - engines: {node: '>=4'} - cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -1900,9 +1882,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - comma-separated-tokens@1.0.8: - resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} - comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -1924,6 +1903,10 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -1941,9 +1924,6 @@ packages: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1994,8 +1974,9 @@ packages: resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} engines: {node: '>=12'} - d3-path@1.0.9: - resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} d3-scale@4.0.2: resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} @@ -2005,8 +1986,9 @@ packages: resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} engines: {node: '>=12'} - d3-shape@1.3.7: - resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} d3-time-format@4.1.0: resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} @@ -2045,8 +2027,8 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + dayjs@1.11.21: + resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -2088,6 +2070,10 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -2112,6 +2098,9 @@ packages: dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dompurify@3.2.7: + resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -2123,6 +2112,9 @@ packages: electron-to-chromium@1.5.344: resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} + electron-to-chromium@1.5.396: + resolution: {integrity: sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==} + elkjs@0.11.1: resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==} @@ -2132,6 +2124,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} @@ -2155,8 +2151,8 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-module-lexer@2.3.0: + resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -2181,10 +2177,6 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -2210,12 +2202,12 @@ packages: '@eslint/json': optional: true - eslint-plugin-i18next@6.1.4: - resolution: {integrity: sha512-BekXQu1VaVFkREepQGsntBYoKuPsf89V16n/s2xpKMtsw0/lDseds1wBhj3RtO1dKnHsfTPaG+xul1vF0R7LEQ==} + eslint-plugin-i18next@6.1.5: + resolution: {integrity: sha512-xCTfstbK9ZpQ6UFT5S1s6zbZMhKn2o2jRSQYiU2UkV7wt8y1m3WjkUYGkGlipgRdFInYI9+LAqE+JQU/L73HmA==} engines: {node: '>=18.10.0'} - eslint-plugin-jsonc@3.1.2: - resolution: {integrity: sha512-dopTxdB22iuOkgKyJCupEC5IYBItUT4J/teq1H5ddUObcaYhOURxtJElZczdcYnnKCghNU/vccuyPkliy2Wxsg==} + eslint-plugin-jsonc@3.3.0: + resolution: {integrity: sha512-CsTR8aDcShDg6A71ZppLaWiPoSo2J1Ivjm5/c4Mnb9sxgwWq+WG2PgeoAnj7SwzDPJB75tlHvLrGy6ntooIitg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: '>=9.38.0' @@ -2226,14 +2218,14 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-perfectionist@5.9.0: - resolution: {integrity: sha512-8TWzg02zmnBdZwCkWLi8jhzqXI+fE7Z/RwV8SL6xD45tJ8Bp3wGuYL2XtQgfe/Wd0eBqOUX+s6ey73IyszvKTA==} + eslint-plugin-perfectionist@5.10.0: + resolution: {integrity: sha512-HiqpDrUDbGrMC6iHQbemgDyHJ0366Vyz/qRWmxQcSAkmG25cXr8BdRgx8yAhOKhEfBXn8Rnf/mTCsV4EqUJSxg==} engines: {node: ^20.0.0 || >=22.0.0} peerDependencies: eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 - eslint-plugin-prettier@5.5.5: - resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==} + eslint-plugin-prettier@5.5.6: + resolution: {integrity: sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -2252,8 +2244,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 - eslint-plugin-react-refresh@0.5.2: - resolution: {integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==} + eslint-plugin-react-refresh@0.5.3: + resolution: {integrity: sha512-5EMmLCV98Pi4o/f/3DP/v/tNqLHMIc9I8LKClNDWhZ9JTho89/kQcitCXQBMG7sAfVRK0Ie3T2EDOzp1YXYiVA==} peerDependencies: eslint: ^9 || ^10 @@ -2263,11 +2255,11 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-unicorn@64.0.0: - resolution: {integrity: sha512-rNZwalHh8i0UfPlhNwg5BTUO1CMdKNmjqe+TgzOTZnpKoi8VBgsW7u9qCHIdpxEzZ1uwrJrPF0uRb7l//K38gA==} - engines: {node: ^20.10.0 || >=21.0.0} + eslint-plugin-unicorn@72.0.0: + resolution: {integrity: sha512-hqO6ksoOHO+ZhdseTuKRVQbx9U7PRO/cv8qAR1mctwzdVO2hYud8uS9luAhp43RJgziYgHAph8eHyipT8GL0ng==} + engines: {node: '>=22'} peerDependencies: - eslint: '>=9.38.0' + eslint: '>=10.4' eslint-scope@9.1.2: resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} @@ -2285,8 +2277,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.3.0: - resolution: {integrity: sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==} + eslint@10.8.0: + resolution: {integrity: sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -2303,10 +2295,6 @@ packages: resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -2334,8 +2322,8 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} extend@3.0.2: @@ -2353,6 +2341,15 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + fault@1.0.4: resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} @@ -2408,8 +2405,8 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} format@0.2.2: @@ -2429,6 +2426,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} + function.prototype.name@1.1.8: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} @@ -2474,16 +2475,8 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globals@17.5.0: - resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} + globals@17.8.0: + resolution: {integrity: sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==} engines: {node: '>=18'} globalthis@1.0.4: @@ -2494,8 +2487,8 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} - graphql@16.13.1: - resolution: {integrity: sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==} + graphql@16.14.2: + resolution: {integrity: sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} handlebars@4.7.9: @@ -2503,8 +2496,8 @@ packages: engines: {node: '>=0.4.7'} hasBin: true - happy-dom@20.8.9: - resolution: {integrity: sha512-Tz23LR9T9jOGVZm2x1EPdXqwA37G/owYMxRwU0E4miurAtFsPMQ1d2Jc2okUaSjZqAFz2oEn3FLXC5a0a+siyA==} + happy-dom@20.11.1: + resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -2534,12 +2527,12 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} - hast-util-parse-selector@2.2.5: - resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} @@ -2547,11 +2540,11 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - hastscript@6.0.0: - resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + headers-polyfill@5.0.1: + resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} hermes-estree@0.25.1: resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} @@ -2571,8 +2564,8 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - html-parse-stringify@3.0.1: - resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + html-parse-stringify@4.0.1: + resolution: {integrity: sha512-0zHsZJrK7S3K2aucXWL6ycoYJ/iNtIcFHC/nYQgFklPtrv5LpJctIiSCroWZWeuoXvuyFdzp6KzjJQ+OT5MfFw==} html-to-image@1.11.13: resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==} @@ -2587,23 +2580,28 @@ packages: i18next-browser-languagedetector@8.2.1: resolution: {integrity: sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==} - i18next-http-backend@3.0.5: - resolution: {integrity: sha512-QaWHnsxieEDcqKe+vo/RFqpiIFRi/KBqlOSPcUlvinBaISCeiTRCbtrazHAjtHtsLC66oDsROAH8frWkQzfMMQ==} + i18next-http-backend@4.0.1: + resolution: {integrity: sha512-O+7MwPCJIKCu68vho8JtD1HF8QHyMPzoChIDFfYCrpaDqX6oq3RqASujnpKEdnNCEOb+kLMOHTNTcGKpj7B1BA==} + engines: {node: '>=18'} - i18next@25.8.16: - resolution: {integrity: sha512-/4Xvgm8RiJNcB+sZwplylrFNJ27DVvubGX7y6uXn7hh7aSvbmXVSRIyIGx08fEn05SYwaSYWt753mIpJuPKo+Q==} + i18next@26.3.6: + resolution: {integrity: sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==} peerDependencies: - typescript: ^5 + typescript: ^5 || ^6 || ^7 peerDependenciesMeta: typescript: optional: true + identifier-regex@1.1.0: + resolution: {integrity: sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==} + engines: {node: '>=18'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} import-fresh@3.3.1: @@ -2633,15 +2631,9 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} - is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} @@ -2688,9 +2680,6 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} - is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -2714,12 +2703,13 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-identifier@1.1.0: + resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} + engines: {node: '>=18'} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -2825,11 +2815,6 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2852,10 +2837,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-eslint-parser@2.4.1: - resolution: {integrity: sha512-uuPNLJkKN8NXAlZlQ6kmUF9qO+T6Kyd7oV4+/7yy8Jz6+MZNyhPq8EdLpdfnPVzUC8qSf1b4j1azKaGnFsjmsw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - jsonc-eslint-parser@3.1.0: resolution: {integrity: sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -2882,78 +2863,74 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: @@ -2963,6 +2940,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -2979,8 +2959,8 @@ packages: lowlight@1.20.0: resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} - lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -2996,8 +2976,12 @@ packages: magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - magicast@0.5.2: - resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + + make-asynchronous@1.1.0: + resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} + engines: {node: '>=18'} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -3006,6 +2990,11 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked@14.0.0: + resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} + engines: {node: '>= 18'} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -3055,6 +3044,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdn-data@2.29.0: + resolution: {integrity: sha512-pVxQFCcaYUEAH853+v7yoI/qzhxXSq1bTb9obMYGYAN1c3Hen+XDCEvr296XhstrwlSTNgOR7mCSD4JPjbJe5A==} + memoize-one@6.0.0: resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} @@ -3161,6 +3153,10 @@ packages: minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -3175,14 +3171,14 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - monaco-editor@0.52.2: - resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==} + monaco-editor@0.55.1: + resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.12.10: - resolution: {integrity: sha512-G3VUymSE0/iegFnuipujpwyTM2GuZAKXNeerUSrG2+Eg391wW63xFs5ixWsK9MWzr1AGoSkYGmyAzNgbR3+urw==} + msw@2.15.0: + resolution: {integrity: sha512-2wQAmKkQKxRuXvYJxVhPGG0wZNBQyD06oJvxqw90XqLvptdqxdlHrFUfEteKkpaNORX3Xzc+HtEl/q0nfmN2wQ==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -3191,12 +3187,12 @@ packages: typescript: optional: true - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -3231,6 +3227,10 @@ packages: node-releases@2.0.38: resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + node-releases@2.0.51: + resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} + engines: {node: '>=18'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3268,8 +3268,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} ohash@1.1.6: resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==} @@ -3292,6 +3293,10 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -3300,6 +3305,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -3307,16 +3316,19 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-imports-exports@0.2.4: + resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-statements@1.0.11: + resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -3361,17 +3373,21 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - playwright-core@1.60.0: - resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} - engines: {node: '>=18'} + playwright-core@1.62.1: + resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==} + engines: {node: '>=20'} hasBin: true - playwright@1.60.0: - resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} - engines: {node: '>=18'} + playwright@1.62.1: + resolution: {integrity: sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==} + engines: {node: '>=20'} hasBin: true pluralize@8.0.0: @@ -3382,8 +3398,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.25: + resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -3394,8 +3410,8 @@ packages: resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} engines: {node: '>=6.0.0'} - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + prettier@3.9.6: + resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} engines: {node: '>=14'} hasBin: true @@ -3410,9 +3426,6 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-information@5.6.0: - resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} - property-information@7.0.0: resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} @@ -3430,6 +3443,10 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quote-js-string@0.1.0: + resolution: {integrity: sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==} + engines: {node: '>=22'} + rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} @@ -3439,31 +3456,31 @@ packages: chart.js: ^4.1.1 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom@19.2.6: - resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} peerDependencies: - react: ^19.2.6 + react: ^19.2.7 - react-hook-form@7.71.2: - resolution: {integrity: sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==} + react-hook-form@7.83.0: + resolution: {integrity: sha512-AXt8cMCmx5a7u4uvpb2uRFVrWQhllI4pV+LSykxIac/hjt44TnQkmX9BKuQi2i+LDC62esmiLpilkav+kjVf/A==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-hotkeys-hook@4.6.1: - resolution: {integrity: sha512-XlZpbKUj9tkfgPgT9gA+1p7Ey6vFIZHttUjPqpTdyT5nqQ8mHL7elxvSbaC+dpSiHUSmr21Ya1mDxBZG3aje4Q==} + react-hotkeys-hook@4.6.2: + resolution: {integrity: sha512-FmP+ZriY3EG59Ug/lxNfrObCnW9xQShgk7Nb83+CkpfkcCpfS95ydv+E9JuXA5cp8KtskU7LGlIARpkc92X22Q==} peerDependencies: react: '>=16.8.1' react-dom: '>=16.8.1' - react-i18next@16.6.5: - resolution: {integrity: sha512-bfdJhmyjQCXtU9CLcGMn3a1V5/jTeUX/x29cOhlS1Lolm/epRtm24gnYsltxArsc29ow3klSJEijjfYXc5kxjg==} + react-i18next@17.0.11: + resolution: {integrity: sha512-cDtkXgxjuFTWUH6V+aQn1Ve5vDiUztCNPWW5GtSHDccsgRXO1nE6QFWCEmc1KAutrb3OUv87wFShJL5RhUwPXg==} peerDependencies: - i18next: '>= 25.6.2' + i18next: '>= 26.2.0' react: '>= 16.8.0' react-dom: '*' react-native: '*' - typescript: ^5 || ^6 + typescript: ^5 || ^6 || ^7 peerDependenciesMeta: react-dom: optional: true @@ -3472,8 +3489,8 @@ packages: typescript: optional: true - react-icons@5.6.0: - resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==} + react-icons@5.7.0: + resolution: {integrity: sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw==} peerDependencies: react: '*' @@ -3489,8 +3506,8 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-markdown@9.1.0: - resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==} + react-markdown@10.1.0: + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} peerDependencies: '@types/react': '>=18' react: '>=18' @@ -3501,15 +3518,15 @@ packages: react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-router-dom@7.13.1: - resolution: {integrity: sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==} + react-router-dom@7.18.1: + resolution: {integrity: sha512-KaZh+X/6UtEp28x51AUYZDMg9NGoz2ja3dNHa+ta/tk40vCzKhQ/RypCWBMLbmDr6//E24Vv5uPsrqXFozdkAg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' react-dom: '>=18' - react-router@7.16.0: - resolution: {integrity: sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==} + react-router@7.18.1: + resolution: {integrity: sha512-GDLgg3i3uM0aeJO3Fm+TCS+sDQ7gu12T6x0qdTEzcwqEfleci7JwugVNIF3U//0FWKnJT7ptG+20B2jfDqnZAg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -3518,14 +3535,15 @@ packages: react-dom: optional: true - react-select@5.10.1: - resolution: {integrity: sha512-roPEZUL4aRZDx6DcsD+ZNreVl+fM8VsKn0Wtex1v4IazH60ILp5xhdlp464IsEAlJdXeD+BhDAFsBVMfvLQueA==} + react-select@5.10.2: + resolution: {integrity: sha512-Z33nHdEFWq9tfnfVXaiM12rbJmk+QjFEztWLtmXqQhz6Al4UZZ9xc0wiatmGtUOCCnHN0WizL3tCMYRENX4rVQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-syntax-highlighter@15.6.1: - resolution: {integrity: sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==} + react-syntax-highlighter@16.1.1: + resolution: {integrity: sha512-PjVawBGy80C6YbC5DDZJeUjBmC7skaoEUdvfFQediQHgCL7aKyVHe57SaJGfQsloGDac+gCpTfRdtxzWWKmCXA==} + engines: {node: '>= 16.20.2'} peerDependencies: react: '>= 0.14.0' @@ -3535,8 +3553,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@19.2.6: - resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} readdirp@3.6.0: @@ -3551,22 +3569,18 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - refractor@3.6.0: - resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + refractor@5.0.0: + resolution: {integrity: sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw==} regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regjsparser@0.13.1: - resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + regjsparser@0.13.2: + resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} hasBin: true remark-gfm@4.0.1: @@ -3589,6 +3603,10 @@ packages: resolution: {integrity: sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==} engines: {node: '>=0.10.5'} + reserved-identifiers@1.2.0: + resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} + engines: {node: '>=18'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -3602,14 +3620,14 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true - rettime@0.10.1: - resolution: {integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==} + rettime@0.11.11: + resolution: {integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==} robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + rolldown@1.2.1: + resolution: {integrity: sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -3632,29 +3650,17 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + set-cookie-parser@3.1.2: + resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3710,9 +3716,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - space-separated-tokens@1.1.5: - resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} - space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -3729,8 +3732,8 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@4.0.0: - resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -3786,6 +3789,10 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3794,8 +3801,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - synckit@0.11.12: - resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} + synckit@0.11.13: + resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} engines: {node: ^14.18.0 || >=16.0.0} tagged-tag@1.0.0: @@ -3806,20 +3813,20 @@ packages: resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==} engines: {node: '>=18'} + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.1.1: - resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -3828,23 +3835,19 @@ packages: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} - tldts-core@7.0.25: - resolution: {integrity: sha512-ZjCZK0rppSBu7rjHYDYsEaMOIbbT+nWF57hKkv4IUmZWBNrBWBOjIElc0mKRgLM8bm7x/BBlof6t2gi/Oq/Asw==} + tldts-core@7.4.9: + resolution: {integrity: sha512-DxKfPBI52p2msTEu7MPhdpdDTBhhVQg1a/8PjQckeyAvO13eMYElX545grIp6nnTGIMZlRvFZPvFhvI/WIz2Vg==} - tldts@7.0.25: - resolution: {integrity: sha512-keinCnPbwXEUG3ilrWQZU+CqcTTzHq9m2HhoUP2l7Xmi8l1LuijAXLpAJ5zRW+ifKTNscs4NdCkfkDCBYm352w==} + tldts@7.4.9: + resolution: {integrity: sha512-3kZ8wQQ/k5DrChD4X4FVvr2D7E5uoRgAqkPyLpSCGUvqOvqu+JEdr3mwMUaVWb+vMHZaKhF5fp2PBigKsui7hA==} hasBin: true - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tough-cookie@6.0.0: - resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + tough-cookie@6.0.2: + resolution: {integrity: sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==} engines: {node: '>=16'} tr46@0.0.3: @@ -3875,8 +3878,12 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.4.4: - resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.8.0: + resolution: {integrity: sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==} engines: {node: '>=20'} typed-array-buffer@1.0.3: @@ -3895,8 +3902,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.60.0: - resolution: {integrity: sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw==} + typescript-eslint@8.65.0: + resolution: {integrity: sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3919,8 +3926,8 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -3949,8 +3956,8 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - uqr@0.1.2: - resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + uqr@0.1.3: + resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -3958,8 +3965,8 @@ packages: urijs@1.19.11: resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} - use-debounce@10.1.0: - resolution: {integrity: sha512-lu87Za35V3n/MyMoEpD5zJv0k7hCn0p+V/fK2kWD+3k2u3kOCwO593UArbczg1fhfs2rqPEnHpULJ3KmGdDzvg==} + use-debounce@10.1.1: + resolution: {integrity: sha512-kvds8BHR2k28cFsxW8k3nc/tRga2rs1RHYCqmmGqb90MEeE++oALwzh2COiuBLO1/QXiOuShXoSN2ZpWnMmvuQ==} engines: {node: '>= 16.0.0'} peerDependencies: react: '*' @@ -3990,18 +3997,18 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-plugin-css-injected-by-js@3.5.2: - resolution: {integrity: sha512-2MpU/Y+SCZyWUB6ua3HbJCrgnF0KACAsmzOQt1UvRVJCGF6S8xdA3ZUhWcWdM9ivG4I5az8PnQmwwrkC2CAQrQ==} + vite-plugin-css-injected-by-js@5.0.2: + resolution: {integrity: sha512-Hvg48QfYsCL53ju9T5zTC0Ofg90XLa8t5zhhKmPYbayoMQieNcQDkkRX8pv4TAcKPZwVisLFiwDy5uBjOn+3Ow==} peerDependencies: - vite: '>2.0.0-0' + vite: '>8.0.0-0' - vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + vite@8.2.0: + resolution: {integrity: sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + '@vitejs/devtools': ^0.4.0 esbuild: '>=0.28.1' jiti: '>=1.21.0' less: ^4.0.0 @@ -4038,20 +4045,20 @@ packages: yaml: optional: true - vitest@4.1.4: - resolution: {integrity: sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==} + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.4 - '@vitest/browser-preview': 4.1.4 - '@vitest/browser-webdriverio': 4.1.4 - '@vitest/coverage-istanbul': 4.1.4 - '@vitest/coverage-v8': 4.1.4 - '@vitest/ui': 4.1.4 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 happy-dom: '>=20.8.8' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -4079,10 +4086,6 @@ packages: jsdom: optional: true - void-elements@3.1.0: - resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} - engines: {node: '>=0.10.0'} - web-worker@1.5.0: resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} @@ -4132,10 +4135,6 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -4152,10 +4151,6 @@ packages: utf-8-validate: optional: true - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -4167,8 +4162,8 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} hasBin: true @@ -4176,18 +4171,14 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} - zod-validation-error@4.0.2: resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} engines: {node: '>=18.0.0'} @@ -4212,8 +4203,8 @@ packages: react: optional: true - zustand@5.0.11: - resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==} + zustand@5.0.14: + resolution: {integrity: sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==} engines: {node: '>=12.20.0'} peerDependencies: '@types/react': '>=18.0.0' @@ -4253,81 +4244,77 @@ snapshots: '@types/json-schema': 7.0.15 js-yaml: 4.1.1 - '@ark-ui/react@5.34.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@internationalized/date': 3.11.0 - '@zag-js/accordion': 1.35.3 - '@zag-js/anatomy': 1.35.3 - '@zag-js/angle-slider': 1.35.3 - '@zag-js/async-list': 1.35.3 - '@zag-js/auto-resize': 1.35.3 - '@zag-js/avatar': 1.35.3 - '@zag-js/carousel': 1.35.3 - '@zag-js/cascade-select': 1.35.3 - '@zag-js/checkbox': 1.35.3 - '@zag-js/clipboard': 1.35.3 - '@zag-js/collapsible': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/color-picker': 1.35.3 - '@zag-js/color-utils': 1.35.3 - '@zag-js/combobox': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/date-picker': 1.35.3(@internationalized/date@3.11.0) - '@zag-js/date-utils': 1.35.3(@internationalized/date@3.11.0) - '@zag-js/dialog': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/drawer': 1.35.3 - '@zag-js/editable': 1.35.3 - '@zag-js/file-upload': 1.35.3 - '@zag-js/file-utils': 1.35.3 - '@zag-js/floating-panel': 1.35.3 - '@zag-js/focus-trap': 1.35.3 - '@zag-js/highlight-word': 1.35.3 - '@zag-js/hover-card': 1.35.3 - '@zag-js/i18n-utils': 1.35.3 - '@zag-js/image-cropper': 1.35.3 - '@zag-js/json-tree-utils': 1.35.3 - '@zag-js/listbox': 1.35.3 - '@zag-js/marquee': 1.35.3 - '@zag-js/menu': 1.35.3 - '@zag-js/navigation-menu': 1.35.3 - '@zag-js/number-input': 1.35.3 - '@zag-js/pagination': 1.35.3 - '@zag-js/password-input': 1.35.3 - '@zag-js/pin-input': 1.35.3 - '@zag-js/popover': 1.35.3 - '@zag-js/presence': 1.35.3 - '@zag-js/progress': 1.35.3 - '@zag-js/qr-code': 1.35.3 - '@zag-js/radio-group': 1.35.3 - '@zag-js/rating-group': 1.35.3 - '@zag-js/react': 1.35.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@zag-js/scroll-area': 1.35.3 - '@zag-js/select': 1.35.3 - '@zag-js/signature-pad': 1.35.3 - '@zag-js/slider': 1.35.3 - '@zag-js/splitter': 1.35.3 - '@zag-js/steps': 1.35.3 - '@zag-js/switch': 1.35.3 - '@zag-js/tabs': 1.35.3 - '@zag-js/tags-input': 1.35.3 - '@zag-js/timer': 1.35.3 - '@zag-js/toast': 1.35.3 - '@zag-js/toggle': 1.35.3 - '@zag-js/toggle-group': 1.35.3 - '@zag-js/tooltip': 1.35.3 - '@zag-js/tour': 1.35.3 - '@zag-js/tree-view': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 + '@ark-ui/react@5.37.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@internationalized/date': 3.12.2 + '@zag-js/accordion': 1.41.2 + '@zag-js/anatomy': 1.41.2 + '@zag-js/angle-slider': 1.41.2 + '@zag-js/async-list': 1.41.2 + '@zag-js/auto-resize': 1.41.2 + '@zag-js/avatar': 1.41.2 + '@zag-js/carousel': 1.41.2 + '@zag-js/cascade-select': 1.41.2 + '@zag-js/checkbox': 1.41.2 + '@zag-js/clipboard': 1.41.2 + '@zag-js/collapsible': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/color-picker': 1.41.2 + '@zag-js/color-utils': 1.41.2 + '@zag-js/combobox': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/date-input': 1.41.2(@internationalized/date@3.12.2) + '@zag-js/date-picker': 1.41.2(@internationalized/date@3.12.2) + '@zag-js/date-utils': 1.41.2(@internationalized/date@3.12.2) + '@zag-js/dialog': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/drawer': 1.41.2 + '@zag-js/editable': 1.41.2 + '@zag-js/file-upload': 1.41.2 + '@zag-js/file-utils': 1.41.2 + '@zag-js/floating-panel': 1.41.2 + '@zag-js/focus-trap': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/highlight-word': 1.41.2 + '@zag-js/hover-card': 1.41.2 + '@zag-js/i18n-utils': 1.41.2 + '@zag-js/image-cropper': 1.41.2 + '@zag-js/json-tree-utils': 1.41.2 + '@zag-js/listbox': 1.41.2 + '@zag-js/marquee': 1.41.2 + '@zag-js/menu': 1.41.2 + '@zag-js/navigation-menu': 1.41.2 + '@zag-js/number-input': 1.41.2 + '@zag-js/pagination': 1.41.2 + '@zag-js/password-input': 1.41.2 + '@zag-js/pin-input': 1.41.2 + '@zag-js/popover': 1.41.2 + '@zag-js/presence': 1.41.2 + '@zag-js/progress': 1.41.2 + '@zag-js/qr-code': 1.41.2 + '@zag-js/radio-group': 1.41.2 + '@zag-js/rating-group': 1.41.2 + '@zag-js/react': 1.41.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@zag-js/scroll-area': 1.41.2 + '@zag-js/select': 1.41.2 + '@zag-js/signature-pad': 1.41.2 + '@zag-js/slider': 1.41.2 + '@zag-js/splitter': 1.41.2 + '@zag-js/steps': 1.41.2 + '@zag-js/switch': 1.41.2 + '@zag-js/tabs': 1.41.2 + '@zag-js/tags-input': 1.41.2 + '@zag-js/timer': 1.41.2 + '@zag-js/toast': 1.41.2 + '@zag-js/toggle': 1.41.2 + '@zag-js/toggle-group': 1.41.2 + '@zag-js/tooltip': 1.41.2 + '@zag-js/tour': 1.41.2 + '@zag-js/tree-view': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@babel/code-frame@7.29.0': dependencies: @@ -4363,20 +4350,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.17.7': - dependencies: - '@babel/types': 7.17.0 - jsesc: 2.5.2 - source-map: 0.5.7 - - '@babel/generator@7.26.10': - dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.1.0 - '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.2 @@ -4393,25 +4366,12 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.24.7': - dependencies: - '@babel/types': 7.26.10 - - '@babel/helper-function-name@7.24.7': - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.26.10 - '@babel/helper-globals@7.28.0': {} - '@babel/helper-hoist-variables@7.24.7': - dependencies: - '@babel/types': 7.26.10 - '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -4431,16 +4391,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-split-export-declaration@7.24.7': - dependencies: - '@babel/types': 7.26.10 - '@babel/helper-string-parser@7.25.9': {} '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-string-parser@7.29.7': - optional: true + '@babel/helper-string-parser@7.29.7': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -4453,10 +4408,6 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 - '@babel/parser@7.26.10': - dependencies: - '@babel/types': 7.26.10 - '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -4464,7 +4415,6 @@ snapshots: '@babel/parser@7.29.7': dependencies: '@babel/types': 7.29.7 - optional: true '@babel/runtime@7.26.10': dependencies: @@ -4472,8 +4422,6 @@ snapshots: '@babel/runtime@7.28.6': {} - '@babel/runtime@7.29.2': {} - '@babel/runtime@7.29.7': {} '@babel/template@7.28.6': @@ -4482,21 +4430,6 @@ snapshots: '@babel/parser': 7.29.2 '@babel/types': 7.29.0 - '@babel/traverse@7.23.2': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-function-name': 7.24.7 - '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - debug: 4.4.3 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.29.0': dependencies: '@babel/code-frame': 7.29.0 @@ -4509,11 +4442,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.17.0': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - to-fast-properties: 2.0.0 - '@babel/types@7.26.10': dependencies: '@babel/helper-string-parser': 7.25.9 @@ -4528,37 +4456,36 @@ snapshots: dependencies: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - optional: true '@bcoe/v8-coverage@1.0.2': {} '@chakra-ui/anatomy@2.3.4': {} - '@chakra-ui/react@3.34.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@chakra-ui/react@3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@ark-ui/react': 5.34.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@ark-ui/react': 5.37.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) '@emotion/utils': 1.4.2 - '@pandacss/is-valid-prop': 1.9.0 + '@pandacss/is-valid-prop': 1.11.5 csstype: 3.2.3 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@emnapi/core@1.10.0': + '@emnapi/core@2.0.0-alpha.3': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 2.0.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@2.0.0-alpha.3': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@2.0.1': dependencies: tslib: 2.8.1 optional: true @@ -4595,19 +4522,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6)': + '@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.26.10 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 transitivePeerDependencies: - supports-color @@ -4623,26 +4550,26 @@ snapshots: '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.6)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 '@emotion/utils@1.4.2': {} '@emotion/weak-memoize@0.4.0': {} - '@eslint-community/eslint-utils@4.9.1(eslint@10.3.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.8.0(jiti@1.21.7))': dependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.0.5(eslint@10.3.0(jiti@1.21.7))': + '@eslint/compat@2.1.0(eslint@10.8.0(jiti@1.21.7))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) '@eslint/config-array@0.23.5': dependencies: @@ -4652,7 +4579,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.5.5': + '@eslint/config-helpers@0.7.0': dependencies: '@eslint/core': 1.2.1 @@ -4660,45 +4587,45 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.3.0(jiti@1.21.7))': + '@eslint/css-tree@4.0.5': + dependencies: + mdn-data: 2.29.0 + source-map-js: 1.2.1 + + '@eslint/js@10.0.1(eslint@10.8.0(jiti@1.21.7))': optionalDependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.6.1': - dependencies: - '@eslint/core': 1.2.1 - levn: 0.4.1 - - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 - '@floating-ui/core@1.7.1': - dependencies: - '@floating-ui/utils': 0.2.9 - '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.7.1': + '@floating-ui/core@1.8.0': dependencies: - '@floating-ui/core': 1.7.1 - '@floating-ui/utils': 0.2.9 + '@floating-ui/utils': 0.2.12 '@floating-ui/dom@1.7.6': dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + '@floating-ui/utils@0.2.11': {} - '@floating-ui/utils@0.2.9': {} + '@floating-ui/utils@0.2.12': {} - '@guanmingchiu/sqlparser-ts@0.61.1': {} + '@guanmingchiu/sqlparser-ts@0.62.0': {} '@hey-api/openapi-ts@0.52.0(magicast@0.3.5)(typescript@6.0.3)': dependencies: @@ -4727,41 +4654,40 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@1.0.2': {} + '@inquirer/ansi@2.0.7': {} - '@inquirer/confirm@5.1.21(@types/node@24.10.3)': + '@inquirer/confirm@6.1.1(@types/node@26.1.2)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.3) - '@inquirer/type': 3.0.10(@types/node@24.10.3) + '@inquirer/core': 11.2.1(@types/node@26.1.2) + '@inquirer/type': 4.0.7(@types/node@26.1.2) optionalDependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 - '@inquirer/core@10.3.2(@types/node@24.10.3)': + '@inquirer/core@11.2.1(@types/node@26.1.2)': dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.3) + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@26.1.2) cli-width: 4.1.0 - mute-stream: 2.0.0 + fast-wrap-ansi: 0.2.2 + mute-stream: 3.0.0 signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 - '@inquirer/figures@1.0.15': {} + '@inquirer/figures@2.0.7': {} - '@inquirer/type@3.0.10(@types/node@24.10.3)': + '@inquirer/type@4.0.7(@types/node@26.1.2)': optionalDependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 - '@internationalized/date@3.11.0': + '@internationalized/date@3.12.2': dependencies: - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.23 - '@internationalized/number@3.6.5': + '@internationalized/number@3.6.6': dependencies: - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.23 '@isaacs/cliui@9.0.0': {} @@ -4774,12 +4700,6 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -4787,17 +4707,8 @@ snapshots: '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -4817,14 +4728,14 @@ snapshots: dependencies: state-local: 1.0.7 - '@monaco-editor/react@4.7.0(monaco-editor@0.52.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@monaco-editor/react@4.7.0(monaco-editor@0.55.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@monaco-editor/loader': 1.5.0 - monaco-editor: 0.52.2 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + monaco-editor: 0.55.1 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@mswjs/interceptors@0.41.3': + '@mswjs/interceptors@0.41.9': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -4833,15 +4744,17 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.2.2(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + '@emnapi/core': 2.0.0-alpha.3 + '@emnapi/runtime': 2.0.0-alpha.3 + '@tybys/wasm-util': 0.10.3 optional: true '@open-draft/deferred-promise@2.2.0': {} + '@open-draft/deferred-promise@3.0.0': {} + '@open-draft/logger@0.3.0': dependencies: is-node-process: 1.2.0 @@ -4851,86 +4764,82 @@ snapshots: '@ota-meshi/ast-token-store@0.3.0': {} - '@oxc-project/types@0.133.0': {} + '@oxc-project/types@0.142.0': {} - '@pandacss/is-valid-prop@1.9.0': {} + '@pandacss/is-valid-prop@1.11.5': {} - '@pkgr/core@0.2.9': {} + '@pkgr/core@0.3.6': {} - '@playwright/test@1.60.0': + '@playwright/test@1.62.1': dependencies: - playwright: 1.60.0 + playwright: 1.62.1 - '@rolldown/binding-android-arm64@1.0.3': + '@rolldown/binding-android-arm64@1.2.1': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@rolldown/binding-darwin-arm64@1.2.1': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@rolldown/binding-darwin-x64@1.2.1': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@rolldown/binding-freebsd-x64@1.2.1': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@rolldown/binding-linux-arm-gnueabihf@1.2.1': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@rolldown/binding-linux-arm64-gnu@1.2.1': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@rolldown/binding-linux-arm64-musl@1.2.1': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@rolldown/binding-linux-ppc64-gnu@1.2.1': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@rolldown/binding-linux-s390x-gnu@1.2.1': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@rolldown/binding-linux-x64-gnu@1.2.1': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@rolldown/binding-linux-x64-musl@1.2.1': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@rolldown/binding-openharmony-arm64@1.2.1': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': + '@rolldown/binding-wasm32-wasi@1.2.1': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 2.0.0-alpha.3 + '@emnapi/runtime': 2.0.0-alpha.3 + '@napi-rs/wasm-runtime': 1.2.2(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@rolldown/binding-win32-arm64-msvc@1.2.1': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@rolldown/binding-win32-x64-msvc@1.2.1': optional: true - '@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3))': + '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.2.1)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.0 - picomatch: 4.0.4 - rolldown: 1.0.3 + picomatch: 4.0.5 + rolldown: 1.2.1 optionalDependencies: '@babel/runtime': 7.29.7 - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) - - '@rolldown/pluginutils@1.0.0-rc.2': {} - - '@rolldown/pluginutils@1.0.0-rc.7': {} + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) '@rolldown/pluginutils@1.0.1': {} '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@2.13.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@stylistic/eslint-plugin@2.13.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - eslint: 10.3.0(jiti@1.21.7) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + eslint: 10.8.0(jiti@1.21.7) eslint-visitor-keys: 4.2.0 espree: 10.3.0 estraverse: 5.3.0 @@ -4939,94 +4848,102 @@ snapshots: - supports-color - typescript - '@swc/core-darwin-arm64@1.15.18': + '@swc/core-darwin-arm64@1.15.47': + optional: true + + '@swc/core-darwin-x64@1.15.47': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.47': optional: true - '@swc/core-darwin-x64@1.15.18': + '@swc/core-linux-arm64-gnu@1.15.47': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.18': + '@swc/core-linux-arm64-musl@1.15.47': optional: true - '@swc/core-linux-arm64-gnu@1.15.18': + '@swc/core-linux-ppc64-gnu@1.15.47': optional: true - '@swc/core-linux-arm64-musl@1.15.18': + '@swc/core-linux-s390x-gnu@1.15.47': optional: true - '@swc/core-linux-x64-gnu@1.15.18': + '@swc/core-linux-x64-gnu@1.15.47': optional: true - '@swc/core-linux-x64-musl@1.15.18': + '@swc/core-linux-x64-musl@1.15.47': optional: true - '@swc/core-win32-arm64-msvc@1.15.18': + '@swc/core-win32-arm64-msvc@1.15.47': optional: true - '@swc/core-win32-ia32-msvc@1.15.18': + '@swc/core-win32-ia32-msvc@1.15.47': optional: true - '@swc/core-win32-x64-msvc@1.15.18': + '@swc/core-win32-x64-msvc@1.15.47': optional: true - '@swc/core@1.15.18(@swc/helpers@0.5.19)': + '@swc/core@1.15.47(@swc/helpers@0.5.23)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.25 + '@swc/types': 0.1.27 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.18 - '@swc/core-darwin-x64': 1.15.18 - '@swc/core-linux-arm-gnueabihf': 1.15.18 - '@swc/core-linux-arm64-gnu': 1.15.18 - '@swc/core-linux-arm64-musl': 1.15.18 - '@swc/core-linux-x64-gnu': 1.15.18 - '@swc/core-linux-x64-musl': 1.15.18 - '@swc/core-win32-arm64-msvc': 1.15.18 - '@swc/core-win32-ia32-msvc': 1.15.18 - '@swc/core-win32-x64-msvc': 1.15.18 - '@swc/helpers': 0.5.19 + '@swc/core-darwin-arm64': 1.15.47 + '@swc/core-darwin-x64': 1.15.47 + '@swc/core-linux-arm-gnueabihf': 1.15.47 + '@swc/core-linux-arm64-gnu': 1.15.47 + '@swc/core-linux-arm64-musl': 1.15.47 + '@swc/core-linux-ppc64-gnu': 1.15.47 + '@swc/core-linux-s390x-gnu': 1.15.47 + '@swc/core-linux-x64-gnu': 1.15.47 + '@swc/core-linux-x64-musl': 1.15.47 + '@swc/core-win32-arm64-msvc': 1.15.47 + '@swc/core-win32-ia32-msvc': 1.15.47 + '@swc/core-win32-x64-msvc': 1.15.47 + '@swc/helpers': 0.5.23 '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.19': + '@swc/helpers@0.5.23': dependencies: tslib: 2.8.1 - '@swc/types@0.1.25': + '@swc/types@0.1.27': dependencies: '@swc/counter': 0.1.3 - '@tanstack/eslint-plugin-query@5.91.4(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@tanstack/eslint-plugin-query@5.101.4(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - eslint: 10.3.0(jiti@1.21.7) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + eslint: 10.8.0(jiti@1.21.7) optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@tanstack/query-core@5.90.20': {} + '@tanstack/query-core@5.101.4': {} - '@tanstack/react-query@5.90.21(react@19.2.6)': + '@tanstack/react-query@5.101.4(react@19.2.7)': dependencies: - '@tanstack/query-core': 5.90.20 - react: 19.2.6 + '@tanstack/query-core': 5.101.4 + react: 19.2.7 - '@tanstack/react-table@8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tanstack/react-table@8.21.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@tanstack/table-core': 8.21.3 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@tanstack/react-virtual@3.13.21(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tanstack/react-virtual@3.14.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/virtual-core': 3.13.21 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@tanstack/virtual-core': 3.17.7 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@tanstack/table-core@8.21.3': {} - '@tanstack/virtual-core@3.13.21': {} + '@tanstack/virtual-core@3.17.7': {} '@testing-library/dom@10.4.0': dependencies: @@ -5039,34 +4956,37 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.9.1': + '@testing-library/jest-dom@7.0.0(@testing-library/dom@10.4.0)': dependencies: '@adobe/css-tools': 4.4.2 + '@testing-library/dom': 10.4.0 aria-query: 5.3.2 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@babel/runtime': 7.28.6 '@testing-library/dom': 10.4.0 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) optionalDependencies: - '@types/react': 19.2.15 - '@types/react-dom': 19.2.3(@types/react@19.2.15) + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@trivago/prettier-plugin-sort-imports@4.3.0(prettier@3.8.1)': + '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.9.6)': dependencies: - '@babel/generator': 7.17.7 - '@babel/parser': 7.26.10 - '@babel/traverse': 7.23.2 - '@babel/types': 7.17.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.7 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.7 javascript-natural-sort: 0.7.1 - lodash: 4.18.1 - prettier: 3.8.1 + lodash-es: 4.18.1 + minimatch: 9.0.9 + parse-imports-exports: 0.2.4 + prettier: 3.9.6 transitivePeerDependencies: - supports-color @@ -5076,16 +4996,17 @@ snapshots: path-browserify: 1.0.1 tinyglobby: 0.2.17 - '@tybys/wasm-util@0.10.2': + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 optional: true '@types/aria-query@5.0.4': {} - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/culori@4.0.1': {} @@ -5109,13 +5030,13 @@ snapshots: '@types/d3-interpolate@3.0.1': dependencies: - '@types/d3-color': 3.1.0 + '@types/d3-color': 3.1.3 '@types/d3-interpolate@3.0.4': dependencies: '@types/d3-color': 3.1.3 - '@types/d3-path@1.0.11': {} + '@types/d3-path@3.1.1': {} '@types/d3-scale@4.0.2': dependencies: @@ -5123,9 +5044,9 @@ snapshots: '@types/d3-selection@3.0.11': {} - '@types/d3-shape@1.3.12': + '@types/d3-shape@3.1.7': dependencies: - '@types/d3-path': 1.0.11 + '@types/d3-path': 3.1.1 '@types/d3-time-format@2.1.0': {} @@ -5156,48 +5077,51 @@ snapshots: '@types/geojson@7946.0.16': {} - '@types/hast@2.3.10': - dependencies: - '@types/unist': 2.0.11 - '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 '@types/json-schema@7.0.15': {} - '@types/lodash@4.17.20': {} - '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 '@types/ms@2.1.0': {} - '@types/node@24.10.3': + '@types/node@26.1.2': dependencies: - undici-types: 7.16.0 + undici-types: 8.3.0 '@types/parse-json@4.0.2': {} - '@types/react-dom@19.2.3(@types/react@19.2.15)': + '@types/prismjs@1.26.6': {} + + '@types/react-dom@19.2.3(@types/react@19.2.17)': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 '@types/react-syntax-highlighter@15.5.13': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@types/react-transition-group@4.4.12(@types/react@19.2.15)': + '@types/react-transition-group@4.4.12(@types/react@19.2.17)': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@types/react@19.2.15': + '@types/react@19.2.17': dependencies: csstype: 3.2.3 + '@types/set-cookie-parser@2.4.10': + dependencies: + '@types/node': 26.1.2 + '@types/statuses@2.0.6': {} + '@types/trusted-types@2.0.7': + optional: true + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -5206,134 +5130,128 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 - eslint: 10.3.0(jiti@1.21.7) - ignore: 7.0.5 + '@typescript-eslint/parser': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/type-utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.65.0 + eslint: 10.8.0(jiti@1.21.7) + ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3 - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.65.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.60.0': + '@typescript-eslint/scope-manager@8.65.0': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 - '@typescript-eslint/tsconfig-utils@8.60.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.65.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) debug: 4.4.3 - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.60.0': {} + '@typescript-eslint/types@8.65.0': {} - '@typescript-eslint/typescript-estree@8.60.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.65.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.60.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.65.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.1 + semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/utils@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - eslint: 10.3.0(jiti@1.21.7) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + eslint: 10.8.0(jiti@1.21.7) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.60.0': + '@typescript-eslint/visitor-keys@8.65.0': dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.65.0 eslint-visitor-keys: 5.0.1 '@ungap/structured-clone@1.3.0': {} - '@visx/curve@3.12.0': + '@visx/curve@4.0.0': dependencies: - '@types/d3-shape': 1.3.12 - d3-shape: 1.3.7 + '@visx/vendor': 4.0.0 - '@visx/group@3.12.0(react@19.2.6)': + '@visx/group@4.0.0(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@types/react': 19.2.15 classnames: 2.5.1 - prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 - '@visx/scale@3.12.0': + '@visx/scale@4.0.0': dependencies: - '@visx/vendor': 3.12.0 + '@visx/vendor': 4.0.0 - '@visx/shape@3.12.0(react@19.2.6)': + '@visx/shape@4.0.0(@types/react@19.2.17)(react@19.2.7)': dependencies: - '@types/d3-path': 1.0.11 - '@types/d3-shape': 1.3.12 - '@types/lodash': 4.17.20 - '@types/react': 19.2.15 - '@visx/curve': 3.12.0 - '@visx/group': 3.12.0(react@19.2.6) - '@visx/scale': 3.12.0 + '@visx/curve': 4.0.0 + '@visx/group': 4.0.0(@types/react@19.2.17)(react@19.2.7) + '@visx/scale': 4.0.0 + '@visx/vendor': 4.0.0 classnames: 2.5.1 - d3-path: 1.0.9 - d3-shape: 1.3.7 - lodash: 4.18.1 - prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 - '@visx/vendor@3.12.0': + '@visx/vendor@4.0.0': dependencies: '@types/d3-array': 3.0.3 '@types/d3-color': 3.1.0 @@ -5341,7 +5259,9 @@ snapshots: '@types/d3-format': 3.0.1 '@types/d3-geo': 3.1.0 '@types/d3-interpolate': 3.0.1 + '@types/d3-path': 3.1.1 '@types/d3-scale': 4.0.2 + '@types/d3-shape': 3.1.7 '@types/d3-time': 3.0.0 '@types/d3-time-format': 2.1.0 d3-array: 3.2.1 @@ -5350,95 +5270,99 @@ snapshots: d3-format: 3.1.0 d3-geo: 3.1.0 d3-interpolate: 3.0.1 + d3-path: 3.1.0 d3-scale: 4.0.2 + d3-shape: 3.2.0 d3-time: 3.1.0 d3-time-format: 4.1.0 internmap: 2.0.3 - '@vitejs/plugin-react-swc@4.2.3(@swc/helpers@0.5.19)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3))': + '@vitejs/plugin-react-swc@4.3.3(@swc/helpers@0.5.23)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0))': dependencies: - '@rolldown/pluginutils': 1.0.0-rc.2 - '@swc/core': 1.15.18(@swc/helpers@0.5.19) - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + '@rolldown/pluginutils': 1.0.1 + '@swc/core': 1.15.47(@swc/helpers@0.5.23) + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.2.1)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0))': dependencies: - '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + '@rolldown/pluginutils': 1.0.1 + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) optionalDependencies: - '@rolldown/plugin-babel': 0.2.2(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.7)(rolldown@1.2.1)(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) babel-plugin-react-compiler: 1.0.0 - '@vitest/coverage-v8@4.1.4(vitest@4.1.4)': + '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.4 - ast-v8-to-istanbul: 1.0.0 + '@vitest/utils': 4.1.10 + ast-v8-to-istanbul: 1.0.4 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 - magicast: 0.5.2 - obug: 2.1.1 - std-env: 4.0.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.2.0 tinyrainbow: 3.1.0 - vitest: 4.1.4(@types/node@24.10.3)(@vitest/coverage-v8@4.1.4)(happy-dom@20.8.9)(msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3))(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) + vitest: 4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3))(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) - '@vitest/expect@4.1.4': + '@vitest/expect@4.1.10': dependencies: '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.2 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.4(msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3))(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3))': + '@vitest/mocker@4.1.10(msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3))(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.4 + '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - msw: 2.12.10(@types/node@24.10.3)(typescript@6.0.3) - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + msw: 2.15.0(@types/node@26.1.2)(typescript@6.0.3) + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) - '@vitest/pretty-format@4.1.4': + '@vitest/pretty-format@4.1.10': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.4': + '@vitest/runner@4.1.10': dependencies: - '@vitest/utils': 4.1.4 + '@vitest/utils': 4.1.10 pathe: 2.0.3 - '@vitest/snapshot@4.1.4': + '@vitest/snapshot@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.4': {} + '@vitest/spy@4.1.10': {} - '@vitest/utils@4.1.4': + '@vitest/utils@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.4 + '@vitest/pretty-format': 4.1.10 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@xyflow/react@12.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@xyflow/react@12.11.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@xyflow/system': 0.0.75 + '@xyflow/system': 0.0.79 classcat: 5.0.5 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - zustand: 4.5.7(@types/react@19.2.15)(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + zustand: 4.5.7(@types/react@19.2.17)(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) transitivePeerDependencies: - - '@types/react' - immer - '@xyflow/system@0.0.75': + '@xyflow/system@0.0.79': dependencies: '@types/d3-drag': 3.0.7 '@types/d3-interpolate': 3.0.4 @@ -5450,579 +5374,584 @@ snapshots: d3-selection: 3.0.0 d3-zoom: 3.0.0 - '@zag-js/accordion@1.35.3': + '@zag-js/accordion@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/anatomy@1.35.3': {} + '@zag-js/anatomy@1.41.2': {} - '@zag-js/angle-slider@1.35.3': + '@zag-js/angle-slider@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/rect-utils': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/rect-utils': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/aria-hidden@1.35.3': + '@zag-js/aria-hidden@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/async-list@1.35.3': + '@zag-js/async-list@1.41.2': dependencies: - '@zag-js/core': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/core': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/auto-resize@1.35.3': + '@zag-js/auto-resize@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/avatar@1.35.3': + '@zag-js/avatar@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/carousel@1.35.3': + '@zag-js/carousel@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/scroll-snap': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/scroll-snap': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/cascade-select@1.35.3': + '@zag-js/cascade-select@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/rect-utils': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/rect-utils': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/checkbox@1.35.3': + '@zag-js/checkbox@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/clipboard@1.35.3': + '@zag-js/clipboard@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/collapsible@1.35.3': + '@zag-js/collapsible@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/collection@1.35.3': + '@zag-js/collection@1.41.2': dependencies: - '@zag-js/utils': 1.35.3 + '@zag-js/utils': 1.41.2 - '@zag-js/color-picker@1.35.3': + '@zag-js/color-picker@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/color-utils': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/color-utils': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/color-utils@1.35.3': - dependencies: - '@zag-js/utils': 1.35.3 + '@zag-js/color-utils@1.41.2': + dependencies: + '@zag-js/utils': 1.41.2 - '@zag-js/combobox@1.35.3': + '@zag-js/combobox@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/aria-hidden': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/live-region': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/core@1.35.3': + '@zag-js/core@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/dom-query': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/date-picker@1.35.3(@internationalized/date@3.11.0)': + '@zag-js/date-input@1.41.2(@internationalized/date@3.12.2)': dependencies: - '@internationalized/date': 3.11.0 - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/date-utils': 1.35.3(@internationalized/date@3.11.0) - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/live-region': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@internationalized/date': 3.12.2 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/date-utils': 1.41.2(@internationalized/date@3.12.2) + '@zag-js/dom-query': 1.41.2 + '@zag-js/live-region': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/date-picker@1.41.2(@internationalized/date@3.12.2)': + dependencies: + '@internationalized/date': 3.12.2 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/date-utils': 1.41.2(@internationalized/date@3.12.2) + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/live-region': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/date-utils@1.35.3(@internationalized/date@3.11.0)': + '@zag-js/date-utils@1.41.2(@internationalized/date@3.12.2)': dependencies: - '@internationalized/date': 3.11.0 + '@internationalized/date': 3.12.2 - '@zag-js/dialog@1.35.3': + '@zag-js/dialog@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/aria-hidden': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-trap': 1.35.3 - '@zag-js/remove-scroll': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/aria-hidden': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-trap': 1.41.2 + '@zag-js/remove-scroll': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/dismissable@1.35.3': + '@zag-js/dismissable@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 - '@zag-js/interact-outside': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/dom-query': 1.41.2 + '@zag-js/interact-outside': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/dom-query@1.35.3': + '@zag-js/dom-query@1.41.2': dependencies: - '@zag-js/types': 1.35.3 + '@zag-js/types': 1.41.2 - '@zag-js/drawer@1.35.3': + '@zag-js/drawer@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/aria-hidden': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-trap': 1.35.3 - '@zag-js/remove-scroll': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/aria-hidden': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-trap': 1.41.2 + '@zag-js/remove-scroll': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/editable@1.35.3': + '@zag-js/editable@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/interact-outside': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/interact-outside': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/file-upload@1.35.3': + '@zag-js/file-upload@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/file-utils': 1.35.3 - '@zag-js/i18n-utils': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/file-utils': 1.41.2 + '@zag-js/i18n-utils': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/file-utils@1.35.3': + '@zag-js/file-utils@1.41.2': dependencies: - '@zag-js/i18n-utils': 1.35.3 + '@zag-js/i18n-utils': 1.41.2 - '@zag-js/floating-panel@1.35.3': + '@zag-js/floating-panel@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/rect-utils': 1.35.3 - '@zag-js/store': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/rect-utils': 1.41.2 + '@zag-js/store': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/focus-trap@1.35.3': + '@zag-js/focus-trap@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/focus-visible@1.35.3': + '@zag-js/focus-visible@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/highlight-word@1.35.3': {} + '@zag-js/highlight-word@1.41.2': {} - '@zag-js/hover-card@1.35.3': + '@zag-js/hover-card@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/i18n-utils@1.35.3': + '@zag-js/i18n-utils@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/image-cropper@1.35.3': + '@zag-js/image-cropper@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/interact-outside@1.35.3': + '@zag-js/interact-outside@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/dom-query': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/json-tree-utils@1.35.3': {} + '@zag-js/json-tree-utils@1.41.2': {} - '@zag-js/listbox@1.35.3': + '@zag-js/listbox@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/live-region@1.35.3': {} + '@zag-js/live-region@1.41.2': {} - '@zag-js/marquee@1.35.3': + '@zag-js/marquee@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/menu@1.35.3': + '@zag-js/menu@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/rect-utils': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/rect-utils': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/navigation-menu@1.35.3': + '@zag-js/navigation-menu@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/number-input@1.35.3': + '@zag-js/number-input@1.41.2': dependencies: - '@internationalized/number': 3.6.5 - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@internationalized/number': 3.6.6 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/pagination@1.35.3': + '@zag-js/pagination@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/password-input@1.35.3': + '@zag-js/password-input@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/pin-input@1.35.3': + '@zag-js/pin-input@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/popover@1.35.3': + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/popover@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/aria-hidden': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-trap': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/remove-scroll': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/aria-hidden': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-trap': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/remove-scroll': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/popper@1.41.2': + dependencies: + '@floating-ui/dom': 1.8.0 + '@zag-js/dom-query': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/popper@1.35.3': - dependencies: - '@floating-ui/dom': 1.7.6 - '@zag-js/dom-query': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/presence@1.35.3': - dependencies: - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - - '@zag-js/progress@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/qr-code@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/presence@1.41.2': + dependencies: + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + + '@zag-js/progress@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/qr-code@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 proxy-memoize: 3.0.1 - uqr: 0.1.2 + uqr: 0.1.3 - '@zag-js/radio-group@1.35.3': + '@zag-js/radio-group@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/rating-group@1.35.3': + '@zag-js/rating-group@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/react@1.35.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@zag-js/react@1.41.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@zag-js/core': 1.35.3 - '@zag-js/store': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@zag-js/core': 1.41.2 + '@zag-js/store': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - '@zag-js/rect-utils@1.35.3': {} + '@zag-js/rect-utils@1.41.2': {} - '@zag-js/remove-scroll@1.35.3': + '@zag-js/remove-scroll@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/scroll-area@1.35.3': + '@zag-js/scroll-area@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/scroll-snap@1.35.3': + '@zag-js/scroll-snap@1.41.2': dependencies: - '@zag-js/dom-query': 1.35.3 + '@zag-js/dom-query': 1.41.2 - '@zag-js/select@1.35.3': + '@zag-js/select@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/signature-pad@1.35.3': + '@zag-js/signature-pad@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 perfect-freehand: 1.2.3 - '@zag-js/slider@1.35.3': + '@zag-js/slider@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/splitter@1.35.3': + '@zag-js/splitter@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/steps@1.35.3': + '@zag-js/steps@1.41.2': dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 - '@zag-js/store@1.35.3': + '@zag-js/store@1.41.2': dependencies: proxy-compare: 3.0.1 - '@zag-js/switch@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/tabs@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/tags-input@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/auto-resize': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/interact-outside': 1.35.3 - '@zag-js/live-region': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/timer@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/toast@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/toggle-group@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/toggle@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/tooltip@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-visible': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/tour@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dismissable': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/focus-trap': 1.35.3 - '@zag-js/interact-outside': 1.35.3 - '@zag-js/popper': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/tree-view@1.35.3': - dependencies: - '@zag-js/anatomy': 1.35.3 - '@zag-js/collection': 1.35.3 - '@zag-js/core': 1.35.3 - '@zag-js/dom-query': 1.35.3 - '@zag-js/types': 1.35.3 - '@zag-js/utils': 1.35.3 - - '@zag-js/types@1.35.3': + '@zag-js/switch@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/tabs@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/tags-input@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/auto-resize': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/interact-outside': 1.41.2 + '@zag-js/live-region': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/timer@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/toast@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/toggle-group@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/toggle@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/tooltip@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-visible': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/tour@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dismissable': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/focus-trap': 1.41.2 + '@zag-js/interact-outside': 1.41.2 + '@zag-js/popper': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/tree-view@1.41.2': + dependencies: + '@zag-js/anatomy': 1.41.2 + '@zag-js/collection': 1.41.2 + '@zag-js/core': 1.41.2 + '@zag-js/dom-query': 1.41.2 + '@zag-js/types': 1.41.2 + '@zag-js/utils': 1.41.2 + + '@zag-js/types@1.41.2': dependencies: csstype: 3.2.3 - '@zag-js/utils@1.35.3': {} + '@zag-js/utils@1.41.2': {} acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn-jsx@5.3.2(acorn@8.16.0): + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: - acorn: 8.16.0 + acorn: 8.17.0 acorn@8.14.1: {} - acorn@8.15.0: {} - - acorn@8.16.0: {} + acorn@8.17.0: {} agent-base@6.0.2: dependencies: @@ -6057,7 +5986,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 4.0.4 + picomatch: 4.0.5 argparse@1.0.10: dependencies: @@ -6126,9 +6055,11 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@1.0.0: + ast-v8-to-istanbul@1.0.4: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -6149,10 +6080,10 @@ snapshots: axe-core@4.10.3: {} - axios@1.16.1: + axios@1.18.1: dependencies: follow-redirects: 1.16.0 - form-data: 4.0.5 + form-data: 4.0.6 https-proxy-agent: 5.0.1 proxy-from-env: 2.1.0 transitivePeerDependencies: @@ -6163,7 +6094,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.26.10 cosmiconfig: 7.1.0 resolve: 1.22.10 @@ -6179,6 +6110,8 @@ snapshots: baseline-browser-mapping@2.10.21: {} + baseline-browser-mapping@2.11.4: {} + binary-extensions@2.3.0: {} brace-expansion@1.1.13: @@ -6186,7 +6119,11 @@ snapshots: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@5.0.6: + brace-expansion@2.1.4: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -6202,6 +6139,18 @@ snapshots: node-releases: 2.0.38 update-browserslist-db: 1.2.3(browserslist@4.28.2) + browserslist@4.28.7: + dependencies: + baseline-browser-mapping: 2.11.4 + caniuse-lite: 1.0.30001806 + electron-to-chromium: 1.5.396 + node-releases: 2.0.51 + update-browserslist-db: 1.2.3(browserslist@4.28.7) + + buffer-image-size@0.6.4: + dependencies: + '@types/node': 26.1.2 + builtin-modules@5.1.0: {} c12@1.11.1(magicast@0.3.5): @@ -6244,16 +6193,18 @@ snapshots: caniuse-lite@1.0.30001790: {} + caniuse-lite@1.0.30001806: {} + ccount@2.0.1: {} chai@6.2.2: {} - chakra-react-select@6.1.1(@chakra-ui/react@3.34.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.15)(next-themes@0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + chakra-react-select@6.1.3(@chakra-ui/react@3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react@19.2.17)(next-themes@0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@chakra-ui/react': 3.34.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - next-themes: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-select: 5.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@chakra-ui/react': 3.36.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + next-themes: 0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-select: 5.10.2(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) transitivePeerDependencies: - '@types/react' - react-dom @@ -6268,26 +6219,20 @@ snapshots: character-entities-html4@2.1.0: {} - character-entities-legacy@1.1.4: {} - character-entities-legacy@3.0.0: {} - character-entities@1.2.4: {} - character-entities@2.0.2: {} - character-reference-invalid@1.1.4: {} - character-reference-invalid@2.0.1: {} chart.js@4.5.1: dependencies: '@kurkle/color': 0.3.4 - chartjs-adapter-dayjs-4@1.0.4(chart.js@4.5.1)(dayjs@1.11.19): + chartjs-adapter-dayjs-4@1.0.4(chart.js@4.5.1)(dayjs@1.11.21): dependencies: chart.js: 4.5.1 - dayjs: 1.11.19 + dayjs: 1.11.21 chartjs-plugin-annotation@3.1.0(chart.js@4.5.1): dependencies: @@ -6317,10 +6262,6 @@ snapshots: classnames@2.5.1: {} - clean-regexp@1.0.0: - dependencies: - escape-string-regexp: 1.0.5 - cli-width@4.1.0: {} cliui@8.0.1: @@ -6341,8 +6282,6 @@ snapshots: dependencies: delayed-stream: 1.0.0 - comma-separated-tokens@1.0.8: {} - comma-separated-tokens@2.0.3: {} commander@12.1.0: {} @@ -6355,6 +6294,8 @@ snapshots: consola@3.4.2: {} + convert-hrtime@5.0.0: {} + convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} @@ -6363,7 +6304,7 @@ snapshots: core-js-compat@3.49.0: dependencies: - browserslist: 4.28.2 + browserslist: 4.28.7 cosmiconfig@7.1.0: dependencies: @@ -6371,13 +6312,7 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 2.8.3 - - cross-fetch@4.1.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding + yaml: 2.9.0 cross-spawn@7.0.6: dependencies: @@ -6420,7 +6355,7 @@ snapshots: dependencies: d3-color: 3.1.0 - d3-path@1.0.9: {} + d3-path@3.1.0: {} d3-scale@4.0.2: dependencies: @@ -6432,9 +6367,9 @@ snapshots: d3-selection@3.0.0: {} - d3-shape@1.3.7: + d3-shape@3.2.0: dependencies: - d3-path: 1.0.9 + d3-path: 3.1.0 d3-time-format@4.1.0: dependencies: @@ -6483,7 +6418,7 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - dayjs@1.11.19: {} + dayjs@1.11.21: {} debug@4.4.3: dependencies: @@ -6519,6 +6454,8 @@ snapshots: destr@2.0.5: {} + detect-indent@7.0.2: {} + detect-libc@2.1.2: {} devlop@1.1.0: @@ -6537,9 +6474,13 @@ snapshots: dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.29.7 csstype: 3.2.3 + dompurify@3.2.7: + optionalDependencies: + '@types/trusted-types': 2.0.7 + dotenv@16.6.1: {} dunder-proto@1.0.1: @@ -6550,12 +6491,16 @@ snapshots: electron-to-chromium@1.5.344: {} + electron-to-chromium@1.5.396: {} + elkjs@0.11.1: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + entities@4.5.0: {} + entities@7.0.1: {} error-ex@1.3.2: @@ -6586,7 +6531,7 @@ snapshots: has-property-descriptors: 1.0.2 has-proto: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.2 internal-slot: 1.1.0 is-array-buffer: 3.0.5 is-callable: 1.2.7 @@ -6639,7 +6584,7 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 - es-module-lexer@2.0.0: {} + es-module-lexer@2.3.0: {} es-object-atoms@1.1.1: dependencies: @@ -6650,11 +6595,11 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 es-shim-unscopables@1.1.0: dependencies: - hasown: 2.0.3 + hasown: 2.0.2 es-to-primitive@1.3.0: dependencies: @@ -6666,43 +6611,40 @@ snapshots: escalade@3.2.0: {} - escape-string-regexp@1.0.5: {} - escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.3.0(jiti@1.21.7)): + eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@1.21.7)): dependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) - eslint-json-compat-utils@0.2.3(eslint@10.3.0(jiti@1.21.7))(jsonc-eslint-parser@3.1.0): + eslint-json-compat-utils@0.2.3(eslint@10.8.0(jiti@1.21.7))(jsonc-eslint-parser@3.1.0): dependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) esquery: 1.7.0 jsonc-eslint-parser: 3.1.0 - eslint-plugin-i18next@6.1.4: + eslint-plugin-i18next@6.1.5: dependencies: - lodash: 4.18.1 requireindex: 1.1.0 - eslint-plugin-jsonc@3.1.2(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-jsonc@3.3.0(eslint@10.8.0(jiti@1.21.7)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@1.21.7)) '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.6.1 + '@eslint/plugin-kit': 0.7.2 '@ota-meshi/ast-token-store': 0.3.0 diff-sequences: 29.6.3 - eslint: 10.3.0(jiti@1.21.7) - eslint-json-compat-utils: 0.2.3(eslint@10.3.0(jiti@1.21.7))(jsonc-eslint-parser@3.1.0) + eslint: 10.8.0(jiti@1.21.7) + eslint-json-compat-utils: 0.2.3(eslint@10.8.0(jiti@1.21.7))(jsonc-eslint-parser@3.1.0) jsonc-eslint-parser: 3.1.0 natural-compare: 1.4.0 - synckit: 0.11.12 + synckit: 0.11.13 transitivePeerDependencies: - '@eslint/json' - eslint-plugin-jsx-a11y@6.10.2(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@10.8.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -6712,7 +6654,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -6721,40 +6663,40 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-perfectionist@5.9.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3): + eslint-plugin-perfectionist@5.10.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3): dependencies: - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - eslint: 10.3.0(jiti@1.21.7) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + eslint: 10.8.0(jiti@1.21.7) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-prettier@5.5.5(eslint-config-prettier@10.1.8(eslint@10.3.0(jiti@1.21.7)))(eslint@10.3.0(jiti@1.21.7))(prettier@3.8.1): + eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@1.21.7)))(eslint@10.8.0(jiti@1.21.7))(prettier@3.9.6): dependencies: - eslint: 10.3.0(jiti@1.21.7) - prettier: 3.8.1 + eslint: 10.8.0(jiti@1.21.7) + prettier: 3.9.6 prettier-linter-helpers: 1.0.1 - synckit: 0.11.12 + synckit: 0.11.13 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@10.3.0(jiti@1.21.7)) + eslint-config-prettier: 10.1.8(eslint@10.8.0(jiti@1.21.7)) - eslint-plugin-react-hooks@7.1.1(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-react-hooks@7.1.1(eslint@10.8.0(jiti@1.21.7)): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.2 - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-react-refresh@0.5.3(eslint@10.8.0(jiti@1.21.7)): dependencies: - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) - eslint-plugin-react@7.37.5(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-react@7.37.5(eslint@10.8.0(jiti@1.21.7)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -6762,7 +6704,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 10.3.0(jiti@1.21.7) + eslint: 10.8.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -6776,25 +6718,29 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-unicorn@64.0.0(eslint@10.3.0(jiti@1.21.7)): + eslint-plugin-unicorn@72.0.0(eslint@10.8.0(jiti@1.21.7)): dependencies: - '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@1.21.7)) + '@eslint/css-tree': 4.0.5 + browserslist: 4.28.7 change-case: 5.4.4 ci-info: 4.4.0 - clean-regexp: 1.0.0 core-js-compat: 3.49.0 - eslint: 10.3.0(jiti@1.21.7) + detect-indent: 7.0.2 + entities: 4.5.0 + eslint: 10.8.0(jiti@1.21.7) find-up-simple: 1.0.1 - globals: 17.5.0 + globals: 17.8.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 - jsesc: 3.1.0 + is-identifier: 1.1.0 pluralize: 8.0.0 - regexp-tree: 0.1.27 - regjsparser: 0.13.1 - semver: 7.7.4 + quote-js-string: 0.1.0 + regjsparser: 0.13.2 + reserved-identifiers: 1.2.0 + semver: 7.8.5 strip-indent: 4.1.1 + yaml: 2.9.0 eslint-scope@9.1.2: dependencies: @@ -6809,14 +6755,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.3.0(jiti@1.21.7): + eslint@10.8.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.8.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 - '@eslint/config-helpers': 0.5.5 + '@eslint/config-helpers': 0.7.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -6854,16 +6800,10 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 5.0.1 - espree@9.6.1: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 3.4.3 - esprima@4.0.1: {} esquery@1.7.0: @@ -6884,7 +6824,7 @@ snapshots: esutils@2.0.3: {} - expect-type@1.3.0: {} + expect-type@1.4.0: {} extend@3.0.2: {} @@ -6896,13 +6836,23 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + fault@1.0.4: dependencies: format: 0.2.2 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 file-entry-cache@8.0.0: dependencies: @@ -6939,12 +6889,12 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.5: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.3 + hasown: 2.0.4 mime-types: 2.1.35 format@0.2.2: {} @@ -6957,13 +6907,15 @@ snapshots: function-bind@1.1.2: {} + function-timeout@1.0.2: {} + function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 - hasown: 2.0.3 + hasown: 2.0.2 is-callable: 1.2.7 functions-have-names@1.2.3: {} @@ -6982,7 +6934,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.2 math-intrinsics: 1.1.0 get-proto@1.0.1: @@ -7023,11 +6975,7 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.2 - globals@11.12.0: {} - - globals@15.15.0: {} - - globals@17.5.0: {} + globals@17.8.0: {} globalthis@1.0.4: dependencies: @@ -7036,7 +6984,7 @@ snapshots: gopd@1.2.0: {} - graphql@16.13.1: {} + graphql@16.14.2: {} handlebars@4.7.9: dependencies: @@ -7047,11 +6995,12 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - happy-dom@20.8.9: + happy-dom@20.11.1: dependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 + buffer-image-size: 0.6.4 entities: 7.0.1 whatwg-mimetype: 3.0.0 ws: 8.21.0 @@ -7081,11 +7030,13 @@ snapshots: dependencies: function-bind: 1.1.2 - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 - hast-util-parse-selector@2.2.5: {} + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 hast-util-to-jsx-runtime@2.3.6: dependencies: @@ -7111,15 +7062,18 @@ snapshots: dependencies: '@types/hast': 3.0.4 - hastscript@6.0.0: + hastscript@9.0.1: dependencies: - '@types/hast': 2.3.10 - comma-separated-tokens: 1.0.8 - hast-util-parse-selector: 2.2.5 - property-information: 5.6.0 - space-separated-tokens: 1.1.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 - headers-polyfill@4.0.3: {} + headers-polyfill@5.0.1: + dependencies: + '@types/set-cookie-parser': 2.4.10 + set-cookie-parser: 3.1.2 hermes-estree@0.25.1: {} @@ -7137,9 +7091,7 @@ snapshots: html-escaper@2.0.2: {} - html-parse-stringify@3.0.1: - dependencies: - void-elements: 3.1.0 + html-parse-stringify@4.0.1: {} html-to-image@1.11.13: {} @@ -7156,21 +7108,19 @@ snapshots: dependencies: '@babel/runtime': 7.28.6 - i18next-http-backend@3.0.5: - dependencies: - cross-fetch: 4.1.0 - transitivePeerDependencies: - - encoding + i18next-http-backend@4.0.1: {} - i18next@25.8.16(typescript@6.0.3): - dependencies: - '@babel/runtime': 7.28.6 + i18next@26.3.6(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 + identifier-regex@1.1.0: + dependencies: + reserved-identifiers: 1.2.0 + ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} import-fresh@3.3.1: dependencies: @@ -7188,20 +7138,13 @@ snapshots: internal-slot@1.1.0: dependencies: es-errors: 1.3.0 - hasown: 2.0.3 + hasown: 2.0.2 side-channel: 1.1.0 internmap@2.0.3: {} - is-alphabetical@1.0.4: {} - is-alphabetical@2.0.1: {} - is-alphanumerical@1.0.4: - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - is-alphanumerical@2.0.1: dependencies: is-alphabetical: 2.0.1 @@ -7244,7 +7187,7 @@ snapshots: is-core-module@2.16.1: dependencies: - hasown: 2.0.3 + hasown: 2.0.2 is-data-view@1.0.2: dependencies: @@ -7257,8 +7200,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-decimal@1.0.4: {} - is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -7280,10 +7221,13 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-hexadecimal@1.0.4: {} - is-hexadecimal@2.0.1: {} + is-identifier@1.1.0: + dependencies: + identifier-regex: 1.1.0 + super-regex: 1.1.0 + is-map@2.0.3: {} is-node-process@1.2.0: {} @@ -7302,7 +7246,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.2 is-set@2.0.3: {} @@ -7390,8 +7334,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@2.5.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -7404,18 +7346,11 @@ snapshots: json5@2.2.3: {} - jsonc-eslint-parser@2.4.1: - dependencies: - acorn: 8.15.0 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - semver: 7.7.1 - jsonc-eslint-parser@3.1.0: dependencies: - acorn: 8.16.0 + acorn: 8.17.0 eslint-visitor-keys: 5.0.1 - semver: 7.7.4 + semver: 7.8.5 jsonpointer@5.0.1: {} @@ -7441,54 +7376,54 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.32.0: + lightningcss-android-arm64@1.33.0: optional: true - lightningcss-darwin-arm64@1.32.0: + lightningcss-darwin-arm64@1.33.0: optional: true - lightningcss-darwin-x64@1.32.0: + lightningcss-darwin-x64@1.33.0: optional: true - lightningcss-freebsd-x64@1.32.0: + lightningcss-freebsd-x64@1.33.0: optional: true - lightningcss-linux-arm-gnueabihf@1.32.0: + lightningcss-linux-arm-gnueabihf@1.33.0: optional: true - lightningcss-linux-arm64-gnu@1.32.0: + lightningcss-linux-arm64-gnu@1.33.0: optional: true - lightningcss-linux-arm64-musl@1.32.0: + lightningcss-linux-arm64-musl@1.33.0: optional: true - lightningcss-linux-x64-gnu@1.32.0: + lightningcss-linux-x64-gnu@1.33.0: optional: true - lightningcss-linux-x64-musl@1.32.0: + lightningcss-linux-x64-musl@1.33.0: optional: true - lightningcss-win32-arm64-msvc@1.32.0: + lightningcss-win32-arm64-msvc@1.33.0: optional: true - lightningcss-win32-x64-msvc@1.32.0: + lightningcss-win32-x64-msvc@1.33.0: optional: true - lightningcss@1.32.0: + lightningcss@1.33.0: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 lines-and-columns@1.2.4: {} @@ -7496,6 +7431,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.18.1: {} + lodash.debounce@4.0.8: {} lodash@4.18.1: {} @@ -7511,7 +7448,7 @@ snapshots: fault: 1.0.4 highlight.js: 10.7.3 - lru-cache@11.5.1: {} + lru-cache@11.5.2: {} lru-cache@5.1.1: dependencies: @@ -7530,18 +7467,26 @@ snapshots: source-map-js: 1.2.1 optional: true - magicast@0.5.2: + magicast@0.5.3: dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 source-map-js: 1.2.1 + make-asynchronous@1.1.0: + dependencies: + p-event: 6.0.1 + type-fest: 4.41.0 + web-worker: 1.5.0 + make-dir@4.0.0: dependencies: - semver: 7.8.0 + semver: 7.8.5 markdown-table@3.0.4: {} + marked@14.0.0: {} + math-intrinsics@1.1.0: {} mdast-util-find-and-replace@3.0.2: @@ -7697,6 +7642,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdn-data@2.29.0: {} + memoize-one@6.0.0: {} micromark-core-commonmark@2.0.3: @@ -7900,12 +7847,16 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.7 minimatch@3.1.5: dependencies: brace-expansion: 1.1.13 + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.4 + minimist@1.2.8: {} minipass@7.1.3: {} @@ -7916,43 +7867,46 @@ snapshots: mlly@1.8.0: dependencies: - acorn: 8.16.0 + acorn: 8.17.0 pathe: 2.0.3 pkg-types: 1.3.1 ufo: 1.6.1 - monaco-editor@0.52.2: {} + monaco-editor@0.55.1: + dependencies: + dompurify: 3.2.7 + marked: 14.0.0 ms@2.1.3: {} - msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3): + msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3): dependencies: - '@inquirer/confirm': 5.1.21(@types/node@24.10.3) - '@mswjs/interceptors': 0.41.3 - '@open-draft/deferred-promise': 2.2.0 + '@inquirer/confirm': 6.1.1(@types/node@26.1.2) + '@mswjs/interceptors': 0.41.9 + '@open-draft/deferred-promise': 3.0.0 '@types/statuses': 2.0.6 cookie: 1.1.1 - graphql: 16.13.1 - headers-polyfill: 4.0.3 + graphql: 16.14.2 + headers-polyfill: 5.0.1 is-node-process: 1.2.0 outvariant: 1.4.3 path-to-regexp: 6.3.0 picocolors: 1.1.1 - rettime: 0.10.1 + rettime: 0.11.11 statuses: 2.0.2 strict-event-emitter: 0.5.1 - tough-cookie: 6.0.0 - type-fest: 5.4.4 + tough-cookie: 6.0.2 + type-fest: 5.8.0 until-async: 3.0.2 - yargs: 17.7.2 + yargs: 17.7.3 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - '@types/node' - mute-stream@2.0.0: {} + mute-stream@3.0.0: {} - nanoid@3.3.12: {} + nanoid@3.3.16: {} natural-compare@1.4.0: {} @@ -7960,10 +7914,10 @@ snapshots: neo-async@2.6.2: {} - next-themes@0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + next-themes@0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) node-fetch-native@1.6.7: {} @@ -7973,6 +7927,8 @@ snapshots: node-releases@2.0.38: {} + node-releases@2.0.51: {} + normalize-path@3.0.0: {} nypm@0.5.4: @@ -8020,7 +7976,7 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - obug@2.1.1: {} + obug@2.1.3: {} ohash@1.1.6: {} @@ -8058,6 +8014,10 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -8066,21 +8026,14 @@ snapshots: dependencies: p-limit: 3.1.0 + p-timeout@6.1.4: {} + package-json-from-dist@1.0.1: {} parent-module@1.0.1: dependencies: callsites: 3.1.0 - parse-entities@2.0.0: - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - parse-entities@4.0.2: dependencies: '@types/unist': 2.0.11 @@ -8091,6 +8044,10 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-imports-exports@0.2.4: + dependencies: + parse-statements: 1.0.11 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.29.0 @@ -8098,6 +8055,8 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-statements@1.0.11: {} + path-browserify@1.0.1: {} path-exists@4.0.0: {} @@ -8108,7 +8067,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.1 + lru-cache: 11.5.2 minipass: 7.1.3 path-to-regexp@6.3.0: {} @@ -8127,17 +8086,19 @@ snapshots: picomatch@4.0.4: {} + picomatch@4.0.5: {} + pkg-types@1.3.1: dependencies: confbox: 0.1.8 mlly: 1.8.0 pathe: 2.0.3 - playwright-core@1.60.0: {} + playwright-core@1.62.1: {} - playwright@1.60.0: + playwright@1.62.1: dependencies: - playwright-core: 1.60.0 + playwright-core: 1.62.1 optionalDependencies: fsevents: 2.3.2 @@ -8145,9 +8106,9 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.15: + postcss@8.5.25: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.16 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -8157,7 +8118,7 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@3.8.1: {} + prettier@3.9.6: {} pretty-format@27.5.1: dependencies: @@ -8173,10 +8134,6 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - property-information@5.6.0: - dependencies: - xtend: 4.0.2 - property-information@7.0.0: {} proxy-compare@3.0.1: {} @@ -8189,64 +8146,66 @@ snapshots: punycode@2.3.1: {} + quote-js-string@0.1.0: {} + rc9@2.1.2: dependencies: defu: 6.1.6 destr: 2.0.5 - react-chartjs-2@5.3.1(chart.js@4.5.1)(react@19.2.6): + react-chartjs-2@5.3.1(chart.js@4.5.1)(react@19.2.7): dependencies: chart.js: 4.5.1 - react: 19.2.6 + react: 19.2.7 - react-dom@19.2.6(react@19.2.6): + react-dom@19.2.7(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 scheduler: 0.27.0 - react-hook-form@7.71.2(react@19.2.6): + react-hook-form@7.83.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - react-hotkeys-hook@4.6.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-hotkeys-hook@4.6.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-i18next@16.6.5(i18next@25.8.16(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3): + react-i18next@17.0.11(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3): dependencies: - '@babel/runtime': 7.29.2 - html-parse-stringify: 3.0.1 - i18next: 25.8.16(typescript@6.0.3) - react: 19.2.6 - use-sync-external-store: 1.6.0(react@19.2.6) + '@babel/runtime': 7.29.7 + html-parse-stringify: 4.0.1 + i18next: 26.3.6(typescript@6.0.3) + react: 19.2.7 + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: - react-dom: 19.2.6(react@19.2.6) + react-dom: 19.2.7(react@19.2.7) typescript: 6.0.3 - react-icons@5.6.0(react@19.2.6): + react-icons@5.7.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - react-innertext@1.1.5(@types/react@19.2.15)(react@19.2.6): + react-innertext@1.1.5(@types/react@19.2.17)(react@19.2.7): dependencies: - '@types/react': 19.2.15 - react: 19.2.6 + '@types/react': 19.2.17 + react: 19.2.7 react-is@16.13.1: {} react-is@17.0.2: {} - react-markdown@9.1.0(@types/react@19.2.15)(react@19.2.6): + react-markdown@10.1.0(@types/react@19.2.17)(react@19.2.7): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.2.15 + '@types/react': 19.2.17 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.1 - react: 19.2.6 + react: 19.2.7 remark-parse: 11.0.0 remark-rehype: 11.1.1 unified: 11.0.5 @@ -8255,66 +8214,66 @@ snapshots: transitivePeerDependencies: - supports-color - react-resizable-panels@3.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-resizable-panels@3.0.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-router-dom@7.13.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-router-dom@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-router: 7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-router: 7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - react-router@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: cookie: 1.1.1 - react: 19.2.6 + react: 19.2.7 set-cookie-parser: 2.7.2 optionalDependencies: - react-dom: 19.2.6(react@19.2.6) + react-dom: 19.2.7(react@19.2.7) - react-select@5.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-select@5.10.2(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.29.7 '@emotion/cache': 11.14.0 - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) - '@floating-ui/dom': 1.7.1 - '@types/react-transition-group': 4.4.12(@types/react@19.2.15) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) + '@floating-ui/dom': 1.7.6 + '@types/react-transition-group': 4.4.12(@types/react@19.2.17) memoize-one: 6.0.0 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.15)(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-transition-group: 4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - '@types/react' - supports-color - react-syntax-highlighter@15.6.1(react@19.2.6): + react-syntax-highlighter@16.1.1(react@19.2.7): dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.29.7 highlight.js: 10.7.3 highlightjs-vue: 1.0.0 lowlight: 1.20.0 prismjs: 1.30.0 - react: 19.2.6 - refractor: 3.6.0 + react: 19.2.7 + refractor: 5.0.0 - react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-transition-group@4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.29.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react@19.2.6: {} + react@19.2.7: {} readdirp@3.6.0: dependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 redent@3.0.0: dependencies: @@ -8332,16 +8291,15 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - refractor@3.6.0: + refractor@5.0.0: dependencies: - hastscript: 6.0.0 - parse-entities: 2.0.0 - prismjs: 1.30.0 + '@types/hast': 3.0.4 + '@types/prismjs': 1.26.6 + hastscript: 9.0.1 + parse-entities: 4.0.2 regenerator-runtime@0.14.1: {} - regexp-tree@0.1.27: {} - regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -8351,7 +8309,7 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - regjsparser@0.13.1: + regjsparser@0.13.2: dependencies: jsesc: 3.1.0 @@ -8393,6 +8351,8 @@ snapshots: requireindex@1.1.0: {} + reserved-identifiers@1.2.0: {} + resolve-from@4.0.0: {} resolve@1.22.10: @@ -8407,30 +8367,30 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rettime@0.10.1: {} + rettime@0.11.11: {} robust-predicates@3.0.2: {} - rolldown@1.0.3: + rolldown@1.2.1: dependencies: - '@oxc-project/types': 0.133.0 + '@oxc-project/types': 0.142.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 + '@rolldown/binding-android-arm64': 1.2.1 + '@rolldown/binding-darwin-arm64': 1.2.1 + '@rolldown/binding-darwin-x64': 1.2.1 + '@rolldown/binding-freebsd-x64': 1.2.1 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.1 + '@rolldown/binding-linux-arm64-gnu': 1.2.1 + '@rolldown/binding-linux-arm64-musl': 1.2.1 + '@rolldown/binding-linux-ppc64-gnu': 1.2.1 + '@rolldown/binding-linux-s390x-gnu': 1.2.1 + '@rolldown/binding-linux-x64-gnu': 1.2.1 + '@rolldown/binding-linux-x64-musl': 1.2.1 + '@rolldown/binding-openharmony-arm64': 1.2.1 + '@rolldown/binding-wasm32-wasi': 1.2.1 + '@rolldown/binding-win32-arm64-msvc': 1.2.1 + '@rolldown/binding-win32-x64-msvc': 1.2.1 safe-array-concat@1.1.3: dependencies: @@ -8455,16 +8415,12 @@ snapshots: semver@6.3.1: {} - semver@7.7.1: {} - - semver@7.7.4: {} - - semver@7.8.0: {} - - semver@7.8.1: {} + semver@7.8.5: {} set-cookie-parser@2.7.2: {} + set-cookie-parser@3.1.2: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -8531,8 +8487,6 @@ snapshots: source-map@0.6.1: {} - space-separated-tokens@1.1.5: {} - space-separated-tokens@2.0.2: {} sprintf-js@1.0.3: {} @@ -8543,7 +8497,7 @@ snapshots: statuses@2.0.2: {} - std-env@4.0.0: {} + std-env@4.2.0: {} strict-event-emitter@0.5.1: {} @@ -8628,15 +8582,21 @@ snapshots: stylis@4.2.0: {} + super-regex@1.1.0: + dependencies: + function-timeout: 1.0.2 + make-asynchronous: 1.1.0 + time-span: 5.1.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} - synckit@0.11.12: + synckit@0.11.13: dependencies: - '@pkgr/core': 0.2.9 + '@pkgr/core': 0.3.6 tagged-tag@1.0.0: {} @@ -8648,39 +8608,36 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 + tinybench@2.9.0: {} tinyexec@0.3.2: {} - tinyexec@1.1.1: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + tinyexec@1.2.4: {} tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tinyrainbow@3.1.0: {} - tldts-core@7.0.25: {} + tldts-core@7.4.9: {} - tldts@7.0.25: + tldts@7.4.9: dependencies: - tldts-core: 7.0.25 - - to-fast-properties@2.0.0: {} + tldts-core: 7.4.9 to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - tough-cookie@6.0.0: + tough-cookie@6.0.2: dependencies: - tldts: 7.0.25 + tldts: 7.4.9 tr46@0.0.3: {} @@ -8705,7 +8662,9 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.4.4: + type-fest@4.41.0: {} + + type-fest@5.8.0: dependencies: tagged-tag: 1.0.0 @@ -8742,13 +8701,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3): + typescript-eslint@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/parser': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.3.0(jiti@1.21.7))(typescript@6.0.3) - eslint: 10.3.0(jiti@1.21.7) + '@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3))(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/parser': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.65.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.8.0(jiti@1.21.7))(typescript@6.0.3) + eslint: 10.8.0(jiti@1.21.7) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -8767,7 +8726,7 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@7.16.0: {} + undici-types@8.3.0: {} unified@11.0.5: dependencies: @@ -8810,7 +8769,13 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - uqr@0.1.2: {} + update-browserslist-db@1.2.3(browserslist@4.28.7): + dependencies: + browserslist: 4.28.7 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.3: {} uri-js@4.4.1: dependencies: @@ -8818,24 +8783,24 @@ snapshots: urijs@1.19.11: {} - use-debounce@10.1.0(react@19.2.6): + use-debounce@10.1.1(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.15)(react@19.2.6): + use-isomorphic-layout-effect@1.2.1(@types/react@19.2.17)(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - use-sync-external-store@1.6.0(react@19.2.6): + use-sync-external-store@1.6.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 - usehooks-ts@3.1.1(react@19.2.6): + usehooks-ts@3.1.1(react@19.2.7): dependencies: lodash.debounce: 4.0.8 - react: 19.2.6 + react: 19.2.7 vfile-message@4.0.2: dependencies: @@ -8847,54 +8812,52 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-plugin-css-injected-by-js@3.5.2(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)): + vite-plugin-css-injected-by-js@5.0.2(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)): dependencies: - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) - vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3): + vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0): dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.0.3 + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.25 + rolldown: 1.2.1 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 24.10.3 + '@types/node': 26.1.2 fsevents: 2.3.3 jiti: 1.21.7 - yaml: 2.8.3 - - vitest@4.1.4(@types/node@24.10.3)(@vitest/coverage-v8@4.1.4)(happy-dom@20.8.9)(msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3))(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)): - dependencies: - '@vitest/expect': 4.1.4 - '@vitest/mocker': 4.1.4(msw@2.12.10(@types/node@24.10.3)(typescript@6.0.3))(vite@8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.4 - '@vitest/runner': 4.1.4 - '@vitest/snapshot': 4.1.4 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 - es-module-lexer: 2.0.0 - expect-type: 1.3.0 + yaml: 2.9.0 + + vitest@4.1.10(@types/node@26.1.2)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3))(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(msw@2.15.0(@types/node@26.1.2)(typescript@6.0.3))(vite@8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.0 + expect-type: 1.4.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.3 pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.0.0 + picomatch: 4.0.5 + std-env: 4.2.0 tinybench: 2.9.0 - tinyexec: 1.1.1 - tinyglobby: 0.2.15 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@24.10.3)(jiti@1.21.7)(yaml@2.8.3) + vite: 8.2.0(@types/node@26.1.2)(jiti@1.21.7)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.10.3 - '@vitest/coverage-v8': 4.1.4(vitest@4.1.4) - happy-dom: 20.8.9 + '@types/node': 26.1.2 + '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) + happy-dom: 20.11.1 transitivePeerDependencies: - msw - void-elements@3.1.0: {} - web-worker@1.5.0: {} webidl-conversions@3.0.1: {} @@ -8962,12 +8925,6 @@ snapshots: wordwrap@1.0.0: {} - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -8976,19 +8933,17 @@ snapshots: ws@8.21.0: {} - xtend@4.0.2: {} - y18n@5.0.8: {} yallist@3.1.1: {} yallist@5.0.0: {} - yaml@2.8.3: {} + yaml@2.9.0: {} yargs-parser@21.1.1: {} - yargs@17.7.2: + yargs@17.7.3: dependencies: cliui: 8.0.1 escalade: 3.2.0 @@ -9000,25 +8955,23 @@ snapshots: yocto-queue@0.1.0: {} - yoctocolors-cjs@2.1.3: {} - zod-validation-error@4.0.2(zod@4.3.6): dependencies: zod: 4.3.6 zod@4.3.6: {} - zustand@4.5.7(@types/react@19.2.15)(react@19.2.6): + zustand@4.5.7(@types/react@19.2.17)(react@19.2.7): dependencies: - use-sync-external-store: 1.6.0(react@19.2.6) + use-sync-external-store: 1.6.0(react@19.2.7) optionalDependencies: - '@types/react': 19.2.15 - react: 19.2.6 + '@types/react': 19.2.17 + react: 19.2.7 - zustand@5.0.11(@types/react@19.2.15)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): + zustand@5.0.14(@types/react@19.2.17)(react@19.2.7)(use-sync-external-store@1.6.0(react@19.2.7)): optionalDependencies: - '@types/react': 19.2.15 - react: 19.2.6 - use-sync-external-store: 1.6.0(react@19.2.6) + '@types/react': 19.2.17 + react: 19.2.7 + use-sync-external-store: 1.6.0(react@19.2.7) zwitch@2.0.4: {} diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json index 9038038e10ed2..59a5af4ebc01a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/admin.json @@ -205,6 +205,7 @@ "title": "تخطي" } }, + "parsingFile": "جارٍ تحليل الملف...", "title": "استيراد المتغيرات", "upload": "تحميل ملف JSON", "uploadPlaceholder": "حمل ملف JSON يحتوي علي متغيرات (مثال: {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/assets.json index b92d0f6bf0974..8518405d8a40d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/assets.json @@ -6,21 +6,21 @@ "asset_other": "أصول", "asset_two": "أصلان", "asset_zero": "لا يوجد أي أصل", - "assetStore": { - "add": "إضافة مخزن الأصول", + "assetStateStore": { + "add": "إضافة مخزن حالة الأصل", "clearAll": { - "resource": "كل مخزن الأصول", - "title": "مسح كل مخزن الأصول", - "warning": "سيتم مسح كل مخزن الأصول. ستفقد المهام التي تستخدم هذا المخزن لتنسيق العمل ذاكرتها المحفوظة." + "resource": "كل مخزن حالة الأصل", + "title": "مسح كل مخزن حالة الأصل", + "warning": "سيتم مسح كل مخزن حالة الأصل. ستفقد المهام التي تستخدم هذا المخزن لتنسيق العمل ذاكرتها المحفوظة." }, - "delete": "حذف مخزن الأصول", - "deleteWarning": "سيفقد الأصل إدخال المخزن المحفوظ هذا.", - "edit": "تعديل مخزن الأصول", - "emptyState": "يخزّن مخزن الأصول قيماً مرتبطة بهوية الأصل، وتكون مشتركة عبر جميع تشغيلات Dag. يمكن للعمّال الكتابة إلى مخزن الأصول عبر Task SDK.", + "delete": "حذف مخزن حالة الأصل", + "deleteWarning": "سيفقد الأصل إدخال مخزن الحالة المحفوظ هذا.", + "edit": "تعديل مخزن حالة الأصل", + "emptyState": "يخزّن مخزن حالة الأصل قيماً مرتبطة بهوية الأصل، وتكون مشتركة عبر جميع تشغيلات Dag. يمكن للعمّال الكتابة إلى مخزن حالة الأصل عبر Task SDK.", "lastUpdatedBy": "آخر تحديث بواسطة", "lastUpdatedByApi": "API", "lastUpdatedByWatcher": "المراقب", - "title": "مخزن الأصول" + "title": "مخزن حالة الأصل" }, "consumingDags": "Dags المستهلكة", "consumingTasks": "المهام المستهلكة", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json index c2ab855cbdfb3..9727da74c5dfb 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/common.json @@ -8,6 +8,7 @@ "Variables": "متغيرات" }, "allOperators": "جميع المُشغِّلات", + "allTeams": "جميع الفرق", "appearance": { "appearance": "المظهر", "darkMode": "الوضع الداكن", @@ -77,7 +78,8 @@ "owner": "المالك", "params": "معاملات", "schedule": "جدولة", - "tags": "وسوم" + "tags": "وسوم", + "team": "الفريق" }, "dagId": "معرف Dag", "dagRun": { @@ -92,6 +94,7 @@ "expectedDuration": "المدة المتوقعة", "lastSchedulingDecision": "آخر قرار جدولة", "mappedPartitionKey": "مفتاح التقسيم المعيَّن", + "partitionDate": "تاريخ التقسيم", "partitionKey": "مفتاح التقسيم", "queuedAt": "في الطابور في", "runAfter": "تشغيل بعد", @@ -169,6 +172,9 @@ "selectDateRange": "اختر نطاق التاريخ", "startTime": "وقت البدء" }, + "fullscreen": { + "tooltip": "اضغط {{hotkey}} لملء الشاشة" + }, "generateToken": "توليد رمز", "key": "المفتاح", "logicalDate": "التاريخ المنطقي", @@ -200,9 +206,12 @@ "note": { "add": "إضافة", "dagRun": "تشغيل Dag", + "edit": "تعديل الملاحظة", "label": "وسم", "placeholder": "أضف ملاحظة...", - "taskInstance": "مثيل المهمة" + "preview": "معاينة", + "taskInstance": "مثيل المهمة", + "write": "كتابة" }, "overallStatus": "الحالة العامة", "partitionedDagRun_few": "تشغيلات Dag مُجزأة", @@ -220,6 +229,23 @@ "pendingDagRun_other": "{{count}} تشغيل Dag مُعلّق", "pendingDagRun_two": "تشغيلا Dag مُعلّقان", "pendingDagRun_zero": "لا توجد تشغيلات Dag مُعلّقة", + "presetFilters": { + "deleteTitle": "حذف الفلتر المُعدّ مسبقاً", + "deleteWarning": "تُحفظ الفلاتر المُعدّة مسبقاً في هذا المتصفح فقط.", + "duplicate": "الفلتر المُعدّ مسبقاً \"{{name}}\" يحفظ هذا الإعداد نفسه بالفعل.", + "empty": "لا توجد فلاتر مُعدّة مسبقاً بعد", + "info": { + "default": "ثبّت فلتراً مُعدّاً مسبقاً كافتراضي ليُطبَّق تلقائياً عند فتح هذه الصفحة دون أي فلاتر.", + "save": "احفظ الفلاتر والترتيب الحالية كفلتر مُعدّ مسبقاً باسم، ثم عُد إليه في أي وقت.", + "storage": "تُحفظ الفلاتر المُعدّة مسبقاً في هذا المتصفح." + }, + "namePlaceholder": "اسم الفلتر المُعدّ مسبقاً", + "nothingToSave": "لا يوجد ما يُحفظ. طبّق فلاتر أو ترتيباً لحفظ فلتر مُعدّ مسبقاً.", + "save": "حفظ", + "setDefault": "تعيين كافتراضي", + "title": "الفلاتر المُعدّة مسبقاً", + "unsetDefault": "إلغاء التعيين كافتراضي" + }, "reset": "إعادة تعيين", "runId": "معرف التشغيل", "runTypes": { @@ -251,6 +277,47 @@ }, "selectLanguage": "اختيار اللغة", "selected": "محدد", + "shortcuts": { + "categories": { + "code": "الكود", + "dagView": "عرض Dag", + "filters": "الفلاتر", + "global": "عام", + "logs": "السجلات", + "navigation": "التنقل", + "runActions": "إجراءات التشغيل والمهام", + "search": "البحث" + }, + "descriptions": { + "clearRun": "مسح $t(dagRun_one)", + "clearTaskInstance": "مسح $t(taskInstance_one)", + "downloadLogs": "تنزيل السجلات", + "focusFilterSearch": "التركيز على بحث الفلاتر", + "focusLogSearch": "البحث في السجلات", + "focusSearch": "التركيز على البحث", + "markRunFailed": "تعليم $t(dagRun_one) كفاشل", + "markRunSuccess": "تعليم $t(dagRun_one) كناجح", + "markTaskFailed": "تعليم $t(task_one) كفاشلة", + "markTaskGroupFailed": "تعليم $t(taskGroup_one) كفاشلة", + "markTaskGroupSuccess": "تعليم $t(taskGroup_one) كناجحة", + "markTaskSuccess": "تعليم $t(task_one) كناجحة", + "navigateTasks": "التنقل بين $t(task_other)", + "openGraphFilters": "فتح فلاتر الرسم البياني", + "scrollBottom": "التمرير إلى الأسفل", + "scrollTop": "التمرير إلى الأعلى", + "searchDags": "البحث في $t(dag_other)", + "showHelp": "إظهار $t(shortcuts.title)", + "toggleExpand": "توسيع أو طي جميع المجموعات", + "toggleFullscreen": "تبديل ملء الشاشة", + "toggleGraphGrid": "التبديل بين عرض الرسم البياني والشبكة", + "toggleSource": "تبديل المصدر", + "toggleTaskGroup": "توسيع أو طي $t(taskGroup_one)", + "toggleTimestamp": "تبديل الأختام الزمنية", + "toggleWrap": "تبديل $t(wrap.wrap)" + }, + "empty": "لا تتوفر اختصارات لوحة مفاتيح في هذه الصفحة.", + "title": "اختصارات لوحة المفاتيح" + }, "showDetailsPanel": "إظهار لوحة التفاصيل", "signedInAs": "تم تسجيل الدخول باسم", "source": { @@ -299,6 +366,7 @@ "from": "من", "maxActiveRuns": "الحد الأقصى للتشغيلات النشطة", "noTagsFound": "لم يتم العثور على وسوم", + "noTeamsFound": "لم يتم العثور على فرق", "tagMode": { "all": "الكل", "any": "اي شيء" @@ -333,10 +401,12 @@ "taskGroup_zero": "لا توجد مجموعات مهام", "taskId": "معرف المهمة", "taskInstance": { + "additionalAttributes": "سمات إضافية لمثيل المهمة", "dagVersion": "إصدار الDag", "executor": "منفذ", "executorConfig": "تكوين المنفذ", "hostname": "اسم المضيف", + "id": "المعرف", "maxTries": "الحد الأقصى للمحاولات", "pid": "معرف العملية", "pool": "مجموعة الموارد", @@ -346,11 +416,13 @@ "queuedWhen": "في الطابور في", "renderedMapIndex": "فهرس الخريطة المعروض", "scheduledWhen": "مجدول في", + "trigger": "المُحفِّز", "triggerer": { "assigned": "مُطلِق مُخصص", "class": "فئة المُطلِق", "createdAt": "تاريخ إنشاء المُطلِق", "id": "معرف المُطلِق", + "job": "وظيفة المُطلِق", "latestHeartbeat": "آخر نبضة للمُطلِق", "title": "معلومات المُطلِق" }, diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json index f958e8798ded2..341396cfdc216 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/components.json @@ -81,6 +81,7 @@ "lastTaskInstance_other": "آخر {{count}} مثيل مهمة", "lastTaskInstance_two": "آخر مثيلين مهمة", "lastTaskInstance_zero": "لا يوجد أي مثيل مهمة", + "medianTotalDuration": "الإجمالي: {{duration}}", "queuedDuration": "مدة الانتظار في الطابور", "runAfter": "تشغيل بعد", "runDuration": "مدة التشغيل" @@ -169,6 +170,7 @@ "loading": "جارٍ تحميل معلومات Dag...", "loadingFailed": "فشل تحميل معلومات Dag. يرجى المحاولة مرة أخرى.", "manualRunDenied": "التشغيلات اليدوية غير مسموح بها لهذا الـDag", + "partitionKeyHelp": "اختياري - ينطبق فقط على Dags المُجزأة", "runIdHelp": "اختياري - سيتم توليده تلقائيًا إذا لم يتم توفيره.", "selectDescription": "تشغيل عملية واحدة من هذا Dag", "selectLabel": "تشغيلة واحدة", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json index 44d0b882563d1..88e762693b63e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json @@ -118,11 +118,6 @@ "viewInExternal": "عرض السجلات في {{name}} (المحاولة {{attempt}})", "warning": "تحذير" }, - "navigation": { - "navigation": "التنقل: {{arrow}}", - "openGraphFilters": "مرشحات المهام: Ctrl+Shift+F", - "toggleGroup": "تبديل المجموعة: المسافة" - }, "notFound": { "back": "رجوع", "backToDags": "العودة إلى Dags", @@ -264,7 +259,7 @@ "runs": "تشغيلات", "storage": "التخزين", "taskInstances": "مثيلات المهام", - "taskStore": "مخزن المهام", + "taskStateStore": "مخزن حالة المهمة", "tasks": "المهام", "xcom": "XCom" }, @@ -272,17 +267,17 @@ "collapseAll": "طي جميع مجموعات المهام", "expandAll": "توسيع جميع مجموعات المهام" }, - "taskStore": { - "add": "إضافة مخزن المهام", + "taskStateStore": { + "add": "إضافة مخزن حالة المهمة", "clearAll": { - "resource": "كل مخزن المهام", - "title": "مسح كل مخزن المهام", - "warning": "سيتم مسح كل مخزن المهام. لن تتمكن المهام التي تستخدم هذا المخزن لتتبع العمل الخارجي من الاستئناف دون إعادة التشغيل من البداية." + "resource": "كل مخزن حالة المهمة", + "title": "مسح كل مخزن حالة المهمة", + "warning": "سيتم مسح كل مخزن حالة المهمة. لن تتمكن المهام التي تستخدم هذا المخزن لتتبع العمل الخارجي من الاستئناف دون إعادة التشغيل من البداية." }, - "delete": "حذف مخزن المهام", + "delete": "حذف مخزن حالة المهمة", "deleteWarning": "ستفقد المهمة هذه الذاكرة المحفوظة. إذا كانت المهمة تستخدم هذا المفتاح لتتبع عمل خارجي (مثل معرّف وظيفة خارجية)، فلن تتمكن من استئنافه.", - "edit": "تعديل مخزن المهام", - "emptyStore": "يخزّن مخزن المهام قيماً تستمر عبر إعادات المحاولة. يمكن للعمّال الكتابة إلى مخزن المهام عبر Task SDK.", + "edit": "تعديل مخزن حالة المهمة", + "emptyStore": "يخزّن مخزن حالة المهمة قيماً تستمر عبر إعادات المحاولة. يمكن للعمّال الكتابة إلى مخزن حالة المهمة عبر Task SDK.", "expiresAt": { "column": "تنتهي الصلاحية في", "custom": "مخصص", @@ -290,6 +285,6 @@ "label": "انتهاء الصلاحية", "never": "أبداً" }, - "title": "مخزن المهام" + "title": "مخزن حالة المهمة" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dags.json index 7cdbce8613301..951e62adaeddc 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "جميع أنواع التشغيلات", "allStates": "جميع الحالات", + "anyRunState": "أي تشغيل", "favorite": { "all": "الكل", "favorite": "تفضيل", "unfavorite": "إلغاء التفضيل" }, + "lastRunState": "آخر تشغيل", "paused": { "active": "مفعّل", "all": "الكل", @@ -76,6 +78,11 @@ "upstream": "المهام السابقة" } }, + "runStateCounts": { + "label": "حالات التشغيل", + "loading": "جارٍ تحميل أعداد حالات التشغيل", + "tooltip": "{{state}}: {{formattedCount}} — انقر لتصفية التشغيلات" + }, "search": { "advanced": "بحث متقدم", "clear": " مسح", @@ -88,6 +95,10 @@ "asc": "الترتيب حسب اسم العرض (A-Z)", "desc": "الترتيب حسب اسم العرض (Z-A)" }, + "lastRunAfter": { + "asc": "الترتيب حسب تشغيل بعد لآخر تشغيل (الأقدم-الأحدث)", + "desc": "الترتيب حسب تشغيل بعد لآخر تشغيل (الأحدث-الأقدم)" + }, "lastRunStartDate": { "asc": "الترتيب حسب تاريخ بداية آخر تشغيل (الأقدم-الأحدث)", "desc": "الترتيب حسب تاريخ بداية آخر تشغيل (الأحدث-الأقدم)" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dashboard.json index 63004b63c69d6..d1d91e037804e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dashboard.json @@ -1,4 +1,26 @@ { + "alerts": { + "seeLessContext": "عرض أقل", + "seeMoreContext": "عرض المزيد", + "showMoreAlerts_few": "+{{count}} تنبيهات إضافية", + "showMoreAlerts_many": "+{{count}} تنبيهاً إضافياً", + "showMoreAlerts_one": "+{{count}} تنبيه إضافي", + "showMoreAlerts_other": "+{{count}} تنبيه إضافي", + "showMoreAlerts_two": "+{{count}} تنبيهان إضافيان", + "showMoreAlerts_zero": "لا توجد تنبيهات إضافية" + }, + "deadlines": { + "pending": { + "empty": "لا توجد مواعيد نهائية قادمة", + "title": "القادمة" + }, + "recentlyMissed": { + "empty": "لا توجد مواعيد نهائية فائتة", + "title": "المواعيد النهائية الفائتة" + }, + "showMore": "عرض المزيد", + "title": "المواعيد النهائية" + }, "deferredSlotsNotCounted": "المؤجّلة غير محتسبة ضمن الحصص: {{count}}", "deferredSlotsNotCountedTooltip": "المهام المؤجّلة الظاهرة داخل الشريط تُحتسب ضمن حصص مجموعة الموارد. المهام المؤجّلة الظاهرة أسفل الشريط تأتي من مجموعات موارد لا تحتسب المهام المؤجّلة ضمن الحصص.", "favorite": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/ar/hitl.json index 24127decf4ecf..fdee256421b01 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/hitl.json @@ -32,6 +32,20 @@ "success": "تمت الاستجابة بنجاح ل{{taskId}}", "title": "مثيل مهمة يدوي - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "اختر إجراءً مطلوباً لعرض التفاصيل" + }, + "list": { + "completedRequiredActions": "الإجراءات المطلوبة المكتملة ({{count}})", + "loadError": "تعذّر تحميل الإجراءات المطلوبة", + "loadingActions": "جارٍ تحميل الإجراءات المطلوبة...", + "pendingRequiredActions": "الإجراءات المطلوبة قيد الانتظار ({{count}})" + }, + "openReviewDrawer": "فتح لوحة المراجعة", + "pageLimitHint": "تُعرض هنا الإجراءات الأولى فقط. استخدم \"$t(review.viewAll)\" لعرضها جميعاً.", + "viewAll": "عرض جميع الإجراءات المطلوبة" + }, "state": { "approvalReceived": "تم استلام الموافقة", "approvalRequired": "تتطلب موافقة", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json index c90bc964f6df5..3cd77f612a7dc 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "Veure els registres a {{name}} (intent {{attempt}})", "warning": "ADVERTIMENT" }, - "navigation": { - "navigation": "Navegació: Shift+{{arrow}}", - "openGraphFilters": "Filtres de tasques: Ctrl+Maj+F", - "toggleGroup": "Alternar grup: Espai" - }, "notFound": { "back": "Enrere", "backToDags": "Tornar als Dags", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json index 829a1aaac4d5c..d48f59856f61f 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "Protokoll in {{name}} (Versuch {{attempt}}) ansehen", "warning": "WARNING" }, - "navigation": { - "navigation": "Navigation: Umschalttaste+{{arrow}}", - "openGraphFilters": "Task-Filter: Strg+Umschalt+F", - "toggleGroup": "Gruppen umschalten: Leertaste" - }, "notFound": { "back": "Zurück", "backToDags": "Zurück zu Dags", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json index b0769021c9fcd..179a725797210 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/admin.json @@ -3,6 +3,7 @@ "description": "Περιγραφή", "key": "Κλειδί", "name": "Όνομα", + "team": "Ομάδα", "value": "Τιμή" }, "config": { @@ -49,6 +50,12 @@ "searchPlaceholder": "Αναζήτηση Συνδέσεων", "test": "Δοκιμή Σύνδεσης", "testDisabled": "Η λειτουργία δοκιμής σύνδεσης είναι απενεργοποιημένη. Επικοινωνήστε με τον διαχειριστή για να την ενεργοποιήσει.", + "testError": { + "title": "Αποτυχημένη Δοκιμή Σύνδεσης" + }, + "testSuccess": { + "title": "Επιτυχής Δοκιμή Σύνδεσης" + }, "typeMeta": { "error": "Αποτυχία ανάκτησης μεταδεδομένων τύπου σύνδεσης", "standardFields": { @@ -74,6 +81,23 @@ "formActions": { "save": "Αποθήκευση" }, + "jobs": { + "columns": { + "executorClass": "Κλάση Εκτελεστή", + "hostname": "Όνομα Υπολογιστή", + "id": "ID", + "jobType": "Τύπος Διεργασίας", + "latestHeartbeat": "Πιο Πρόσφατος Παλμός", + "unixname": "Όνομα Unix" + }, + "filters": { + "allStates": "Όλες οι Καταστάσεις", + "allTypes": "Όλοι οι Τύποι", + "dagProcessorJob": "DagProcessorJob", + "schedulerJob": "SchedulerJob", + "triggererJob": "TriggererJob" + } + }, "plugins": { "columns": { "source": "Πηγή" @@ -84,19 +108,20 @@ }, "pools": { "add": "Προσθήκη Pool", - "deferredSlotsIncluded": "Συμπεριλαμβάνονται Αναβληθέντα Slots", + "deferredSlotsIncluded": "Συμπεριλαμβάνονται Αναβληθείσες Θέσεις", "delete": { "title": "Διαγραφή Pool", "warning": "Αυτό θα αφαιρέσει όλα τα μεταδεδομένα που σχετίζονται με το pool και μπορεί να επηρεάσει εργασίες που το χρησιμοποιούν." }, "edit": "Επεξεργασία Pool", "form": { - "checkbox": "Επιλέξτε για να συμπεριλάβετε αναβληθείσες εργασίες στον υπολογισμό των διαθέσιμων slots του pool", + "checkbox": "Επιλέξτε για να συμπεριλάβετε αναβληθείσες εργασίες στον υπολογισμό των διαθέσιμων θέσεων του pool", "description": "Περιγραφή", "includeDeferred": "Συμπερίληψη Αναβληθέντων", "nameMaxLength": "Το όνομα μπορεί να περιέχει έως 256 χαρακτήρες", "nameRequired": "Το όνομα είναι υποχρεωτικό", - "slots": "Slots" + "slots": "Θέσεις", + "slotsHelperText": "Χρησιμοποιήστε -1 για απεριόριστες θέσεις." }, "noPoolsFound": "Δεν βρέθηκαν pools", "pool_one": "Pool", @@ -152,6 +177,7 @@ "title": "Παράλειψη" } }, + "parsingFile": "Ανάλυση αρχείου...", "title": "Εισαγωγή Μεταβλητών", "upload": "Ανέβασμα Αρχείου JSON", "uploadPlaceholder": "Ανεβάστε ένα αρχείο JSON που περιέχει μεταβλητές (π.χ., {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json index 27d565581af85..ea70910b8d717 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/assets.json @@ -1,5 +1,25 @@ { + "additional_data": "Επιπλέον Δεδομένα", + "asset_many": "Οντότητες", + "asset_one": "Οντότητα", + "assetStateStore": { + "add": "Προσθήκη Αποθήκης Καταστάσεων Οντότητας", + "clearAll": { + "resource": "ολόκληρη η αποθήκη καταστάσεων οντότητας", + "title": "Εκκαθάριση ολόκληρης της Αποθήκης Καταστάσεων Οντότητας", + "warning": "Ολόκληρη η αποθήκη καταστάσεων οντότητας θα διαγραφεί. Οι εργασίες που χρησιμοποιούν αυτήν την αποθήκη για τον συντονισμό τους θα χάσουν την διατηρημένη μνήμη τους." + }, + "delete": "Διαγραφή Αποθήκης Καταστάσεων Οντότητας", + "deleteWarning": "Η οντότητα θα χάσει αυτή την αποθηκευμένη εγγραφή κατάστασης.", + "edit": "Επεξεργασία Αποθήκης Καταστάσεων Οντότητας", + "emptyState": "Η αποθήκη κατάστασης οντότητας αποθηκεύει τιμές που ανήκουν στην ταυτότητα μιας οντότητας και μοιράζονται σε όλες τις Dag εκτελέσεις. Οι εργάτες μπορούν να γράψουν στην αποθήκη κατάστασης οντότητας μέσω του Task SDK.", + "lastUpdatedBy": "Τελευταία Ενημέρωση Από", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Παρατηρητής", + "title": "Αποθήκη Καταστάσεων Οντότητας" + }, "consumingDags": "Καταναλωτικά Dags", + "consumingTasks": "Καταναλωτικές Εργασίες", "createEvent": { "button": "Δημιουργία Συμβάντος", "manual": { @@ -21,10 +41,14 @@ }, "title": "Δημιουργία Συμβάντος Οντότητας για {{name}}" }, + "events": "Συμβάντα", + "extra": "Επιπλέον", "group": "Ομάδα", "lastAssetEvent": "Τελευταίο Συμβάν Οντότητας", "name": "Όνομα", "producingTasks": "Παραγωγή Εργασιών", "scheduledDags": "Προγραμματισμένα Dags", - "searchPlaceholder": "Αναζήτηση Οντοτήτων" + "scheduling": "Προγραμματισμός", + "searchPlaceholder": "Αναζήτηση Οντοτήτων", + "taskDependencies": "Εξαρτήσεις Εργασιών" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json index 75c155eddb290..a63c8fa93618a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/browse.json @@ -11,12 +11,54 @@ }, "title": "Καταγραφή Ελέγχου" }, + "deadlines": { + "columns": { + "alertName": "Όνομα Ειδοποίησης", + "deadlineTime": "Χρόνος Προθεσμίας", + "status": "Κατάσταση" + }, + "deadline_one": "Προθεσμία", + "deadline_other": "Προθεσμίες", + "filters": { + "status": "Κατάσταση", + "statusOptions": { + "all": "Όλες", + "missed": "Χαμένες", + "pending": "Σε Εκκρεμότητα" + } + }, + "title": "Προθεσμίες" + }, "xcom": { + "add": { + "error": "Αποτυχία προσθήκης XCom", + "errorTitle": "Σφάλμα", + "success": "Επιτυχία προσθήκης XCom", + "successTitle": "Το XCom Προστέθηκε", + "title": "Προσθήκη XCom" + }, "columns": { "dag": "Dag", "key": "Κλειδί", "value": "Τιμή" }, - "title": "XCom" + "delete": { + "error": "Αποτυχία διαγραφής XCom", + "errorTitle": "Σφάλμα", + "success": "Επιτυχία διαγραφής XCom", + "successTitle": "Το XCom Διαγράφηκε", + "title": "Διαγραφή XCom", + "warning": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτό το XCom; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί." + }, + "edit": { + "error": "Αποτυχία ενημέρωσης XCom", + "errorTitle": "Σφάλμα", + "success": "Επιτυχία ενημέρωσης XCom", + "successTitle": "Το XCom Ενημερώθηκε", + "title": "Επεξεργασία XCom" + }, + "key": "Κλειδί", + "title": "XCom", + "value": "Τιμή" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json index 297891a3918d1..5abcf2f11adcf 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/common.json @@ -8,6 +8,7 @@ "Variables": "Μεταβλητές" }, "allOperators": "Όλοι οι Τελεστές", + "allTeams": "Όλες οι Ομάδες", "appearance": { "appearance": "Εμφάνιση", "darkMode": "Σκούρο Θέμα", @@ -18,15 +19,21 @@ "asset_other": "Οντότητες", "assetEvent_one": "Συμβάν Οντότητας", "assetEvent_other": "Συμβάντα Οντοτήτων", + "assetInactive": { + "tooltip": "Η ανάντη οντότητα έχει απενεργοποιηθεί· ο προγραμματιστής αναστέλλει την αξιολόγηση κατατμήσεων μέχρι να επανενεργοποιηθεί." + }, "backfill_one": "Backfill", "backfill_other": "Backfills", "browse": { "auditLog": "Καταγραφή Ελέγχου", + "deadlines": "Προθεσμίες", + "jobs": "Διεργασίες", "requiredActions": "Απαιτούμενες Ενέργειες", "xcoms": "XComs" }, "collapseAllExtra": "Σύμπτυξη όλων των επιπλέον json", "collapseDetailsPanel": "Σύμπτυξη Πίνακα Λεπτομερειών", + "consumingAsset": "Καταναλωτική Οντότητα", "createdAssetEvent_one": "Δημιουργήθηκε Συμβάν Οντότητας", "createdAssetEvent_other": "Δημιουργήθηκαν Συμβάντα Οντοτήτων", "dag_one": "Dag", @@ -51,7 +58,8 @@ "owner": "Ιδιοκτήτης", "params": "Παράμετροι", "schedule": "Πρόγραμμα", - "tags": "Ετικέτες" + "tags": "Ετικέτες", + "team": "Ομάδα" }, "dagId": "Dag ID", "dagRun": { @@ -65,6 +73,9 @@ }, "expectedDuration": "Αναμενόμενη Διάρκεια", "lastSchedulingDecision": "Τελευταία Απόφαση Προγραμματισμού", + "mappedPartitionKey": "Χαρτογραφημένο Κλειδί Κατάτμησης", + "partitionDate": "Ημερομηνία Κατάτμησης", + "partitionKey": "Κλειδί Κατάτμησης", "queuedAt": "Σε Ουρά Στις", "runAfter": "Εκτέλεση Μετά", "runType": "Τύπος Εκτέλεσης", @@ -78,21 +89,39 @@ "dagWarnings": "Προειδοποιήσεις/Σφάλματα Dag", "defaultToGraphView": "Προεπιλογή σε γραφική προβολή", "defaultToGridView": "Προεπιλογή σε πλέγμα", + "delete": "Διαγραφή", + "diff": "Διαφορές", + "diffCompareWith": "Σύγκριση με", + "diffExit": "Έξοδος από τις Διαφορές", + "diffSelectVersionToCompare": "Επιλέξτε έκδοση για σύγκριση", "direction": "Κατεύθυνση", "docs": { "documentation": "Τεκμηρίωση", "githubRepo": "Αποθετήριο GitHub", "restApiReference": "REST API Αναφορά" }, + "download": { + "download": "Λήψη", + "hotkey": "d", + "tooltip": "Πατήστε {{hotkey}} για λήψη των καταγραφών" + }, "duration": "Διάρκεια", + "edit": "Επεξεργασία", "endDate": "Ημερομηνία Λήξης", "error": { "back": "Πίσω", "defaultMessage": "Παρουσιάστηκε απρόσμενο σφάλμα", "home": "Αρχική", + "invalidUrl": "Η σελίδα δεν βρέθηκε. Ελέγξτε τη διεύθυνση URL και δοκιμάστε ξανά.", "notFound": "Η σελίδα δεν βρέθηκε", "title": "Σφάλμα" }, + "errors": { + "forbidden": { + "description": "Δεν έχετε δικαίωμα να εκτελέσετε αυτήν την ενέργεια.", + "title": "Άρνηση Πρόσβασης" + } + }, "expand": { "collapse": "Σύμπτυξη", "expand": "Ανάπτυξη", @@ -110,22 +139,33 @@ "filters": { "durationFrom": "Διάρκεια Από", "durationTo": "Διάρκεια Έως", + "endTime": "Ώρα Λήξης", "logicalDateFrom": "Λογική Ημερομηνία Από", "logicalDateTo": "Λογική Ημερομηνία Έως", "runAfterFrom": "Εκτέλεση Μετά Από", - "runAfterTo": "Εκτέλεση Μετά Έως" + "runAfterTo": "Εκτέλεση Μετά Έως", + "searchAsset": "Αναζήτηση Οντότητας", + "selectDateRange": "Επιλέξτε Εύρος Ημερομηνιών", + "startTime": "Ώρα Έναρξης" }, + "fullscreen": { + "tooltip": "Πατήστε {{hotkey}} για πλήρη οθόνη" + }, + "generateToken": "Δημιουργία Token", + "key": "Κλειδί", "logicalDate": "Λογική Ημερομηνία", "logout": "Αποσύνδεση", "logoutConfirmation": "Πρόκειται να αποσυνδεθείτε από την εφαρμογή.", "mapIndex": "Δείκτης Χάρτη", "modal": { + "add": "Προσθήκη", "cancel": "Ακύρωση", "confirm": "Επιβεβαίωση", "delete": { "button": "Διαγραφή", - "confirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε το {{resourceName}}; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί." - } + "confirmation": "Είστε σίγουροι ότι θέλετε να διαγράψετε {{resourceName}}; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί." + }, + "save": "Αποθήκευση" }, "nav": { "admin": "Διαχείριση", @@ -142,22 +182,42 @@ "note": { "add": "Προσθήκη σημείωσης", "dagRun": "Σημείωση Εκτέλεσης Dag", + "edit": "Επεξεργασία σημείωσης", "label": "Σημείωση", "placeholder": "Προσθέστε μια σημείωση...", - "taskInstance": "Σημείωση Εκτέλεσης Εργασίας" + "preview": "Προεπισκόπηση", + "taskInstance": "Σημείωση Εκτέλεσης Εργασίας", + "write": "Σύνταξη" }, - "pools": { - "deferred": "Αναβληθέν", - "open": "Ανοιχτό", - "pools_one": "pool", - "pools_other": "pools", - "queued": "Σε Ουρά", - "running": "Εκτελείται", - "scheduled": "Προγραμματισμένο" + "overallStatus": "Συνολική Κατάσταση", + "partitionedDagRun_one": "Εκτέλεση Dag με Κατάτμηση", + "partitionedDagRun_other": "Εκτελέσεις Dag με Κατάτμηση", + "partitionedDagRunDetail": { + "receivedAssetEvents": "Ληφθέντα Συμβάντα Οντότητας" + }, + "pendingDagRun_one": "{{count}} Εκκρεμής Εκτέλεση Dag", + "pendingDagRun_other": "{{count}} Εκκρεμείς Εκτελέσεις Dag", + "presetFilters": { + "deleteTitle": "Διαγραφή προκαθορισμένου φίλτρου", + "deleteWarning": "Τα προκαθορισμένα φίλτρα αποθηκεύονται μόνο στο παρόν πρόγραμμα περιήγησης.", + "duplicate": "Το προκαθορισμένο φίλτρο «{{name}}» αποθηκεύει ήδη ακριβώς αυτήν τη διαμόρφωση.", + "empty": "Δεν υπάρχουν προκαθορισμένα φίλτρα", + "info": { + "default": "Καρφιτσώστε ένα προκαθορισμένο φίλτρο ως προεπιλογή και θα εφαρμόζεται αυτόματα όταν φορτώνετε αυτήν τη σελίδα χωρίς ενεργά φίλτρα.", + "save": "Αποθηκεύστε τα τρέχοντα φίλτρα και την ταξινόμηση ως προκαθορισμένο φίλτρο με όνομα, και έπειτα επιστρέψτε σε αυτό όποτε θέλετε.", + "storage": "Τα προκαθορισμένα φίλτρα αποθηκεύονται στο παρόν πρόγραμμα περιήγησης." + }, + "namePlaceholder": "Όνομα προκαθορισμένου φίλτρου", + "nothingToSave": "Δεν υπάρχει τίποτα προς αποθήκευση. Εφαρμόστε φίλτρα ή ταξινόμηση για να αποθηκεύσετε ένα προκαθορισμένο φίλτρο.", + "save": "Αποθήκευση", + "setDefault": "Ορισμός ως προεπιλογή", + "title": "Προκαθορισμένα Φίλτρα", + "unsetDefault": "Κατάργηση προεπιλογής" }, "reset": "Επαναφορά", "runId": "ID Εκτέλεσης", "runTypes": { + "asset_materialization": "Υλοποίηση Οντότητας", "asset_triggered": "Ενεργοποιήθηκε από Οντότητα", "backfill": "Backfill", "manual": "Χειροκίνητο", @@ -170,6 +230,12 @@ }, "tooltip": "Πατήστε {{hotkey}} για κύλιση προς τα {{direction}}" }, + "search": { + "advanced": { + "description": "Αντιστοίχιση οπουδήποτε μέσα στην τιμή (αναζήτηση υπο-συμβολοσειράς). Είναι πιο αργή σε μεγάλες εγκαταστάσεις, επειδή δεν μπορεί να χρησιμοποιήσει το προεπιλεγμένο B-tree ευρετήριο. Για λεπτομέρειες, δείτε την ενότητα της τεκμηρίωσης για τα προσαρμοσμένα ευρετήρια μεταδεδομένων.", + "title": "Αντιστοίχιση οπουδήποτε" + } + }, "security": { "actions": "Ενέργειες", "permissions": "Δικαιώματα", @@ -178,7 +244,50 @@ "users": "Χρήστες" }, "selectLanguage": "Επιλογή Γλώσσας", + "selected": "Επιλεγμένα", + "shortcuts": { + "categories": { + "code": "Κώδικας", + "dagView": "Προβολή Dag", + "filters": "Φίλτρα", + "global": "Καθολικά", + "logs": "Καταγραφές", + "navigation": "Πλοήγηση", + "runActions": "Ενέργειες Εκτελέσεων & Εργασιών", + "search": "Αναζήτηση" + }, + "descriptions": { + "clearRun": "Εκκαθάριση Εκτέλεσης Dag", + "clearTaskInstance": "Εκκαθάριση Εκτέλεσης Εργασίας", + "downloadLogs": "Λήψη καταγραφών", + "focusFilterSearch": "Εστιασμένη αναζήτηση με φίλτρα", + "focusLogSearch": "Αναζήτηση στις καταγραφές", + "focusSearch": "Εστιασμένη αναζήτηση", + "markRunFailed": "Σήμανση Εκτέλεσης Dag ως αποτυχημένης", + "markRunSuccess": "Σήμανση Εκτέλεσης Dag ως επιτυχημένης", + "markTaskFailed": "Σήμανση Εργασίας ως αποτυχημένης", + "markTaskGroupFailed": "Σήμανση Ομάδας Εργασιών ως αποτυχημένης", + "markTaskGroupSuccess": "Σήμανση Ομάδας Εργασιών ως επιτυχημένης", + "markTaskSuccess": "Σήμανση Εργασίας ως επιτυχημένης", + "navigateTasks": "Πλοήγηση στις Εργασίες", + "openGraphFilters": "Άνοιγμα φίλτρων γραφήματος", + "scrollBottom": "Κύλιση στο τέλος", + "scrollTop": "Κύλιση στην αρχή", + "searchDags": "Αναζήτηση Dags", + "showHelp": "Εμφάνιση Συντομεύσεων Πληκτρολογίου", + "toggleExpand": "Ανάπτυξη ή σύμπτυξη όλων των ομάδων", + "toggleFullscreen": "Εναλλαγή πλήρους οθόνης", + "toggleGraphGrid": "Εναλλαγή προβολής γραφήματος / πλέγματος", + "toggleSource": "Εναλλαγή πηγαίου", + "toggleTaskGroup": "Ανάπτυξη ή σύμπτυξη Ομάδας Εργασιών", + "toggleTimestamp": "Εναλλαγή χρονικών σημάνσεων", + "toggleWrap": "Εναλλαγή αναδίπλωσης" + }, + "empty": "Δεν υπάρχουν διαθέσιμες συντομεύσεις πληκτρολογίου σε αυτήν τη σελίδα.", + "title": "Συντομεύσεις Πληκτρολογίου" + }, "showDetailsPanel": "Εμφάνιση Πίνακα Λεπτομερειών", + "signedInAs": "Συνδεδεμένος ως", "source": { "hide": "Απόκρυψη Πηγαίου Κώδικα", "hotkey": "s", @@ -189,10 +298,12 @@ "startDate": "Ημερομηνία Έναρξης", "state": "Κατάσταση", "states": { + "awaiting_input": "Αναμονή Εισόδου", "deferred": "Αναβληθέν", "failed": "Αποτυχία", "no_status": "Χωρίς Κατάσταση", "none": "Χωρίς Κατάσταση", + "open": "Ανοιχτό", "planned": "Προγραμματισμένο", "queued": "Σε Ουρά", "removed": "Αφαιρέθηκε", @@ -215,27 +326,39 @@ "from": "Από", "maxActiveRuns": "Μέγιστες Ενεργές Εκτελέσεις", "noTagsFound": "Δεν βρέθηκαν ετικέτες", + "noTeamsFound": "Δεν βρέθηκαν ομάδες", "tagMode": { "all": "Όλα", "any": "Οποιοδήποτε" }, "tagPlaceholder": "Φιλτράρισμα κατά ετικέτα", - "to": "Έως" + "to": "Έως", + "updatedAt": "Ενημερώθηκε στη/στις" }, "task": { + "dependsOnPast": "Εξαρτάται από παρελθοντική", "documentation": "Τεκμηρίωση Εργασίας", "lastInstance": "Τελευταία Εκτέλεση", "operator": "Τελεστής", - "triggerRule": "Κανόνας Ενεργοποίησης" + "retries": "Επαναλήψεις", + "triggerRule": "Κανόνας Ενεργοποίησης", + "waitForDownstream": "Αναμονή για Κατάντη" }, "task_one": "Εργασία", "task_other": "Εργασίες", + "taskGroup": { + "documentation": "Τεκμηρίωση Ομάδας Εργασιών" + }, + "taskGroup_one": "Ομάδα Εργασιών", + "taskGroup_other": "Ομάδες Εργασιών", "taskId": "ID Εργασίας", "taskInstance": { + "additionalAttributes": "Επιπλέον Ιδιότητες Εκτέλεσης Εργασίας", "dagVersion": "Έκδοση Dag", "executor": "Εκτελεστής", "executorConfig": "Ρυθμίσεις Εκτελεστή", "hostname": "Όνομα Υπολογιστή", + "id": "ID", "maxTries": "Μέγιστες Προσπάθειες", "pid": "PID", "pool": "Pool", @@ -243,14 +366,17 @@ "priorityWeight": "Βάρος Προτεραιότητας", "queue": "Ουρά", "queuedWhen": "Σε Ουρά Στις", + "renderedMapIndex": "Αποδιδόμενος Δείκτης Χάρτη", "scheduledWhen": "Προγραμματίστηκε Στις", + "trigger": "Ενεργοποίηση", "triggerer": { - "assigned": "Ανατεθειμένος triggerer", - "class": "Κλάση Trigger", - "createdAt": "Χρόνος δημιουργίας trigger", + "assigned": "Ανατεθειμένος ενεργοποιητής", + "class": "Κλάση Ενεργοποίησης", + "createdAt": "Χρόνος δημιουργίας ενεργοποίησης", "id": "ID Trigger", - "latestHeartbeat": "Τελευταίος παλμός triggerer", - "title": "Πληροφορίες Triggerer" + "job": "Διεργασία Ενεργοποιητή", + "latestHeartbeat": "Τελευταίος παλμός ενεργοποιητή", + "title": "Πληροφορίες Ενεργοποιητή" }, "unixname": "Όνομα Unix" }, @@ -275,46 +401,77 @@ "utc": "UTC (Συντονισμένη Παγκόσμια Ώρα)" }, "toaster": { + "bulkClear": { + "error": "Αποτυχία αιτήματος μαζικής εκκαθάρισης {{resourceName}}", + "success": { + "description": "{{count}} {{resourceName}} εκκαθαρίστηκαν με επιτυχία. Κλειδιά: {{keys}}", + "title": "Υποβλήθηκε αίτημα μαζικής εκκαθάρισης {{resourceName}}" + } + }, "bulkDelete": { - "error": "Αποτυχία μαζικής διαγραφής {{resourceName}}", + "error": "Αποτυχία αιτήματος μαζικής διαγραφής {{resourceName}}", "success": { "description": "{{count}} {{resourceName}} διαγράφηκαν με επιτυχία. Κλειδιά: {{keys}}", "title": "Υποβλήθηκε αίτημα μαζικής διαγραφής {{resourceName}}" } }, + "bulkUpdate": { + "error": "Αποτυχία αιτήματος μαζικής ενημέρωσης {{resourceName}}", + "success": { + "description": "{{count}} {{resourceName}} ενημερώθηκαν με επιτυχία. Κλειδιά: {{keys}}", + "title": "Υποβλήθηκε αίτημα μαζικής ενημέρωσης {{resourceName}}" + } + }, "create": { - "error": "Αποτυχία δημιουργίας {{resourceName}}", + "error": "Αποτυχία αιτήματος δημιουργίας {{resourceName}}", "success": { "description": "Το {{resourceName}} δημιουργήθηκε με επιτυχία.", "title": "Υποβλήθηκε αίτημα δημιουργίας {{resourceName}}" } }, "delete": { - "error": "Αποτυχία διαγραφής {{resourceName}}", + "error": "Αποτυχία αιτήματος διαγραφής {{resourceName}}", "success": { "description": "Το {{resourceName}} διαγράφηκε με επιτυχία.", "title": "Υποβλήθηκε αίτημα διαγραφής {{resourceName}}" } }, "import": { - "error": "Αποτυχία εισαγωγής {{resourceName}}", + "error": "Αποτυχία αιτήματος εισαγωγής {{resourceName}}", "success": { "description": "{{count}} {{resourceName}} εισήχθησαν με επιτυχία.", "title": "Υποβλήθηκε αίτημα εισαγωγής {{resourceName}}" } }, "update": { - "error": "Αποτυχία ενημέρωσης {{resourceName}}", + "error": "Αποτυχία αιτήματος ενημέρωσης {{resourceName}}", "success": { "description": "Το {{resourceName}} ενημερώθηκε με επιτυχία.", "title": "Υποβλήθηκε αίτημα ενημέρωσης {{resourceName}}" } } }, + "tokenGeneration": { + "apiToken": "Token API", + "cliToken": "Token CLI", + "errorDescription": "Παρουσιάστηκε σφάλμα κατά τη δημιουργία του token. Παρακαλώ δοκιμάστε ξανά.", + "errorTitle": "Αποτυχία Δημιουργίας Token", + "generate": "Δημιουργία", + "selectType": "Επιλέξτε τον τύπο του token προς δημιουργία.", + "title": "Δημιουργία Token", + "tokenExpiresIn": "Αυτό το token λήγει σε {{duration}}.", + "tokenGenerated": "Το token σας δημιουργήθηκε.", + "tokenShownOnce": "Αυτό το token θα εμφανιστεί μόνο μία φορά. Αντιγράψτε το τώρα." + }, "total": "Σύνολο {{state}}", "triggered": "Ενεργοποιήθηκε", "tryNumber": "Αριθμός Προσπάθειας", "user": "Χρήστης", + "validation": { + "mustBeAtLeast": "Πρέπει να είναι τουλάχιστον {{min}}.", + "mustBeValidNumber": "Πρέπει να είναι έγκυρος αριθμός." + }, + "value": "Τιμή", "wrap": { "hotkey": "w", "tooltip": "Πατήστε {{hotkey}} για εναλλαγή αναδίπλωσης", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json index aae983deabb1e..1079391c2ec16 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/components.json @@ -10,8 +10,12 @@ "maxRuns": "Μέγιστες Ενεργές Εκτελέσεις", "missingAndErroredRuns": "Εκτελέσεις που λείπουν ή απέτυχαν", "missingRuns": "Εκτελέσεις που λείπουν", + "overrideExistingParams": "Αντικατάσταση παραμέτρων σε υπάρχουσες εκτελέσεις", + "permissionDenied": "Η Δοκιμαστική Εκτέλεση Απέτυχε: Ο χρήστης δεν έχει δικαίωμα δημιουργίας backfills.", "reprocessBehavior": "Συμπεριφορά Επανεπεξεργασίας", "run": "Εκτέλεση Backfill", + "scheduleNotBackfillable": "Ο προγραμματισμός αυτού του Dag δεν υποστηρίζει backfills", + "schedulerPriorityHint": "Οι backfill εκτελέσεις Dag κατατάσσονται μετά από τις non-backfill εκτελέσεις Dag σε κάθε κύκλο του προγραμματιστή. Οι backfill εκτελέσεις ενδέχεται να παραμείνουν σε ουρά περισσότερο, εάν υπάρχουν άλλες non-backfill εκτελέσεις.", "selectDescription": "Εκτελέστε αυτό το Dag για ένα εύρος ημερομηνιών", "selectLabel": "Backfill", "title": "Εκτέλεση Backfill", @@ -44,17 +48,24 @@ }, "dagWarnings": { "error_one": "1 Σφάλμα", - "error_other": "{{count}} Σφάλματα", "errorAndWarning": "1 Σφάλμα και {{warningText}}", "warning_one": "1 Προειδοποίηση", "warning_other": "{{count}} Προειδοποιήσεις" }, + "dateRangeFilter": { + "validation": { + "invalidDateFormat": "Μη έγκυρη μορφή ημερομηνίας.", + "invalidTimeFormat": "Μη έγκυρη μορφή ώρας.", + "startBeforeEnd": "Η ημερομηνία/ώρα έναρξης πρέπει να είναι πριν από την ημερομηνία/ώρα λήξης" + } + }, "durationChart": { "duration": "Διάρκεια (δευτερόλεπτα)", "lastDagRun_one": "Τελευταία Εκτέλεση Dag", "lastDagRun_other": "Τελευταίες {{count}} Εκτελέσεις Dag", "lastTaskInstance_one": "Τελευταία Εκτέλεση Εργασίας", "lastTaskInstance_other": "Τελευταίες {{count}} Εκτελέσεις Εργασίας", + "medianTotalDuration": "Σύνολο: {{duration}}", "queuedDuration": "Διάρκεια σε Ουρά", "runAfter": "Εκτέλεση Μετά", "runDuration": "Διάρκεια Εκτέλεσης" @@ -64,6 +75,7 @@ "files_other": "{{count}} αρχεία" }, "flexibleForm": { + "durationPlaceholder": "Εισάγετε Διάρκεια σε μορφή ISO 8601", "placeholder": "Επιλέξτε Τιμή", "placeholderArray": "Εισάγετε κάθε συμβολοσειρά σε νέα γραμμή", "placeholderExamples": "Ξεκινήστε να πληκτρολογείτε για να δείτε επιλογές", @@ -71,6 +83,7 @@ "validationErrorArrayNotArray": "Η τιμή πρέπει να είναι πίνακας.", "validationErrorArrayNotNumbers": "Όλα τα στοιχεία του πίνακα πρέπει να είναι αριθμοί.", "validationErrorArrayNotObject": "Όλα τα στοιχεία του πίνακα πρέπει να είναι αντικείμενα.", + "validationErrorDuration": "Μη έγκυρη διάρκεια μορφής ISO 8601", "validationErrorRequired": "Αυτό το πεδίο είναι υποχρεωτικό" }, "graph": { @@ -84,9 +97,18 @@ "otherDagRuns": "+Άλλες Εκτελέσεις Dag", "taskCount_one": "{{count}} Εργασία", "taskCount_other": "{{count}} Εργασίες", - "taskGroup": "Ομάδα Εργασιών" + "taskGroup": "Ομάδα Εργασιών", + "zoomToTask": "Μεγέθυνση στην επιλεγμένη εργασία" }, "limitedList": "+{{count}} ακόμα", + "limitedList.allItems": "Όλα τα {{count}} στοιχεία:", + "limitedList.allTags_one": "Όλες οι Ετικέτες (1)", + "limitedList.allTags_other": "Όλες οι Ετικέτες ({{count}})", + "limitedList.clickToInteract": "Κάντε κλικ σε μια ετικέτα για φιλτράρισμα των Dags", + "limitedList.clickToOpenFull": "Κάντε κλικ στο «+{{count}} ακόμα» για πλήρη προβολή", + "limitedList.copyPasteText": "Μπορείτε να αντιγράψετε και να επικολλήσετε το παραπάνω κείμενο", + "limitedList.showingItems_one": "Εμφάνιση 1 στοιχείου", + "limitedList.showingItems_other": "Εμφάνιση {{count}} στοιχείων", "logs": { "file": "Αρχείο", "location": "γραμμή {{line}} στο {{name}}" @@ -96,22 +118,41 @@ "sortedDescending": "φθίνουσα ταξινόμηση", "sortedUnsorted": "μη ταξινομημένο", "taskTries": "Προσπάθειες Εργασίας", + "taskTryPlaceholder": "Προσπάθεια Εργασίας", + "team": { + "selector": { + "helperText": "Προαιρετικό. Περιορισμός της χρήσης σε συγκεκριμένη ομάδα.", + "label": "Ομάδα", + "placeHolder": "Επιλέξτε ομάδα" + } + }, "toggleCardView": "Εμφάνιση κάρτας", "toggleTableView": "Εμφάνιση πίνακα", "triggerDag": { "button": "Ενεργοποίηση", + "dataInterval": "Διάστημα Δεδομένων", + "dataIntervalAuto": "Συνάγεται από τη Λογική Ημερομηνία και το Χρονοδιάγραμμα", + "dataIntervalManual": "Χειροκίνητος Ορισμός", + "intervalEnd": "Λήξη", + "intervalStart": "Έναρξη", "loading": "Φόρτωση πληροφοριών Dag...", "loadingFailed": "Αποτυχία φόρτωσης πληροφοριών Dag. Παρακαλώ δοκιμάστε ξανά.", + "manualRunDenied": "Οι χειροκίνητες εκτελέσεις δεν επιτρέπονται για αυτό το Dag", + "partitionKeyHelp": "Προαιρετικό - ισχύει μόνο για Dags με κατατμήσεις", "runIdHelp": "Προαιρετικό - θα δημιουργηθεί αν δεν δοθεί", "selectDescription": "Ενεργοποιήστε μία εκτέλεση αυτού του Dag", "selectLabel": "Μονή Εκτέλεση", "title": "Ενεργοποίηση Dag", "toaster": { + "error": { + "title": "Αποτυχία Ενεργοποίησης Dag" + }, "success": { "description": "Η εκτέλεση Dag ενεργοποιήθηκε με επιτυχία.", "title": "Η Εκτέλεση Dag Ενεργοποιήθηκε" } }, + "triggerAgainWithConfig": "Ενεργοποίηση ξανά με αυτές τις ρυθμίσεις", "unpause": "Αναίρεση παύσης του {{dagDisplayName}} κατά την ενεργοποίηση" }, "trimText": { @@ -127,6 +168,7 @@ "versionId": "ID Έκδοσης" }, "versionSelect": { + "allVersions": "Όλες οι Εκδόσεις", "dagVersion": "Έκδοση Dag", "versionCode": "v{{versionCode}}" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json index 12f472a19473b..fa3e170889f82 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json @@ -20,7 +20,7 @@ "previousYear": "Προηγούμενο έτος" }, "noData": "Δεν υπάρχουν διαθέσιμα δεδομένα", - "noFailedRuns": "No failed runs", + "noFailedRuns": "Δεν υπάρχουν αποτυχημένες εκτελέσεις", "noRuns": "Δεν υπάρχουν εκτελέσεις", "totalRuns": "Σύνολο Εκτελέσεων", "week": "Εβδομάδα {{weekNumber}}", @@ -40,17 +40,49 @@ "parseDuration": "Διάρκεια Ανάλυσης:", "parsedAt": "Αναλύθηκε στις:" }, + "deadlineAlerts": { + "completionRule": "Πρέπει να ολοκληρωθεί εντός {{interval}} από {{reference}}", + "count_one": "{{count}} προθεσμία", + "count_other": "{{count}} προθεσμίες", + "referenceType": { + "AverageRuntimeDeadline": "μέσος χρόνος εκτέλεσης", + "DagRunLogicalDateDeadline": "λογική ημερομηνία", + "DagRunQueuedAtDeadline": "χρόνος στην ουρά" + } + }, + "deadlineStatus": { + "actual": "Πραγματικό", + "expected": "Αναμενόμενο", + "finishedEarly": "Ολοκληρώθηκε {{duration}} πριν από την προθεσμία", + "finishedLate": "Ολοκληρώθηκε {{duration}} μετά την προθεσμία", + "label": "Προθεσμία", + "met": "Τηρήθηκε", + "missed": "Χάθηκε", + "missedCount_one": "{{count}} Χαμένη Προθεσμία", + "missedCount_other": "{{count}} Χαμένες Προθεσμίες", + "mixedCount": "{{missedCount}} Χαμένες, {{upcomingCount}} Επερχόμενες", + "stillRunning": "Εκτελείται ακόμη", + "upcoming": "Επερχόμενη", + "upcomingCount_one": "{{count}} Επερχόμενη Προθεσμία", + "upcomingCount_other": "{{count}} Επερχόμενες Προθεσμίες" + }, "extraLinks": "Επιπλέον Σύνδεσμοι", "grid": { "buttons": { + "newerRuns": "Νεότερες εκτελέσεις", + "olderRuns": "Παλαιότερες εκτελέσεις", "resetToLatest": "Επαναφορά στα πιο πρόσφατα", "toggleGroup": "Εναλλαγή ομάδας" - } + }, + "runTypeLegend": "Υπόμνημα Τύπων Εκτέλεσης" }, "header": { "buttons": { "advanced": "Για προχωρημένους", "dagDocs": "Τεκμήρια Dag" + }, + "status": { + "deactivated": "Απενεργοποιημένο" } }, "logs": { @@ -59,19 +91,22 @@ "critical": "ΚΡΙΣΙΜΟ", "debug": "DEBUG", "error": "ΣΦΑΛΜΑ", - "fullscreen": { - "button": "Πλήρης οθόνη", - "tooltip": "Πατήστε {{hotkey}} για πλήρη οθόνη" - }, "info": "INFO", "noTryNumber": "Χωρίς αριθμό προσπάθειας", + "search": { + "matchCount": "{{current}} από {{total}}", + "noMatches": "Δεν βρέθηκαν αντιστοιχίες", + "placeholder": "Αναζήτηση στις καταγραφές..." + }, "settings": "Ρυθμίσεις Καταγραφής", "viewInExternal": "Προβολή καταγραφών στο {{name}} (προσπάθεια {{attempt}})", "warning": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ" }, - "navigation": { - "navigation": "Πλοήγηση: Shift+{{arrow}}", - "toggleGroup": "Εναλλαγή ομάδας: Space" + "notFound": { + "back": "Επιστροφή", + "backToDags": "Επιστροφή στα Dags", + "message": "Το Dag «{{dagId}}» δεν υπάρχει.", + "title": "Το Dag Δεν Βρέθηκε" }, "overview": { "buttons": { @@ -86,6 +121,10 @@ "assetEvent_one": "Δημιουργήθηκε Συμβάν Οντότητας", "assetEvent_other": "Δημιουργήθηκαν Συμβάντα Οντοτήτων" }, + "deadlines": { + "showAll": "Εμφάνιση Όλων", + "title": "Προθεσμίες" + }, "failedLogs": { "hideLogs": "Απόκρυψη Καταγραφών", "showLogs": "Εμφάνιση Καταγραφών", @@ -114,6 +153,45 @@ }, "graphDirection": { "label": "Κατεύθυνση Γραφήματος" + }, + "graphFilters": { + "clearFilters": "Εκκαθάριση Φίλτρων", + "durationGte": "Ελάχ. διάρκεια (δευτ.)", + "durationGteHint": "Για χαρτογραφημένες εργασίες, μετρά τη συνολική διάρκεια όλων των εκτελέσεων", + "mapIndex": "Ελάχ. δείκτης χάρτη", + "mapIndexHint": "Εμφανίζει χαρτογραφημένες εργασίες αναπτυγμένες τουλάχιστον έως αυτόν τον δείκτη", + "selectStatus": "Επιλέξτε κατάσταση", + "selectTaskGroup": "Επιλέξτε ομάδα εργασιών", + "title": "Φίλτρα Εργασιών" + }, + "showVersionIndicator": { + "label": "Εμφάνιση Ένδειξης Έκδοσης", + "options": { + "hideAll": "Απόκρυψη Όλων", + "showAll": "Εμφάνιση Όλων", + "showBundleVersion": "Εμφάνιση Έκδοσης Πακέτου", + "showDagVersion": "Εμφάνιση Έκδοσης Dag" + } + }, + "taskStreamFilter": { + "activeFilter": "Ενεργό φίλτρο", + "clearFilter": "Εκκαθάριση Φίλτρου", + "clickTask": "Κάντε κλικ σε μια εργασία για να την ορίσετε ως ρίζα του φίλτρου", + "depth": "Βάθος", + "direction": "Κατεύθυνση", + "label": "Φίλτρο", + "mode": "Λειτουργία", + "modeTooltip": "Η στατική λειτουργία διατηρεί την τρέχουσα προβολή κατά τη μετάβαση σε άλλες εργασίες, ενώ η λειτουργία διάσχισης ενημερώνει αυτόματα το ενεργό φίλτρο στην εργασία που επιλέχθηκε, για ευκολότερη διάσχιση του Dag.", + "modes": { + "static": "Στατική", + "traverse": "Διάσχιση" + }, + "options": { + "both": "Ανάντη & κατάντη", + "downstream": "Κατάντη", + "upstream": "Ανάντη" + }, + "selectedTask": "Επιλεγμένη εργασία" } }, "paramsFailed": "Αποτυχία φόρτωσης παραμέτρων", @@ -143,12 +221,34 @@ "renderedTemplates": "Αποδοθέντα Πρότυπα", "requiredActions": "Απαιτούμενες Ενέργειες", "runs": "Εκτελέσεις", + "storage": "Αποθήκευση", "taskInstances": "Στιγμιαίες Καταστάσεις Εργασίας", + "taskStateStore": "Αποθήκη Καταστάσεων Εργασίας", "tasks": "Εργασίες", "xcom": "XCom" }, "taskGroups": { "collapseAll": "Σύμπτυξη όλων των ομάδων εργασιών", "expandAll": "Ανάπτυξη όλων των ομάδων εργασιών" + }, + "taskStateStore": { + "add": "Προσθήκη Αποθήκης Καταστάσεων Εργασίας", + "clearAll": { + "resource": "όλη την αποθήκη καταστάσεων εργασίας", + "title": "Εκκαθάριση Ολόκληρης της Αποθήκης Καταστάσεων Εργασίας", + "warning": "Ολόκληρη η αποθήκη καταστάσεων εργασίας θα διαγραφεί. Οι εργασίες που χρησιμοποιούν αυτήν την αποθήκη για την παρακολούθηση εξωτερικών εργασιών δεν θα μπορούν να συνεχίσουν χωρίς πλήρη επανεκτέλεση." + }, + "delete": "Διαγραφή Αποθήκης Καταστάσεων Εργασίας", + "deleteWarning": "Η εργασία θα χάσει αυτήν την αποθηκευμένη μνήμη. Αν η εργασία χρησιμοποιεί αυτό το κλειδί για την παρακολούθηση εξωτερικής εργασίας (π.χ. ένα εξωτερικό ID διεργασίας), δεν θα μπορεί να τη συνεχίσει.", + "edit": "Επεξεργασία Αποθήκης Καταστάσεων Εργασίας", + "emptyStore": "Η αποθήκη καταστάσεων εργασίας αποθηκεύει τιμές που διατηρούνται μεταξύ επαναλήψεων. Οι εργάτες μπορούν να γράψουν στην αποθήκη καταστάσεων εργασίας μέσω του Task SDK.", + "expiresAt": { + "column": "Λήγει Στις", + "custom": "Προσαρμοσμένη", + "default": "Προεπιλογή ({{interval}})", + "label": "Λήξη", + "never": "Ποτέ" + }, + "title": "Αποθήκη Καταστάσεων Εργασίας" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json index 7b127ac0af95d..19c78804dca57 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "Όλοι οι τύποι Εκτελέσεων", "allStates": "Όλες οι καταστάσεις", + "anyRunState": "Οποιαδήποτε εκτέλεση", "favorite": { "all": "Όλα", "favorite": "Αγαπημένο", "unfavorite": "Μη αγαπημένα" }, + "lastRunState": "Τελευταία εκτέλεση", "paused": { "active": "Ενεργό", "all": "Όλα", @@ -34,6 +36,15 @@ "error": "Αποτυχία εκκαθάρισης {{type}}", "title": "Εκκαθάριση {{type}}" }, + "clearAllMapped": { + "button": "Εκκαθάριση Όλων των Χαρτογραφημένων Εργασιών", + "buttonTooltip": "Πατήστε shift+c για εκκαθάριση όλων των χαρτογραφημένων εκτελέσεων εργασίας", + "title": "Εκκαθάριση Όλων των Χαρτογραφημένων Εκτελέσεων Εργασίας" + }, + "confirmationDialog": { + "description": "Η εργασία βρίσκεται αυτήν τη στιγμή σε κατάσταση {{state}} και ξεκίνησε από τον χρήστη {{user}} στις {{time}}. \nΔεν είναι δυνατή η εκκαθάριση αυτής της εργασίας μέχρι να ολοκληρωθεί η εκτέλεσή της ή μέχρι ένας χρήστης να αποεπιλέξει την επιλογή «Αποτροπή επανεκτέλεσης αν η εργασία εκτελείται» στο παράθυρο εκκαθάρισης εργασίας.", + "title": "Αδυναμία Εκκαθάρισης Εκτέλεσης Εργασίας" + }, "delete": { "button": "Διαγραφή {{type}}", "dialog": { @@ -61,11 +72,17 @@ "future": "Μελλοντικές", "onlyFailed": "Εκκαθάριση μόνο αποτυχημένων εργασιών", "past": "Παρελθόν", + "preventRunningTasks": "Αποτροπή επανεκτέλεσης αν η εργασία εκτελείται", "queueNew": "Προσθήκη νέων εργασιών στην ουρά", "runOnLatestVersion": "Εκτέλεση με την τελευταία έκδοση του bundle", "upstream": "Άνοδος" } }, + "runStateCounts": { + "label": "Καταστάσεις εκτελέσεων", + "loading": "Φόρτωση πλήθους καταστάσεων εκτελέσεων", + "tooltip": "{{state}}: {{formattedCount}} — κάντε κλικ για φιλτράρισμα εκτελέσεων" + }, "search": { "advanced": "Σύνθετη Αναζήτηση", "clear": "Εκκαθάριση αναζήτησης", @@ -78,9 +95,9 @@ "asc": "Ταξινόμηση κατά Όνομα (A-Z)", "desc": "Ταξινόμηση κατά Όνομα (Z-A)" }, - "lastRunStartDate": { - "asc": "Ταξινόμηση κατά Ημερομηνία Έναρξης Τελευταίας Εκτέλεσης (Παλαιότερο-Νεότερο)", - "desc": "Ταξινόμηση κατά Ημερομηνία Έναρξης Τελευταίας Εκτέλεσης (Νεότερο-Παλαιότερο)" + "lastRunAfter": { + "asc": "Ταξινόμηση κατά Τελευταία Εκτέλεση Μετά (Νεότερο-Παλαιότερο)", + "desc": "Ταξινόμηση κατά Τελευταία Εκτέλεση Μετά (Παλαιότερο-Νεότερο)" }, "lastRunState": { "asc": "Ταξινόμηση κατά Κατάσταση Τελευταίας Εκτέλεσης (A-Z)", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json index 1ff8e42424699..529624a093fd1 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dashboard.json @@ -1,4 +1,24 @@ { + "alerts": { + "seeLessContext": "Εμφάνιση λιγότερων", + "seeMoreContext": "Εμφάνιση περισσότερων", + "showMoreAlerts_one": "+{{count}} ακόμη ειδοποίηση", + "showMoreAlerts_other": "+{{count}} ακόμη ειδοποιήσεις" + }, + "deadlines": { + "pending": { + "empty": "Δεν υπάρχουν επερχόμενες προθεσμίες", + "title": "Επερχόμενες" + }, + "recentlyMissed": { + "empty": "Δεν υπάρχουν χαμένες προθεσμίες", + "title": "Χαμένες Προθεσμίες" + }, + "showMore": "Εμφάνιση περισσότερων", + "title": "Προθεσμίες" + }, + "deferredSlotsNotCounted": "Αναβληθείσες που δεν μετρώνται στις θέσεις: {{count}}", + "deferredSlotsNotCountedTooltip": "Οι αναβληθείσες εργασίες που εμφανίζονται στη μπάρα προσμετρώνται στις θέσεις του pool. Οι αναβληθείσες εργασίες που εμφανίζονται κάτω από τη μπάρα προέρχονται από pools που δεν προσμετρούν τις αναβληθείσες εργασίες στις θέσεις.", "favorite": { "favoriteDags_one": "Πρώτο αγαπημένο Dag ({{count}})", "favoriteDags_other": "Πρώτα αγαπημένα Dag ({{count}})", @@ -29,7 +49,8 @@ "poolSlots": "Θέσεις Pool", "sortBy": { "newestFirst": "Νεότερα Πρώτα", - "oldestFirst": "Παλαιότερα Πρώτα" + "oldestFirst": "Παλαιότερα Πρώτα", + "placeholder": "Ταξινόμηση κατά" }, "source": "Πηγή", "stats": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json index d93ea3c216fe8..62098c39fbf77 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/hitl.json @@ -1,5 +1,7 @@ { "filters": { + "body": "Περιεχόμενο", + "createdAt": "Δημιουργήθηκε Στις", "response": { "all": "Όλα", "pending": "Σε εκκρεμότητα", @@ -12,14 +14,30 @@ "requiredActionCount_other": "Απαιτούμενες Ενέργειες ({{count}})", "requiredActionState": "Κατάσταση Απαιτούμενης Ενέργειας", "response": { + "created": "Η απάντηση δημιουργήθηκε στις ", "error": "Αποτυχημένη απάντηση", "optionsDescription": "Επιλέξτε τις επιλογές σας για αυτήν την εκτέλεση εργασίας", "optionsLabel": "Επιλογές", "received": "Η απάντηση ελήφθη στις ", "respond": "Απάντηση", + "responded_by_user_name": "Απαντήθηκε από (Όνομα Χρήστη)", "success": "Η απάντηση για το {{taskId}} ήταν επιτυχής", "title": "Εκτέλεση Εργασίας με Παρέμβαση Χρήστη - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "Επιλέξτε μια απαιτούμενη ενέργεια για να δείτε λεπτομέρειες" + }, + "list": { + "completedRequiredActions": "Ολοκληρωμένες απαιτούμενες ενέργειες ({{count}})", + "loadError": "Αδυναμία φόρτωσης απαιτούμενων ενεργειών", + "loadingActions": "Φόρτωση απαιτούμενων ενεργειών...", + "pendingRequiredActions": "Απαιτούμενες ενέργειες σε εκκρεμότητα ({{count}})" + }, + "openReviewDrawer": "Άνοιγμα Πλαισίου Αξιολόγησης", + "pageLimitHint": "Εδώ εμφανίζονται μόνο οι πρώτες ενέργειες. Χρησιμοποιήστε την επιλογή «Προβολή όλων των απαιτούμενων ενεργειών» για να τις δείτε όλες.", + "viewAll": "Προβολή όλων των απαιτούμενων ενεργειών" + }, "state": { "approvalReceived": "Έγκριση Ελήφθη", "approvalRequired": "Απαιτείται Έγκριση", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json index 1b02ee5b9b448..58319ddd81d5c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/admin.json @@ -177,6 +177,7 @@ "title": "Skip" } }, + "parsingFile": "Parsing file...", "title": "Import Variables", "upload": "Upload a JSON File", "uploadPlaceholder": "Upload a JSON file containing variables (e.g., {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json index 7b5f37c9cfd3b..70e600b332dae 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json @@ -71,9 +71,9 @@ }, "expectedDuration": "Expected Duration", "lastSchedulingDecision": "Last Scheduling Decision", - "mappedPartitionKey": "Mapped Partition key", + "mappedPartitionKey": "Mapped Partition Key", "partitionDate": "Partition Date", - "partitionKey": "Partition key", + "partitionKey": "Partition Key", "queuedAt": "Queued At", "runAfter": "Run After", "runType": "Run Type", @@ -226,6 +226,47 @@ }, "selectLanguage": "Select Language", "selected": "Selected", + "shortcuts": { + "categories": { + "code": "Code", + "dagView": "Dag View", + "filters": "Filters", + "global": "Global", + "logs": "Logs", + "navigation": "Navigation", + "runActions": "Run & Task Actions", + "search": "Search" + }, + "descriptions": { + "clearRun": "Clear $t(dagRun_one)", + "clearTaskInstance": "Clear $t(taskInstance_one)", + "downloadLogs": "Download logs", + "focusFilterSearch": "Focus filter search", + "focusLogSearch": "Search logs", + "focusSearch": "Focus search", + "markRunFailed": "Mark $t(dagRun_one) as failed", + "markRunSuccess": "Mark $t(dagRun_one) as success", + "markTaskFailed": "Mark $t(task_one) as failed", + "markTaskGroupFailed": "Mark $t(taskGroup_one) as failed", + "markTaskGroupSuccess": "Mark $t(taskGroup_one) as success", + "markTaskSuccess": "Mark $t(task_one) as success", + "navigateTasks": "Navigate $t(task_other)", + "openGraphFilters": "Open graph filters", + "scrollBottom": "Scroll to bottom", + "scrollTop": "Scroll to top", + "searchDags": "Search $t(dag_other)", + "showHelp": "Show $t(shortcuts.title)", + "toggleExpand": "Expand or collapse all groups", + "toggleFullscreen": "Toggle fullscreen", + "toggleGraphGrid": "Toggle graph / grid view", + "toggleSource": "Toggle source", + "toggleTaskGroup": "Expand or collapse $t(taskGroup_one)", + "toggleTimestamp": "Toggle timestamps", + "toggleWrap": "Toggle $t(wrap.wrap)" + }, + "empty": "No keyboard shortcuts are available on this page.", + "title": "Keyboard Shortcuts" + }, "showDetailsPanel": "Show Details Panel", "signedInAs": "Signed in as", "source": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json index 350e3898a39ee..837726e376dc6 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/components.json @@ -65,6 +65,7 @@ "lastDagRun_other": "Last {{count}} Dag Runs", "lastTaskInstance_one": "Last Task Instance", "lastTaskInstance_other": "Last {{count}} Task Instances", + "medianTotalDuration": "Total: {{duration}}", "queuedDuration": "Queued Duration", "runAfter": "Run After", "runDuration": "Run Duration" @@ -136,6 +137,7 @@ "loading": "Loading Dag information...", "loadingFailed": "Failed to load Dag information. Please try again.", "manualRunDenied": "Manual runs are not allowed for this Dag", + "partitionKeyHelp": "Optional - only applies to partitioned Dags", "runIdHelp": "Optional - will be generated if not provided", "selectDescription": "Trigger a single run of this Dag", "selectLabel": "Single Run", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json index b51add8d5ec09..f203c21595f5d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json @@ -42,6 +42,7 @@ }, "deadlineAlerts": { "completionRule": "Must complete within {{interval}} of {{reference}}", + "completionRuleDynamic": "Must complete within a variable interval measured from {{reference}}", "count_one": "{{count}} deadline", "count_other": "{{count}} deadlines", "referenceType": { @@ -102,11 +103,6 @@ "viewInExternal": "View logs in {{name}} (attempt {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "Navigation: Shift+{{arrow}}", - "openGraphFilters": "Task Filters: Ctrl+Shift+F", - "toggleGroup": "Toggle group: Space" - }, "notFound": { "back": "Go Back", "backToDags": "Back to Dags", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/dags.json index dc40390745709..472c949ce284d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/en/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "All Run Types", "allStates": "All States", + "anyRunState": "Any run", "favorite": { "all": "All", "favorite": "Favorite", "unfavorite": "Unfavorite" }, + "lastRunState": "Last run", "paused": { "active": "Active", "all": "All", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json index 5f486075678d0..22a888915a760 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/admin.json @@ -3,6 +3,7 @@ "description": "Descripción", "key": "Clave", "name": "Nombre", + "team": "Equipo", "value": "Valor" }, "config": { @@ -52,6 +53,12 @@ "searchPlaceholder": "Buscar Conexiones", "test": "Prueba de Conexión", "testDisabled": "La función de prueba de conexión está desactivada. Por favor, contacta a un administrador para activarla.", + "testError": { + "title": "Prueba de Conexión Fallida" + }, + "testSuccess": { + "title": "Prueba de Conexión Exitosa" + }, "typeMeta": { "error": "Error al recuperar la Metadata del Tipo de Conexión", "standardFields": { @@ -77,6 +84,23 @@ "formActions": { "save": "Guardar" }, + "jobs": { + "columns": { + "executorClass": "Clase de Executor", + "hostname": "Nombre de Host", + "id": "ID", + "jobType": "Tipo de Trabajo", + "latestHeartbeat": "Último Heartbeat", + "unixname": "Nombre de Unix" + }, + "filters": { + "allStates": "Todos los Estados", + "allTypes": "Todos los Tipos", + "dagProcessorJob": "DagProcessorJob", + "schedulerJob": "SchedulerJob", + "triggererJob": "TriggererJob" + } + }, "plugins": { "columns": { "source": "Origen" @@ -100,7 +124,8 @@ "includeDeferred": "Incluir diferidos", "nameMaxLength": "El nombre puede contener un máximo de 256 caracteres", "nameRequired": "El nombre es requerido", - "slots": "Slots" + "slots": "Slots", + "slotsHelperText": "Use -1 para slots ilimitados." }, "noPoolsFound": "No se encontraron pools", "pool_many": "Pools", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/assets.json index bbfba653429bc..caacecd572d3b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/assets.json @@ -1,5 +1,26 @@ { + "additional_data": "Datos Adicionales", + "asset_many": "Assets", + "asset_one": "Asset", + "asset_other": "Assets", + "assetStateStore": { + "add": "Agregar Almacenamiento de Estado de Asset", + "clearAll": { + "resource": "todo el almacenamiento de estado de Asset", + "title": "Limpiar Todo el Almacenamiento de Estado de Asset", + "warning": "Se borrará todo el almacenamiento de estado de Asset. Las tareas que usan este almacenamiento para coordinar trabajo perderán su memoria persistente." + }, + "delete": "Eliminar Almacenamiento de Estado de Asset", + "deleteWarning": "El Asset perderá esta entrada de almacenamiento de estado persistente.", + "edit": "Editar Almacenamiento de Estado de Asset", + "emptyState": "El almacenamiento de estado de Asset almacena valores con alcance en la identidad de un Asset, compartidos entre todas las ejecuciones del Dag. Los workers pueden escribir en el almacenamiento de estado de Asset mediante el Task SDK.", + "lastUpdatedBy": "Última Actualización Realizada Por", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Watcher", + "title": "Almacenamiento de Estado de Asset" + }, "consumingDags": "Consumiendo Dags", + "consumingTasks": "Tareas Consumidoras", "createEvent": { "button": "Crear Evento", "manual": { @@ -21,10 +42,14 @@ }, "title": "Crear Evento de Asset para {{name}}" }, + "events": "Eventos", + "extra": "Extra", "group": "Grupo", "lastAssetEvent": "Último Evento de Asset", "name": "Nombre", "producingTasks": "Tareas produciendo", "scheduledDags": "Dags programados", - "searchPlaceholder": "Buscar Assets" + "scheduling": "Programación", + "searchPlaceholder": "Buscar Assets", + "taskDependencies": "Dependencias de Tareas" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/browse.json index 5e117af466d12..8f69458715956 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/browse.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/browse.json @@ -11,12 +11,55 @@ }, "title": "Auditar Log" }, + "deadlines": { + "columns": { + "alertName": "Nombre de Alerta", + "deadlineTime": "Hora del Plazo", + "status": "Estado" + }, + "deadline_many": "Plazos", + "deadline_one": "Plazo", + "deadline_other": "Plazos", + "filters": { + "status": "Estado", + "statusOptions": { + "all": "Todos", + "missed": "Incumplido", + "pending": "Pendiente" + } + }, + "title": "Plazos" + }, "xcom": { + "add": { + "error": "Error al agregar XCom", + "errorTitle": "Error", + "success": "XCom agregado exitosamente", + "successTitle": "XCom Agregado", + "title": "Agregar XCom" + }, "columns": { "dag": "Dag", "key": "Clave", "value": "Valor" }, - "title": "XCom" + "delete": { + "error": "Error al eliminar XCom", + "errorTitle": "Error", + "success": "XCom eliminado exitosamente", + "successTitle": "XCom Eliminado", + "title": "Eliminar XCom", + "warning": "¿Confirmas que deseas eliminar este XCom? Esta acción no se puede deshacer." + }, + "edit": { + "error": "Error al actualizar XCom", + "errorTitle": "Error", + "success": "XCom actualizado exitosamente", + "successTitle": "XCom Actualizado", + "title": "Editar XCom" + }, + "key": "Clave", + "title": "XCom", + "value": "Valor" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json index 3dcc974b2f48d..d84ff40f3596a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/common.json @@ -20,16 +20,22 @@ "assetEvent_many": "Eventos de Asset", "assetEvent_one": "Evento de Asset", "assetEvent_other": "Eventos de Asset", + "assetInactive": { + "tooltip": "El Asset upstream ha sido desactivado; el programador retiene la evaluación de particiones hasta que se reactive." + }, "backfill_many": "Backfills", "backfill_one": "Backfill", "backfill_other": "Backfills", "browse": { "auditLog": "Auditar Log", + "deadlines": "Plazos", + "jobs": "Trabajos", "requiredActions": "Acciones Requeridas", "xcoms": "XComs" }, "collapseAllExtra": "Colapsar todos los extra json", "collapseDetailsPanel": "Colapsar Detalles del Panel", + "consumingAsset": "Asset Consumidor", "createdAssetEvent_many": "Eventos de Asset Creados", "createdAssetEvent_one": "Evento de Asset Creado", "createdAssetEvent_other": "Eventos de Asset Creados", @@ -70,6 +76,8 @@ }, "expectedDuration": "Duración Esperada", "lastSchedulingDecision": "Última Decisión de Programación", + "mappedPartitionKey": "Clave de Partición Mapeada", + "partitionKey": "Clave de Partición", "queuedAt": "En Cola en", "runAfter": "Ejecutar Después", "runType": "Tipo de Ejecución", @@ -84,6 +92,11 @@ "dagWarnings": "Advertencias/Errores del Dag", "defaultToGraphView": "Por defecto a vista gráfica", "defaultToGridView": "Por defecto a vista en cuadrícula", + "delete": "Eliminar", + "diff": "Diff", + "diffCompareWith": "Comparar con", + "diffExit": "Salir de Diff", + "diffSelectVersionToCompare": "Seleccionar versión para comparar", "direction": "Dirección", "docs": { "documentation": "Documentación", @@ -96,14 +109,22 @@ "tooltip": "Presiona {{hotkey}} para descargar los registros" }, "duration": "Duración", + "edit": "Editar", "endDate": "Fecha Final", "error": { "back": "Atrás", "defaultMessage": "Ocurrió un error inesperado", "home": "Inicio", + "invalidUrl": "Página No Encontrada. Verifica la URL e inténtalo de nuevo.", "notFound": "Página no encontrada", "title": "Error" }, + "errors": { + "forbidden": { + "description": "No tienes permiso para realizar esta acción.", + "title": "Acceso Denegado" + } + }, "expand": { "collapse": "Colapsar", "expand": "Expandir", @@ -121,22 +142,33 @@ "filters": { "durationFrom": "Duración Desde", "durationTo": "Duración Hasta", + "endTime": "Hora Final", "logicalDateFrom": "Fecha Lógica Desde", "logicalDateTo": "Fecha Lógica Hasta", "runAfterFrom": "Ejecutar Después Desde", - "runAfterTo": "Ejecutar Después Hasta" + "runAfterTo": "Ejecutar Después Hasta", + "searchAsset": "Buscar Asset", + "selectDateRange": "Seleccionar Rango de Fechas", + "startTime": "Hora Inicial" }, + "fullscreen": { + "tooltip": "Presiona {{hotkey}} para pantalla completa" + }, + "generateToken": "Generar Token", + "key": "Clave", "logicalDate": "Fecha Lógica", "logout": "Cerrar Sesión", "logoutConfirmation": "Estás a punto de cerrar sesión de la aplicación.", "mapIndex": "Mapa de Índice", "modal": { + "add": "Agregar", "cancel": "Cancelar", "confirm": "Confirmar", "delete": { "button": "Eliminar", "confirmation": "¿Confirmas de querer eliminar {{resourceName}}? Esta acción no se puede deshacer." - } + }, + "save": "Guardar" }, "nav": { "admin": "Administración", @@ -153,23 +185,27 @@ "note": { "add": "Agregar una nota", "dagRun": "Nota de Ejecución del Dag", + "edit": "Editar nota", "label": "Nota", "placeholder": "Agregar una nota...", - "taskInstance": "Nota de Instancia de Tarea" + "preview": "Vista Previa", + "taskInstance": "Nota de Instancia de Tarea", + "write": "Escribir" }, - "pools": { - "deferred": "Diferido", - "open": "Abierto", - "pools_many": "pools", - "pools_one": "pool", - "pools_other": "pools", - "queued": "En Cola", - "running": "En Ejecución", - "scheduled": "Programado" + "overallStatus": "Estado General", + "partitionedDagRun_many": "Ejecuciones del Dag Particionadas", + "partitionedDagRun_one": "Ejecución del Dag Particionada", + "partitionedDagRun_other": "Ejecuciones del Dag Particionadas", + "partitionedDagRunDetail": { + "receivedAssetEvents": "Eventos de Asset Recibidos" }, + "pendingDagRun_many": "{{count}} Ejecuciones del Dag Pendientes", + "pendingDagRun_one": "{{count}} Ejecución del Dag Pendiente", + "pendingDagRun_other": "{{count}} Ejecuciones del Dag Pendientes", "reset": "Restablecer", "runId": "ID de la ejecución", "runTypes": { + "asset_materialization": "Materialización de Asset", "asset_triggered": "Asset Activado", "backfill": "Backfill", "manual": "Manual", @@ -182,6 +218,12 @@ }, "tooltip": "Presiona {{hotkey}} para desplazarte a {{direction}}" }, + "search": { + "advanced": { + "description": "Coincide en cualquier parte del valor (búsqueda por subcadena). Más lento en despliegues grandes porque no puede usar el índice B-tree predeterminado. Consulta la sección de documentación sobre índices de metadata personalizados para más detalles.", + "title": "Coincidir en Cualquier Parte" + } + }, "security": { "actions": "Acciones", "permissions": "Permisos", @@ -190,7 +232,9 @@ "users": "Usuarios" }, "selectLanguage": "Seleccionar Idioma", + "selected": "Seleccionado", "showDetailsPanel": "Mostrar Panel de Detalles", + "signedInAs": "Sesión iniciada como", "source": { "hide": "Ocultar Fuente", "hotkey": "s", @@ -202,10 +246,12 @@ "startDate": "Fecha Inicial", "state": "Estado", "states": { + "awaiting_input": "Esperando Entrada", "deferred": "Diferido", "failed": "Fallido", "no_status": "Sin Estado", "none": "Sin Estado", + "open": "Abierto", "planned": "Planificado", "queued": "En Cola", "removed": "Removido", @@ -234,23 +280,35 @@ "any": "Cualquiera" }, "tagPlaceholder": "Filtrar por etiqueta", - "to": "Hasta" + "to": "Hasta", + "updatedAt": "Actualizado en" }, "task": { + "dependsOnPast": "Depende del Pasado", "documentation": "Documentación de la Tarea", "lastInstance": "Última Instancia", "operator": "Operador", - "triggerRule": "Regla de Activación" + "retries": "Reintentos", + "triggerRule": "Regla de Activación", + "waitForDownstream": "Esperar Downstream" }, "task_many": "Tareas", "task_one": "Tarea", "task_other": "Tareas", + "taskGroup": { + "documentation": "Documentación del Grupo de Tareas" + }, + "taskGroup_many": "Grupos de Tareas", + "taskGroup_one": "Grupo de Tareas", + "taskGroup_other": "Grupos de Tareas", "taskId": "ID de la Tarea", "taskInstance": { + "additionalAttributes": "Atributos Adicionales de la Instancia de Tarea", "dagVersion": "Versión del Dag", "executor": "Executor", "executorConfig": "Configuración del Executor", "hostname": "Nombre de Host", + "id": "ID", "maxTries": "Máximo de Intentos", "pid": "PID", "pool": "Pool", @@ -258,12 +316,15 @@ "priorityWeight": "Peso de Prioridad", "queue": "Cola", "queuedWhen": "En Cola en", + "renderedMapIndex": "Map Index Renderizado", "scheduledWhen": "Programado en", + "trigger": "Trigger", "triggerer": { "assigned": "Triggerer Asignado", "class": "Clase del Trigger", "createdAt": "Tiempo de Creación del Trigger", "id": "ID del Trigger", + "job": "Trabajo del Triggerer", "latestHeartbeat": "Último Heartbeat del Triggerer", "title": "Información del Triggerer" }, @@ -291,6 +352,13 @@ "utc": "UTC (Tiempo Universal Coordinado)" }, "toaster": { + "bulkClear": { + "error": "Solicitud de Limpieza Masiva de {{resourceName}} Fallida", + "success": { + "description": "{{count}} {{resourceName}} han sido limpiados exitosamente. Claves: {{keys}}", + "title": "Solicitud de Limpieza Masiva de {{resourceName}} Enviada" + } + }, "bulkDelete": { "error": "Eliminar {{resourceName}} Request Fallido", "success": { @@ -298,6 +366,13 @@ "title": "Eliminar {{resourceName}} Request Enviado" } }, + "bulkUpdate": { + "error": "Solicitud de Actualización Masiva de {{resourceName}} Fallida", + "success": { + "description": "{{count}} {{resourceName}} han sido actualizados exitosamente. Claves: {{keys}}", + "title": "Solicitud de Actualización Masiva de {{resourceName}} Enviada" + } + }, "create": { "error": "Crear {{resourceName}} Request Fallido", "success": { @@ -327,10 +402,27 @@ } } }, + "tokenGeneration": { + "apiToken": "Token de API", + "cliToken": "Token de CLI", + "errorDescription": "Ocurrió un error al generar el token. Inténtalo de nuevo.", + "errorTitle": "Generación de Token Fallida", + "generate": "Generar", + "selectType": "Selecciona el tipo de token a generar.", + "title": "Generar Token", + "tokenExpiresIn": "Este token expira en {{duration}}.", + "tokenGenerated": "Tu token ha sido generado.", + "tokenShownOnce": "Este token solo se mostrará una vez. Cópialo ahora." + }, "total": "Total {{state}}", "triggered": "Activado", "tryNumber": "Intento Número", "user": "Usuario", + "validation": { + "mustBeAtLeast": "Debe ser al menos {{min}}.", + "mustBeValidNumber": "Debe ser un número válido." + }, + "value": "Valor", "wrap": { "hotkey": "w", "tooltip": "Presiona {{hotkey}} para alternar el 'envolver'", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json index de515551a737e..75a32c161834a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/components.json @@ -11,8 +11,12 @@ "maxRuns": "Máximo de Ejecuciones Activas", "missingAndErroredRuns": "Ejecutaciones Faltantes y con Errores", "missingRuns": "Ejecutaciones Faltantes", + "overrideExistingParams": "Sobrescribir parámetros en ejecuciones existentes", + "permissionDenied": "Ejecución en Seco Fallida: el usuario no tiene permiso para crear backfills.", "reprocessBehavior": "Comportamiento de Reprocesamiento", "run": "Ejecutar Backfill", + "scheduleNotBackfillable": "La programación de este Dag no admite backfills", + "schedulerPriorityHint": "Las ejecuciones del Dag de backfill se ordenan después de las ejecuciones del Dag que no son backfill en cada ciclo del programador. Las ejecuciones de backfill pueden permanecer en cola más tiempo si hay otras ejecuciones que no son backfill presentes.", "selectDescription": "Ejecutar este Dag para un rango de fechas", "selectLabel": "Backfill", "title": "Ejecutar Backfill", @@ -44,14 +48,19 @@ "invalidJson": "Formato JSON inválido: {{errorMessage}}" }, "dagWarnings": { - "error_many": "Errores", "error_one": "1 Error", - "error_other": "Errores", "errorAndWarning": "1 Error y {{warningText}}", "warning_many": "{{count}} Advertencias", "warning_one": "1 Advertencia", "warning_other": "{{count}} Advertencias" }, + "dateRangeFilter": { + "validation": { + "invalidDateFormat": "Formato de fecha inválido.", + "invalidTimeFormat": "Formato de hora inválido.", + "startBeforeEnd": "La fecha/hora inicial debe ser anterior a la fecha/hora final" + } + }, "durationChart": { "duration": "Duración (segundos)", "lastDagRun_many": "Últimas {{count}} Ejecuciones de Dag", @@ -70,6 +79,7 @@ "files_other": "{{count}} archivos" }, "flexibleForm": { + "durationPlaceholder": "Ingresa la duración en formato ISO 8601", "placeholder": "Seleccionar Valor", "placeholderArray": "Ingrese cada cadena en una nueva línea", "placeholderExamples": "Comience a escribir para ver opciones", @@ -77,6 +87,7 @@ "validationErrorArrayNotArray": "El valor debe ser un array.", "validationErrorArrayNotNumbers": "Todos los elementos en el array deben ser números.", "validationErrorArrayNotObject": "Todos los elementos en el array deben ser objetos.", + "validationErrorDuration": "Formato de duración ISO 8601 inválido", "validationErrorRequired": "Este campo es requerido" }, "graph": { @@ -91,7 +102,8 @@ "taskCount_many": "{{count}} Tareas", "taskCount_one": "{{count}} Tarea", "taskCount_other": "{{count}} Tareas", - "taskGroup": "Grupo de Tareas" + "taskGroup": "Grupo de Tareas", + "zoomToTask": "Zoom a la tarea seleccionada" }, "limitedList": "+{{count}} más", "limitedList.allItems": "Todos los {{count}} elementos:", @@ -113,22 +125,40 @@ "sortedDescending": "ordenado descendente", "sortedUnsorted": "sin ordenar", "taskTries": "Intentos de Tarea", + "taskTryPlaceholder": "Intento de Tarea", + "team": { + "selector": { + "helperText": "Opcional. Restringe el uso a un equipo específico.", + "label": "Equipo", + "placeHolder": "Seleccionar un equipo" + } + }, "toggleCardView": "Mostrar vista de tarjeta", "toggleTableView": "Mostrar vista de tabla", "triggerDag": { "button": "Trigger", + "dataInterval": "Intervalo de Datos", + "dataIntervalAuto": "Inferido de la Fecha Lógica y la Programación", + "dataIntervalManual": "Especificar Manualmente", + "intervalEnd": "Fin", + "intervalStart": "Inicio", "loading": "Cargando información del Dag...", "loadingFailed": "Error al cargar la información del Dag. Por favor, inténtelo de nuevo.", + "manualRunDenied": "Las ejecuciones manuales no están permitidas para este Dag", "runIdHelp": "Opcional - se generará si no se proporciona", "selectDescription": "Activar una ejecución única de este Dag", "selectLabel": "Ejecución Única", "title": "Activar Dag", "toaster": { + "error": { + "title": "Error al Activar el Dag" + }, "success": { "description": "La ejecución del Dag ha sido activada exitosamente.", "title": "Ejecución del Dag Activada" } }, + "triggerAgainWithConfig": "Activar de nuevo con esta configuración", "unpause": "Reanudar {{dagDisplayName}} al activarse" }, "trimText": { @@ -144,6 +174,7 @@ "versionId": "ID de la Versión" }, "versionSelect": { + "allVersions": "Todas las Versiones", "dagVersion": "Versión del Dag", "versionCode": "v{{versionCode}}" } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json index 9a4f6549d36bf..005fdeed444d0 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json @@ -40,17 +40,52 @@ "parseDuration": "Duración del parseo:", "parsedAt": "Parseado en:" }, + "deadlineAlerts": { + "completionRule": "Debe completarse dentro de {{interval}} de {{reference}}", + "count_many": "{{count}} plazos", + "count_one": "{{count}} plazos", + "count_other": "{{count}} plazos", + "referenceType": { + "AverageRuntimeDeadline": "duración promedio de ejecución", + "DagRunLogicalDateDeadline": "fecha lógica", + "DagRunQueuedAtDeadline": "hora de cola" + } + }, + "deadlineStatus": { + "actual": "Real", + "expected": "Esperado", + "finishedEarly": "Finalizado {{duration}} antes del plazo", + "finishedLate": "Finalizado {{duration}} después del plazo", + "label": "Plazo", + "met": "Cumplido", + "missed": "Incumplido", + "missedCount_many": "{{count}} Plazos Incumplidos", + "missedCount_one": "{{count}} Plazos Incumplidos", + "missedCount_other": "{{count}} Plazos Incumplidos", + "mixedCount": "{{missedCount}} Incumplidos, {{upcomingCount}} Próximos", + "stillRunning": "Aún en ejecución", + "upcoming": "Próximos", + "upcomingCount_many": "{{count}} Plazos Próximos", + "upcomingCount_one": "{{count}} Plazos Próximos", + "upcomingCount_other": "{{count}} Plazos Próximos" + }, "extraLinks": "Enlaces Extra", "grid": { "buttons": { + "newerRuns": "Ejecuciones más recientes", + "olderRuns": "Ejecuciones más antiguas", "resetToLatest": "Reiniciar a la última", "toggleGroup": "Alternar grupo" - } + }, + "runTypeLegend": "Leyenda de Tipo de Ejecución" }, "header": { "buttons": { "advanced": "Avanzado", "dagDocs": "Documentacion del Dag" + }, + "status": { + "deactivated": "Desactivado" } }, "logs": { @@ -59,20 +94,28 @@ "critical": "CRÍTICO", "debug": "DEPURACIÓN", "error": "ERROR", - "fullscreen": { - "button": "Pantalla completa", - "tooltip": "Presiona {{hotkey}} para pantalla completa" - }, "info": "INFO", "noTryNumber": "No hay número de intento", + "search": { + "matchCount": "{{current}} de {{total}}", + "noMatches": "Sin coincidencias", + "placeholder": "Buscar en logs..." + }, "settings": "Configuración de logs", "viewInExternal": "Ver logs en {{name}} (intento {{attempt}})", "warning": "ADVERTENCIA" }, "navigation": { "navigation": "Navegación: Shift+{{arrow}}", + "openGraphFilters": "Filtros de Tareas: Ctrl+Shift+F", "toggleGroup": "Alternar grupo: Espacio" }, + "notFound": { + "back": "Volver", + "backToDags": "Volver a Dags", + "message": "El Dag \"{{dagId}}\" no existe.", + "title": "Dag No Encontrado" + }, "overview": { "buttons": { "failedRun_many": "Ejecuciones Fallidas", @@ -90,6 +133,10 @@ "assetEvent_one": "Evento de Asset Creado", "assetEvent_other": "Eventos de Asset Creados" }, + "deadlines": { + "showAll": "Mostrar Todo", + "title": "Plazos" + }, "failedLogs": { "hideLogs": "Ocultar Logs", "showLogs": "Mostrar Logs", @@ -118,6 +165,45 @@ }, "graphDirection": { "label": "Dirección del Gráfico" + }, + "graphFilters": { + "clearFilters": "Limpiar Filtros", + "durationGte": "Duración mín. (s)", + "durationGteHint": "Para tareas mapeadas, mide la duración total en todas las instancias", + "mapIndex": "Map Index mín.", + "mapIndexHint": "Muestra tareas mapeadas expandidas al menos hasta este índice", + "selectStatus": "Seleccionar estado", + "selectTaskGroup": "Seleccionar grupo de tareas", + "title": "Filtros de Tareas" + }, + "showVersionIndicator": { + "label": "Mostrar Indicador de Versión", + "options": { + "hideAll": "Ocultar Todo", + "showAll": "Mostrar Todo", + "showBundleVersion": "Mostrar Versión del Bundle", + "showDagVersion": "Mostrar Versión del Dag" + } + }, + "taskStreamFilter": { + "activeFilter": "Filtro activo", + "clearFilter": "Limpiar Filtro", + "clickTask": "Haz clic en una tarea para seleccionarla como raíz del filtro", + "depth": "Profundidad", + "direction": "Dirección", + "label": "Filtro", + "mode": "Modo", + "modeTooltip": "El modo Estático mantiene la vista actual al navegar a diferentes tareas, mientras que el modo Recorrer actualiza automáticamente el filtro activo a la tarea en la que se hace clic para facilitar el recorrido del Dag.", + "modes": { + "static": "Estático", + "traverse": "Recorrer" + }, + "options": { + "both": "Upstream y Downstream", + "downstream": "Downstream", + "upstream": "Upstream" + }, + "selectedTask": "Tarea seleccionada" } }, "paramsFailed": "Error al cargar los parámetros", @@ -148,12 +234,34 @@ "renderedTemplates": "Plantillas Renderizadas", "requiredActions": "Acciones Requeridas", "runs": "Ejecuciones", + "storage": "Almacenamiento", "taskInstances": "Instancias de Tarea", + "taskStateStore": "Almacenamiento de Estado de Tarea", "tasks": "Tareas", "xcom": "XCom" }, "taskGroups": { "collapseAll": "Colapsar todos los grupos de tareas", "expandAll": "Expandir todos los grupos de tareas" + }, + "taskStateStore": { + "add": "Agregar Almacenamiento de Estado de Tarea", + "clearAll": { + "resource": "todo el almacenamiento de estado de tarea", + "title": "Limpiar Todo el Almacenamiento de Estado de Tarea", + "warning": "Se borrará todo el almacenamiento de estado de tarea. Las tareas que usan este almacenamiento para hacer seguimiento de trabajo externo no podrán reanudarlo sin volver a ejecutarse desde cero." + }, + "delete": "Eliminar Almacenamiento de Estado de Tarea", + "deleteWarning": "La tarea perderá esta memoria persistente. Si la tarea usa esta clave para hacer seguimiento de trabajo externo (p. ej., un ID de trabajo externo), no podrá reanudarlo.", + "edit": "Editar Almacenamiento de Estado de Tarea", + "emptyStore": "El almacenamiento de estado de tarea almacena valores que persisten entre reintentos. Los workers pueden escribir en el almacenamiento de estado de tarea mediante el Task SDK.", + "expiresAt": { + "column": "Expira en", + "custom": "Personalizado", + "default": "Predeterminado ({{interval}})", + "label": "Expiración", + "never": "Nunca" + }, + "title": "Almacenamiento de Estado de Tarea" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/dags.json index 353ae56534a77..e94092f3b470d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/dags.json @@ -34,6 +34,15 @@ "error": "Error al limpiar {{type}}", "title": "Limpiar {{type}}" }, + "clearAllMapped": { + "button": "Limpiar Todas las Tareas Mapeadas", + "buttonTooltip": "Presiona shift+c para limpiar todas las instancias de tarea mapeadas", + "title": "Limpiar Todas las Instancias de Tarea Mapeadas" + }, + "confirmationDialog": { + "description": "La tarea está actualmente en estado {{state}}, iniciada por el usuario {{user}} a las {{time}}. \nEl usuario no puede limpiar esta tarea hasta que termine de ejecutarse o hasta que desmarque la opción \"Evitar reejecución si la tarea está en ejecución\" en el diálogo de limpiar tarea.", + "title": "No Se Puede Limpiar la Instancia de Tarea" + }, "delete": { "button": "Eliminar {{type}}", "dialog": { @@ -61,6 +70,7 @@ "future": "Futuro", "onlyFailed": "Limpiar solo tareas fallidas", "past": "Pasado", + "preventRunningTasks": "Evitar reejecución si la tarea está en ejecución", "queueNew": "Poner en cola nuevas tareas", "runOnLatestVersion": "Ejecutar en la última versión del bundle", "upstream": "Upstream" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/dashboard.json index 9c055a4a33451..d5aa4923ddc09 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/dashboard.json @@ -1,4 +1,18 @@ { + "deadlines": { + "pending": { + "empty": "No hay plazos próximos", + "title": "Próximos" + }, + "recentlyMissed": { + "empty": "No hay plazos incumplidos", + "title": "Plazos Incumplidos" + }, + "showMore": "Mostrar más", + "title": "Plazos" + }, + "deferredSlotsNotCounted": "Diferidos no contados en slots: {{count}}", + "deferredSlotsNotCountedTooltip": "Las tareas diferidas mostradas en la barra se cuentan contra los slots del pool. Las tareas diferidas mostradas debajo de la barra provienen de pools que no cuentan las tareas diferidas contra los slots.", "favorite": { "favoriteDags_many": "Primeros {{count}} Dags Favoritos", "favoriteDags_one": "Primer {{count}} Dag Favorito", @@ -31,7 +45,8 @@ "poolSlots": "Slots del Pool", "sortBy": { "newestFirst": "Más Recientes", - "oldestFirst": "Más Antiguos" + "oldestFirst": "Más Antiguos", + "placeholder": "Ordenar por" }, "source": "Origen", "stats": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/es/hitl.json index 028a59e1be9f1..5a2256747818b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/es/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/hitl.json @@ -1,8 +1,7 @@ { "filters": { "body": "Cuerpo", - "createdAtFrom": "Creado Desde", - "createdAtTo": "Creado Hasta", + "createdAt": "Creado en", "response": { "all": "Todas", "pending": "Pendientes", @@ -27,6 +26,20 @@ "success": "Respuesta de {{taskId}} exitosa", "title": "Instancia de Tarea Humana - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "Selecciona una acción requerida para ver detalles" + }, + "list": { + "completedRequiredActions": "Acciones requeridas completadas ({{count}})", + "loadError": "No se pudieron cargar las acciones requeridas", + "loadingActions": "Cargando acciones requeridas...", + "pendingRequiredActions": "Acciones requeridas pendientes ({{count}})" + }, + "openReviewDrawer": "Abrir Panel de Revisión", + "pageLimitHint": "Solo se muestran aquí las primeras acciones. Usa \"$t(review.viewAll)\" para ver todas.", + "viewAll": "Ver todas las acciones requeridas" + }, "state": { "approvalReceived": "Aprobación recibida", "approvalRequired": "Aprobación requerida", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json index 2365ae65cd967..745fed9941935 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/admin.json @@ -184,6 +184,7 @@ "title": "Ignorer" } }, + "parsingFile": "Analyse du fichier...", "title": "Importer des Variables", "upload": "Soumettre un Fichier JSON", "uploadPlaceholder": "Soumettre un fichier JSON contenant des variables (par exemple, {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/assets.json index ad18565147ecf..cfa77103bd725 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/assets.json @@ -3,6 +3,22 @@ "asset_many": "Assets", "asset_one": "Asset", "asset_other": "Assets", + "assetStateStore": { + "add": "Ajouter un stockage d'état d'Asset", + "clearAll": { + "resource": "tout le stockage d'état d'Asset", + "title": "Effacer tout le stockage d'état d'Asset", + "warning": "Tout le stockage d'état d'Asset sera effacé. Les tâches qui utilisent ce stockage pour coordonner leur travail perdront leur mémoire persistée." + }, + "delete": "Supprimer le stockage d'état d'Asset", + "deleteWarning": "L'Asset perdra cette entrée de stockage d'état persistée.", + "edit": "Modifier le stockage d'état d'Asset", + "emptyState": "Le stockage d'état d'Asset stocke des valeurs liées à l'identité d'un Asset, partagées entre toutes les exécutions de Dag. Les workers peuvent écrire dans le stockage d'état d'Asset via le Task SDK.", + "lastUpdatedBy": "Dernière mise à jour par", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Watcher", + "title": "Stockage d'état d'Asset" + }, "consumingDags": "Dags consomatteurs", "consumingTasks": "Tâches consommatrices", "createEvent": { @@ -26,6 +42,7 @@ }, "title": "Créer un événement d'Asset pour {{name}}" }, + "events": "Événements", "extra": "Extra", "group": "Group", "lastAssetEvent": "Dernier événement d'Asset", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/browse.json index 173c8450fbf98..80c8ee092c119 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/browse.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/browse.json @@ -11,6 +11,25 @@ }, "title": "Journal d'Audit" }, + "deadlines": { + "columns": { + "alertName": "Nom de l'alerte", + "deadlineTime": "Heure de l'échéance", + "status": "Statut" + }, + "deadline_many": "Échéances", + "deadline_one": "Échéance", + "deadline_other": "Échéances", + "filters": { + "status": "Statut", + "statusOptions": { + "all": "Toutes", + "missed": "Manquée", + "pending": "En attente" + } + }, + "title": "Échéances" + }, "xcom": { "add": { "error": "Échec de l'ajout du XCom", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json index a38f02cda9cdc..c883b8a016ff0 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/common.json @@ -20,11 +20,15 @@ "assetEvent_many": "Événements d'Asset", "assetEvent_one": "Événement d'Asset", "assetEvent_other": "Événements d'Asset", + "assetInactive": { + "tooltip": "L'Asset en amont a été désactivé ; le planificateur suspend l'évaluation des partitions jusqu'à sa réactivation." + }, "backfill_many": "Rattrapages", "backfill_one": "Rattrapage", "backfill_other": "Rattrapages", "browse": { "auditLog": "Journal d'audit", + "deadlines": "Échéances", "jobs": "Travaux", "requiredActions": "Actions requises", "xcoms": "XComs" @@ -73,6 +77,7 @@ "expectedDuration": "Durée Attendue", "lastSchedulingDecision": "Dernière décision de planification", "mappedPartitionKey": "Clé de partition mappée", + "partitionDate": "Date de partition", "partitionKey": "Clé de partition", "queuedAt": "Mis en file à", "runAfter": "Exécuté après", @@ -147,7 +152,11 @@ "selectDateRange": "Sélectionner une plage de dates", "startTime": "Heure de début" }, + "fullscreen": { + "tooltip": "Appuyez sur {{hotkey}} pour le plein écran" + }, "generateToken": "Générer un jeton", + "key": "Clé", "logicalDate": "Date logique", "logout": "Déconnexion", "logoutConfirmation": "Vous êtes sur le point de vous déconnecter de l'application.", @@ -177,10 +186,14 @@ "note": { "add": "Ajouter une note", "dagRun": "Note d'exécution du Run", + "edit": "Modifier la note", "label": "Note", "placeholder": "Ajouter une note...", - "taskInstance": "Note de Task Instance" + "preview": "Aperçu", + "taskInstance": "Note de Task Instance", + "write": "Écrire" }, + "overallStatus": "Statut global", "partitionedDagRun_many": "Exécutions de Dag partitionnées", "partitionedDagRun_one": "Exécution de Dag partitionnée", "partitionedDagRun_other": "Exécutions de Dag partitionnées", @@ -221,6 +234,47 @@ }, "selectLanguage": "Choisir la langue", "selected": "Sélectionné", + "shortcuts": { + "categories": { + "code": "Code", + "dagView": "Vue Dag", + "filters": "Filtres", + "global": "Général", + "logs": "Journaux", + "navigation": "Navigation", + "runActions": "Actions de Run et de tâche", + "search": "Recherche" + }, + "descriptions": { + "clearRun": "Effacer $t(dagRun_one)", + "clearTaskInstance": "Effacer $t(taskInstance_one)", + "downloadLogs": "Télécharger les journaux", + "focusFilterSearch": "Cibler la recherche de filtres", + "focusLogSearch": "Rechercher dans les journaux", + "focusSearch": "Cibler la recherche", + "markRunFailed": "Marquer $t(dagRun_one) comme échoué", + "markRunSuccess": "Marquer $t(dagRun_one) comme réussi", + "markTaskFailed": "Marquer $t(task_one) comme échoué", + "markTaskGroupFailed": "Marquer $t(taskGroup_one) comme échoué", + "markTaskGroupSuccess": "Marquer $t(taskGroup_one) comme réussi", + "markTaskSuccess": "Marquer $t(task_one) comme réussi", + "navigateTasks": "Naviguer entre les $t(task_other)", + "openGraphFilters": "Ouvrir les filtres du graphe", + "scrollBottom": "Défiler vers le bas", + "scrollTop": "Défiler vers le haut", + "searchDags": "Rechercher des $t(dag_other)", + "showHelp": "Afficher $t(shortcuts.title)", + "toggleExpand": "Développer ou réduire tous les groupes", + "toggleFullscreen": "Basculer le plein écran", + "toggleGraphGrid": "Basculer entre la vue graphe et grille", + "toggleSource": "Basculer la source", + "toggleTaskGroup": "Développer ou réduire $t(taskGroup_one)", + "toggleTimestamp": "Basculer les horodatages", + "toggleWrap": "Basculer $t(wrap.wrap)" + }, + "empty": "Aucun raccourci clavier n'est disponible sur cette page.", + "title": "Raccourcis clavier" + }, "showDetailsPanel": "Afficher le panneau des détails", "signedInAs": "Connecté en tant que", "source": { @@ -234,6 +288,7 @@ "startDate": "Date de début", "state": "État", "states": { + "awaiting_input": "En attente de saisie", "deferred": "Différé", "failed": "Échoué", "no_status": "Aucun statut", @@ -267,26 +322,35 @@ "any": "N'importe lequel" }, "tagPlaceholder": "Filtrer par tag", - "to": "À" + "to": "À", + "updatedAt": "Mis à jour le" }, "task": { + "dependsOnPast": "Dépend du passé", "documentation": "Documentation de la tâche", "lastInstance": "Dernière instance", "operator": "Opérateur", - "triggerRule": "Règle de déclenchement" + "retries": "Tentatives", + "triggerRule": "Règle de déclenchement", + "waitForDownstream": "Attendre l'aval" }, "task_many": "Tâches", "task_one": "Tâche", "task_other": "Tâches", + "taskGroup": { + "documentation": "Documentation du groupe de tâches" + }, "taskGroup_many": "Groupes de tâches", "taskGroup_one": "Groupe de tâches", "taskGroup_other": "Groupes de tâches", "taskId": "ID de la tâche", "taskInstance": { + "additionalAttributes": "Attributs supplémentaires de l'instance de tâche", "dagVersion": "Version du Dag", "executor": "Exécuteur", "executorConfig": "Configuration de l'exécuteur", "hostname": "Nom d'hôte", + "id": "ID", "maxTries": "Essais max.", "pid": "PID", "pool": "Pool", @@ -296,11 +360,13 @@ "queuedWhen": "Mis en file à", "renderedMapIndex": "Map Index rendu", "scheduledWhen": "Planifié à", + "trigger": "Déclencheur", "triggerer": { "assigned": "Déclencheur assigné", "class": "Classe de déclencheur", "createdAt": "Heure de création du déclencheur", "id": "ID du déclencheur", + "job": "Job du déclencheur", "latestHeartbeat": "Dernier battement du déclencheur", "title": "Infos sur le déclencheur" }, @@ -398,6 +464,7 @@ "mustBeAtLeast": "Doit être au moins {{min}}.", "mustBeValidNumber": "Doit être un nombre valide." }, + "value": "Valeur", "wrap": { "hotkey": "w", "tooltip": "Appuyez sur {{hotkey}} pour activer/désactiver le retour à la ligne", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json index 8ccdaf1aa352d..b8bffe0ad0cc6 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/components.json @@ -16,6 +16,7 @@ "reprocessBehavior": "Comportement de réexécution", "run": "Lancer le rattrapage", "scheduleNotBackfillable": "La planification de ce Dag ne prend pas en charge les rattrapages", + "schedulerPriorityHint": "Les exécutions de Dag de rattrapage sont ordonnées après les exécutions de Dag hors rattrapage à chaque cycle du planificateur. Les exécutions de rattrapage peuvent rester en file plus longtemps si d'autres exécutions hors rattrapage sont présentes.", "selectDescription": "Exécuter ce Dag pour une plage de dates", "selectLabel": "Rattrapage", "title": "Lancer un rattrapage", @@ -68,6 +69,7 @@ "lastTaskInstance_many": "Dernières {{count}} Task Instances", "lastTaskInstance_one": "Dernière Task Instance", "lastTaskInstance_other": "Dernières {{count}} Task Instances", + "medianTotalDuration": "Total : {{duration}}", "queuedDuration": "Durée en file d'attente", "runAfter": "Exécuté après", "runDuration": "Durée d'exécution" @@ -78,6 +80,7 @@ "files_other": "{{count}} fichiers" }, "flexibleForm": { + "durationPlaceholder": "Saisissez la durée au format ISO 8601", "placeholder": "Sélectionner une valeur", "placeholderArray": "Entrez chaque mot sur une ligne séparée", "placeholderExamples": "Commencez à taper pour voir les options", @@ -85,6 +88,7 @@ "validationErrorArrayNotArray": "La valeur doit être un tableau.", "validationErrorArrayNotNumbers": "Tous les éléments du tableau doivent être des nombres.", "validationErrorArrayNotObject": "Tous les éléments du tableau doivent être des objets.", + "validationErrorDuration": "Format de durée ISO 8601 invalide", "validationErrorRequired": "Ce champ est requis" }, "graph": { @@ -142,6 +146,7 @@ "loading": "Chargement des informations du Dag...", "loadingFailed": "Échec du chargement des informations du Dag. Veuillez réessayer.", "manualRunDenied": "Les exécutions manuelles ne sont pas autorisées pour ce Dag", + "partitionKeyHelp": "Optionnel - s'applique uniquement aux Dags partitionnés", "runIdHelp": "Optionnel – sera généré s'il n'est pas fourni", "selectDescription": "Déclencher une exécution unique de ce Dag", "selectLabel": "Exécution unique", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json index de7952e02204c..2d01b4dacb9a5 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json @@ -94,10 +94,6 @@ "critical": "CRITIQUE", "debug": "DÉBOGAGE", "error": "ERREUR", - "fullscreen": { - "button": "Plein écran", - "tooltip": "Appuyez sur {{hotkey}} pour le plein écran" - }, "info": "INFO", "noTryNumber": "Aucun essai", "search": { @@ -109,11 +105,6 @@ "viewInExternal": "Voir les journaux dans {{name}} (tentative {{attempt}})", "warning": "AVERTISSEMENT" }, - "navigation": { - "navigation": "Navigation : {{arrow}}", - "openGraphFilters": "Filtres de tâches : Ctrl+Maj+F", - "toggleGroup": "Basculer le groupe : Espace" - }, "notFound": { "back": "Retour", "backToDags": "Retour aux Dags", @@ -238,12 +229,34 @@ "renderedTemplates": "Modèles rendus", "requiredActions": "Actions requises", "runs": "Runs", + "storage": "Stockage", "taskInstances": "Task Instances", + "taskStateStore": "Stockage d'état de tâche", "tasks": "Tâches", "xcom": "XCom" }, "taskGroups": { "collapseAll": "Réduire tous les groupes de tâches", "expandAll": "Développer tous les groupes de tâches" + }, + "taskStateStore": { + "add": "Ajouter un stockage d'état de tâche", + "clearAll": { + "resource": "tout le stockage d'état de tâche", + "title": "Effacer tout le stockage d'état de tâche", + "warning": "Tout le stockage d'état de tâche sera effacé. Les tâches qui utilisent ce stockage pour suivre un travail externe ne pourront pas reprendre sans être ré-exécutées depuis le début." + }, + "delete": "Supprimer le stockage d'état de tâche", + "deleteWarning": "La tâche perdra cette mémoire persistée. Si la tâche utilise cette clé pour suivre un travail externe (par exemple un ID de job externe), elle ne pourra pas le reprendre.", + "edit": "Modifier le stockage d'état de tâche", + "emptyStore": "Le stockage d'état de tâche stocke des valeurs qui persistent entre les tentatives. Les workers peuvent écrire dans le stockage d'état de tâche via le Task SDK.", + "expiresAt": { + "column": "Expire le", + "custom": "Personnalisé", + "default": "Par défaut ({{interval}})", + "label": "Expiration", + "never": "Jamais" + }, + "title": "Stockage d'état de tâche" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dags.json index 4580c1b9eb958..f39c5c377fc83 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "Tous les types de Run", "allStates": "Tous les états", + "anyRunState": "N'importe quel Run", "favorite": { "all": "Tous", "favorite": "Favoris", "unfavorite": "Non favoris" }, + "lastRunState": "Dernier Run", "paused": { "active": "Actif", "all": "Tous", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json index f61c92b57063a..3821c8df53db2 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dashboard.json @@ -1,4 +1,25 @@ { + "alerts": { + "seeLessContext": "Voir moins", + "seeMoreContext": "Voir plus", + "showMoreAlerts_many": "+{{count}} alertes supplémentaires", + "showMoreAlerts_one": "+{{count}} alerte supplémentaire", + "showMoreAlerts_other": "+{{count}} alertes supplémentaires" + }, + "deadlines": { + "pending": { + "empty": "Aucune échéance à venir", + "title": "À venir" + }, + "recentlyMissed": { + "empty": "Aucune échéance manquée", + "title": "Échéances manquées" + }, + "showMore": "Voir plus", + "title": "Échéances" + }, + "deferredSlotsNotCounted": "Différées non comptées dans les slots : {{count}}", + "deferredSlotsNotCountedTooltip": "Les tâches différées affichées dans la barre sont comptées dans les slots des Pools. Les tâches différées affichées sous la barre proviennent de Pools qui ne comptent pas les tâches différées dans les slots.", "favorite": { "favoriteDags_many": "{{count}} premiers Dags favoris", "favoriteDags_one": "{{count}} premier Dag favori", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json index 2265ec154cd30..a8f28ce879ab5 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/hitl.json @@ -26,6 +26,20 @@ "success": "Réponse pour {{taskId}} réussie", "title": "Instance de tâche humaine - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "Sélectionnez une action requise pour voir les détails" + }, + "list": { + "completedRequiredActions": "Actions requises terminées ({{count}})", + "loadError": "Impossible de charger les actions requises", + "loadingActions": "Chargement des actions requises...", + "pendingRequiredActions": "Actions requises en attente ({{count}})" + }, + "openReviewDrawer": "Ouvrir le panneau de revue", + "pageLimitHint": "Seules les premières actions sont affichées ici. Utilisez « $t(review.viewAll) » pour toutes les voir.", + "viewAll": "Voir toutes les actions requises" + }, "state": { "approvalReceived": "Approbation reçue", "approvalRequired": "Approbation requise", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json index 7cd7b4fa91bf3..3587bcd775b7c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/admin.json @@ -184,6 +184,7 @@ "title": "דלג" } }, + "parsingFile": "מנתח קובץ...", "title": "ייבא משתנים", "upload": "העלה קובץ JSON", "uploadPlaceholder": "העלה קובץ JSON המכיל משתנים (לדוגמה, {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json index eadc6bea75ab0..0c463ee2dd85a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/assets.json @@ -2,6 +2,22 @@ "additional_data": "נתונים נוספים", "asset_many": "נכסים", "asset_one": "נכס", + "assetStateStore": { + "add": "הוסף מאגר מצבי נכסים", + "clearAll": { + "resource": "כל מאגר מצבי הנכסים", + "title": "נקה את כל מאגר מצבי הנכסים", + "warning": "כל מאגר מצבי הנכסים יימחק. משימות שמשתמשות במאגר זה לתיאום עבודה יאבדו את הזיכרון השמור שלהן." + }, + "delete": "מחק מאגר מצבי נכסים", + "deleteWarning": "הנכס יאבד רשומה זו ממאגר המצבים.", + "edit": "ערוך מאגר מצבי נכסים", + "emptyState": "מאגר מצבי הנכסים שומר ערכים בהקשר של זהות נכס, המשותפים לכל הרצות ה-Dags. עובדים יכולים לכתוב למאגר מצבי הנכסים באמצעות Task SDK.", + "lastUpdatedBy": "עודכן לאחרונה על-ידי", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Watcher", + "title": "מאגר מצבי נכסים" + }, "consumingDags": "צורכים Dags", "consumingTasks": "משימות צורכות", "createEvent": { @@ -25,6 +41,7 @@ }, "title": "יצירת אירוע בנכס עבור {{name}}" }, + "events": "אירועים", "extra": "תוכן", "group": "קבוצה", "lastAssetEvent": "אירוע אחרון בנכס", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json index cfef74cab1eba..5f9c660058bc2 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/common.json @@ -8,6 +8,7 @@ "Variables": "משתנים" }, "allOperators": "כל האופרטורים", + "allTeams": "כל הצוותים", "appearance": { "appearance": "מראה", "darkMode": "מצב כהה", @@ -62,7 +63,8 @@ "owner": "בעלים", "params": "פרמטרים", "schedule": "תזמון", - "tags": "תגיות" + "tags": "תגיות", + "team": "צוות" }, "dagId": "מזהה Dag", "dagRun": { @@ -77,6 +79,7 @@ "expectedDuration": "משך זמן צפוי", "lastSchedulingDecision": "החלטת תזמון אחרונה", "mappedPartitionKey": "מפתח חלוקה ממופה", + "partitionDate": "תאריך חלוקה", "partitionKey": "מפתח חלוקה", "queuedAt": "זמן כניסה לתור", "runAfter": "ריצה לאחר", @@ -151,7 +154,11 @@ "selectDateRange": "בחר טווח תאריכים", "startTime": "זמן התחלה" }, + "fullscreen": { + "tooltip": "לחץ {{hotkey}} למסך מלא" + }, "generateToken": "צור אסימון", + "key": "מפתח", "logicalDate": "תאריך לוגי", "logout": "התנתק", "logoutConfirmation": "האם אתה בטוח שברצונך להתנתק?", @@ -181,10 +188,14 @@ "note": { "add": "הוסף הערה", "dagRun": "הערת הרצת Dag", + "edit": "ערוך הערה", "label": "הערה", "placeholder": "הוסף הערה...", - "taskInstance": "הערת משימה" + "preview": "תצוגה מקדימה", + "taskInstance": "הערת משימה", + "write": "כתיבה" }, + "overallStatus": "סטטוס כללי", "partitionedDagRun_one": "הרצת Dag מחולקת", "partitionedDagRun_other": "הרצות Dag מחולקות", "partitionedDagRun_two": "הרצות Dag מחולקות", @@ -194,6 +205,23 @@ "pendingDagRun_one": "{{count}} הרצת Dag ממתינה", "pendingDagRun_other": "{{count}} הרצות Dag ממתינות", "pendingDagRun_two": "{{count}} הרצות Dag ממתינות", + "presetFilters": { + "deleteTitle": "מחק מסנן מוגדר מראש", + "deleteWarning": "מסננים מוגדרים מראש נשמרים בדפדפן זה בלבד.", + "duplicate": "למסנן המוגדר מראש \"{{name}}\" כבר יש הגדרה זהה.", + "empty": "אין עדיין מסננים מוגדרים מראש", + "info": { + "default": "נעץ מסנן מוגדר מראש כברירת מחדל, והוא יוחל אוטומטית בכל כניסה לדף זה ללא מסננים פעילים.", + "save": "שמור את המסננים והמיון הנוכחיים כמסנן מוגדר מראש בעל שם, וחזור אליו בכל עת.", + "storage": "מסננים מוגדרים מראש נשמרים בדפדפן זה." + }, + "namePlaceholder": "שם המסנן המוגדר מראש", + "nothingToSave": "אין מה לשמור. החל מסננים או מיון כדי לשמור מסנן מוגדר מראש.", + "save": "שמור", + "setDefault": "הגדר כברירת מחדל", + "title": "מסננים מוגדרים מראש", + "unsetDefault": "בטל ברירת מחדל" + }, "reset": "אתחל", "runId": "מזהה ריצה", "runTypes": { @@ -225,6 +253,47 @@ }, "selectLanguage": "בחר שפה", "selected": "נבחר", + "shortcuts": { + "categories": { + "code": "קוד", + "dagView": "תצוגת Dag", + "filters": "מסננים", + "global": "כללי", + "logs": "רישומים", + "navigation": "ניווט", + "runActions": "פעולות ריצה ומשימה", + "search": "חיפוש" + }, + "descriptions": { + "clearRun": "נקה $t(dagRun_one)", + "clearTaskInstance": "נקה $t(taskInstance_one)", + "downloadLogs": "הורד רישומים", + "focusFilterSearch": "מיקוד בחיפוש מסננים", + "focusLogSearch": "חפש ברישומים", + "focusSearch": "מיקוד בחיפוש", + "markRunFailed": "סמן $t(dagRun_one) ככשלון", + "markRunSuccess": "סמן $t(dagRun_one) כהצלחה", + "markTaskFailed": "סמן $t(task_one) ככשלון", + "markTaskGroupFailed": "סמן $t(taskGroup_one) ככשלון", + "markTaskGroupSuccess": "סמן $t(taskGroup_one) כהצלחה", + "markTaskSuccess": "סמן $t(task_one) כהצלחה", + "navigateTasks": "נווט בין $t(task_other)", + "openGraphFilters": "פתח מסנני גרף", + "scrollBottom": "גלול לתחתית הדף", + "scrollTop": "גלול לראש הדף", + "searchDags": "חפש $t(dag_other)", + "showHelp": "הצג $t(shortcuts.title)", + "toggleExpand": "הרחב או כווץ את כל הקבוצות", + "toggleFullscreen": "הפעל/כבה מסך מלא", + "toggleGraphGrid": "החלף בין תצוגת גרף לתצוגת רשת", + "toggleSource": "הצג/הסתר מקור", + "toggleTaskGroup": "הרחב או כווץ $t(taskGroup_one)", + "toggleTimestamp": "הצג/הסתר חותמות זמן", + "toggleWrap": "הפעל/כבה גלישת טקסט" + }, + "empty": "אין קיצורי מקלדת זמינים בדף זה.", + "title": "קיצורי מקלדת" + }, "showDetailsPanel": "הצג לוח פרטים", "signedInAs": "מחובר כ", "source": { @@ -267,18 +336,23 @@ "from": "מ-", "maxActiveRuns": "מספר הרצות פעילות מרבי", "noTagsFound": "לא נמצאו תגיות", + "noTeamsFound": "לא נמצאו צוותים", "tagMode": { "all": "הכל", "any": "כלשהו" }, "tagPlaceholder": "סנן לפי תגית", - "to": "עד" + "to": "עד", + "updatedAt": "עודכן בתאריך" }, "task": { + "dependsOnPast": "תלוי בעבר", "documentation": "תיעוד משימה", "lastInstance": "משימה אחרונה", "operator": "אופרטור", - "triggerRule": "כלל הפעלה" + "retries": "ניסיונות חוזרים", + "triggerRule": "כלל הפעלה", + "waitForDownstream": "המתן למשימות במורד הזרם" }, "task_one": "משימה", "task_other": "משימות", @@ -291,10 +365,12 @@ "taskGroup_two": "קבוצות משימות", "taskId": "מזהה משימה", "taskInstance": { + "additionalAttributes": "מאפייני מופע משימה נוספים", "dagVersion": "גרסת Dag", "executor": "Executor", "executorConfig": "הגדרות Executor", "hostname": "שם מארח", + "id": "מזהה", "maxTries": "מספר נסיונות מרבי", "pid": "מזהה תהליך", "pool": "מאגר משאבים", @@ -304,11 +380,13 @@ "queuedWhen": "זמן כניסה לתור", "renderedMapIndex": "אינדקס מיפוי מעובד", "scheduledWhen": "מועד תזמון", + "trigger": "מפעיל", "triggerer": { "assigned": "מפעיל מוקצה", "class": "סוג מפעיל", "createdAt": "זמן יצירת מפעיל", "id": "מזהה מפעיל", + "job": "עבודת מפעיל", "latestHeartbeat": "אות חיים אחרון", "title": "פרטי מפעיל" }, @@ -406,6 +484,7 @@ "mustBeAtLeast": "חייב להיות {{min}} לפחות.", "mustBeValidNumber": "חייב להיות מספר תקין." }, + "value": "ערך", "wrap": { "hotkey": "w", "tooltip": "לחץ {{hotkey}} להפעלת/כיבוי גלישת טקסט", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json index 5b4b186125870..0f149da0c4087 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/components.json @@ -69,6 +69,7 @@ "lastTaskInstance_one": "מופע משימה אחרונה", "lastTaskInstance_other": "{{count}} מופעי משימות אחרונות", "lastTaskInstance_two": "שני מופעי משימות אחרונות", + "medianTotalDuration": "סה״כ: {{duration}}", "queuedDuration": "זמן המתנה בתור", "runAfter": "הרץ אחרי", "runDuration": "משך זמן ריצה" @@ -145,6 +146,7 @@ "loading": "טוען מידע Dag...", "loadingFailed": "טעינת מידע ה-Dag נכשלה. אנא נסו שוב.", "manualRunDenied": "הרצות ידניות אינן מותרות עבור Dag זה", + "partitionKeyHelp": "אופציונלי - רלוונטי רק ל-Dags מחולקים", "runIdHelp": "אופציונלי - ייווצר אוטומטית אם לא יסופק", "selectDescription": "הפעל ריצה בודדת של Dag זה", "selectLabel": "ריצה בודדת", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json index 0214ee911024e..c1ee6c8493b98 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json @@ -109,11 +109,6 @@ "viewInExternal": "צפה ברישומים ב-{{name}} (ניסיון {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "ניווט: {{arrow}}", - "openGraphFilters": "פילטרים משימות: Ctrl+Shift+F", - "toggleGroup": "החלפת קבוצה: רווח" - }, "notFound": { "back": "חזור", "backToDags": "חזור ל-Dags", @@ -238,12 +233,34 @@ "renderedTemplates": "תבניות מעובדות", "requiredActions": "פעולות נדרשות", "runs": "הרצות", + "storage": "אחסון", "taskInstances": "מופעי משימות", + "taskStateStore": "מאגר מצבי משימות", "tasks": "משימות", "xcom": "XCom" }, "taskGroups": { "collapseAll": "כווץ את כל קבוצות המשימות", "expandAll": "הרחב את כל קבוצות המשימות" + }, + "taskStateStore": { + "add": "הוסף מאגר מצבי משימות", + "clearAll": { + "resource": "כל מאגר מצבי המשימות", + "title": "נקה את כל מאגר מצבי המשימות", + "warning": "כל מאגר מצבי המשימות יימחק. משימות שמשתמשות במאגר זה למעקב אחר עבודה חיצונית לא יוכלו להמשיך ללא הרצה מחדש מאפס." + }, + "delete": "מחק מאגר מצבי משימות", + "deleteWarning": "המשימה תאבד את הזיכרון השמור הזה. אם המשימה משתמשת במפתח זה למעקב אחר עבודה חיצונית (לדוגמה, מזהה עבודה חיצוני), היא לא תוכל להמשיך אותה.", + "edit": "ערוך מאגר מצבי משימות", + "emptyStore": "מאגר מצבי המשימות שומר ערכים הנשמרים בין ניסיונות חוזרים. עובדים יכולים לכתוב למאגר מצבי המשימות באמצעות Task SDK.", + "expiresAt": { + "column": "תקף עד", + "custom": "מותאם אישית", + "default": "ברירת מחדל ({{interval}})", + "label": "תפוגה", + "never": "לעולם לא" + }, + "title": "מאגר מצבי משימות" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/dags.json index 48d53f5a8e3d6..08432feed09ec 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "כל סוגי הריצות", "allStates": "כל המצבים", + "anyRunState": "ריצה כלשהי", "favorite": { "all": "הכל", "favorite": "מועדף", "unfavorite": "לא מועדף" }, + "lastRunState": "ריצה אחרונה", "paused": { "active": "פעיל", "all": "הכל", @@ -76,6 +78,11 @@ "upstream": "במעלה הזרם" } }, + "runStateCounts": { + "label": "מצבי ריצה", + "loading": "טוען ספירת מצבי ריצה", + "tooltip": "{{state}}: {{formattedCount}} — לחץ כדי לסנן ריצות" + }, "search": { "advanced": "חיפוש מתקדם", "clear": "נקה חיפוש", @@ -88,6 +95,10 @@ "asc": "מיין לפי שם תצוגה (A-Z)", "desc": "מיין לפי שם תצוגה (Z-A)" }, + "lastRunAfter": { + "asc": "מיין לפי ריצה לאחר של הריצה האחרונה (מהמוקדם למאוחר)", + "desc": "מיין לפי ריצה לאחר של הריצה האחרונה (מהמאוחר למוקדם)" + }, "lastRunStartDate": { "asc": "מיין לפי תאריך התחלת ריצה אחרון (מהמוקדם למאוחר)", "desc": "מיין לפי תאריך התחלת ריצה אחרון (מהמאוחר למוקדם)" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json index bb3fbe5414644..945925d0ede8c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dashboard.json @@ -1,4 +1,23 @@ { + "alerts": { + "seeLessContext": "הצג פחות", + "seeMoreContext": "הצג עוד", + "showMoreAlerts_one": "+{{count}} התראה נוספת", + "showMoreAlerts_other": "+{{count}} התראות נוספות", + "showMoreAlerts_two": "+{{count}} התראות נוספות" + }, + "deadlines": { + "pending": { + "empty": "אין מועדים קרובים", + "title": "קרובים" + }, + "recentlyMissed": { + "empty": "אין מועדים שהוחמצו", + "title": "מועדים שהוחמצו" + }, + "showMore": "הצג עוד", + "title": "מועדים" + }, "deferredSlotsNotCounted": "משימות בהשהיה שלא נספרו במכסות: {{count}}", "deferredSlotsNotCountedTooltip": "משימות בהשהיה המוצגות בסרגל נספרות מול מכסות המאגר. משימות בהשהיה המוצגות מתחת לסרגל מגיעות ממאגרים שאינם סופרים משימות בהשהיה מול המכסות.", "favorite": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/he/hitl.json index 9d450c86b9b12..2e6f41bd33bd1 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/he/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/hitl.json @@ -26,6 +26,20 @@ "success": "התגובה של {{taskId}} הצליחה", "title": "מופע משימה ידנית - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "בחר פעולה נדרשת כדי לראות פרטים" + }, + "list": { + "completedRequiredActions": "פעולות נדרשות שהושלמו ({{count}})", + "loadError": "לא ניתן לטעון פעולות נדרשות", + "loadingActions": "טוען פעולות נדרשות...", + "pendingRequiredActions": "פעולות נדרשות ממתינות ({{count}})" + }, + "openReviewDrawer": "פתח מגירת סקירה", + "pageLimitHint": "כאן מוצגות רק הפעולות הראשונות. השתמש ב-\"$t(review.viewAll)\" כדי לראות את כולן.", + "viewAll": "הצג את כל הפעולות הנדרשות" + }, "state": { "approvalReceived": "האישור התקבל", "approvalRequired": "נדרש אישור", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json index cbd6a675e78dd..8e436ab7a4b0f 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "{{name}} में लॉग्स देखें (प्रयास {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "नेवीगेशन: Shift+{{arrow}}", - "openGraphFilters": "Task फ़िल्टर: Ctrl+Shift+F", - "toggleGroup": "ग्रुप टॉगल करें: Space" - }, "notFound": { "back": "वापस जाएं", "backToDags": "डैग्स पर वापस जाएं", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json index 62b7a4cb7907c..a4a8c1cb057bf 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "Naplók megtekintése itt: {{name}} (próbálkozás: {{attempt}})", "warning": "FIGYELMEZTETÉS" }, - "navigation": { - "navigation": "Navigáció: {{arrow}}", - "openGraphFilters": "Feladat szűrők: Ctrl+Shift+F", - "toggleGroup": "Csoport váltása: Szóköz" - }, "notFound": { "back": "Vissza", "backToDags": "Vissza a Dag-ekhez", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json index ed02653885be4..fba3b7d5fb178 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/admin.json @@ -177,6 +177,7 @@ "title": "건너뛰기" } }, + "parsingFile": "파일 구문 분석 중...", "title": "변수 가져오기", "upload": "JSON 파일 업로드", "uploadPlaceholder": "변수를 포함한 JSON 파일 업로드 (e.g., {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json index a27a19a400076..6e4a61f08c147 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/common.json @@ -72,6 +72,7 @@ "expectedDuration": "예상 소요 시간", "lastSchedulingDecision": "마지막 스케줄링 결정", "mappedPartitionKey": "매핑된 파티션 키", + "partitionDate": "파티션 날짜", "partitionKey": "파티션 키", "queuedAt": "대기열에 추가된 시간", "runAfter": "다음 실행", @@ -179,9 +180,12 @@ "note": { "add": "메모 추가", "dagRun": "Dag 실행 메모", + "edit": "메모 수정", "label": "메모", "placeholder": "메모 추가...", - "taskInstance": "태스크 인스턴스 메모" + "preview": "미리보기", + "taskInstance": "태스크 인스턴스 메모", + "write": "작성" }, "overallStatus": "전체 상태", "partitionedDagRun_one": "파티션된 Dag 실행", @@ -222,6 +226,47 @@ }, "selectLanguage": "언어 선택", "selected": "선택됨", + "shortcuts": { + "categories": { + "code": "코드", + "dagView": "Dag 뷰", + "filters": "필터", + "global": "전역", + "logs": "로그", + "navigation": "탐색", + "runActions": "Dag 실행 및 태스크 작업", + "search": "검색" + }, + "descriptions": { + "clearRun": "$t(dagRun_one) 지우기", + "clearTaskInstance": "$t(taskInstance_one) 지우기", + "downloadLogs": "로그 다운로드", + "focusFilterSearch": "필터 검색창 포커스", + "focusLogSearch": "로그 검색창 포커스", + "focusSearch": "검색창 포커스", + "markRunFailed": "$t(dagRun_one)을 실패로 표시", + "markRunSuccess": "$t(dagRun_one)을 성공으로 표시", + "markTaskFailed": "$t(task_one)를 실패로 표시", + "markTaskGroupFailed": "$t(taskGroup_one)을 실패로 표시", + "markTaskGroupSuccess": "$t(taskGroup_one)을 성공으로 표시", + "markTaskSuccess": "$t(task_one)를 성공으로 표시", + "navigateTasks": "$t(task_other) 탐색", + "openGraphFilters": "그래프 필터 열기", + "scrollBottom": "맨 아래로 스크롤", + "scrollTop": "맨 위로 스크롤", + "searchDags": "$t(dag_other) 검색", + "showHelp": "$t(shortcuts.title) 보기", + "toggleExpand": "모든 그룹 펼치기/접기", + "toggleFullscreen": "전체 화면 전환", + "toggleGraphGrid": "그래프 / 그리드 뷰 전환", + "toggleSource": "소스 보기/숨기기", + "toggleTaskGroup": "$t(taskGroup_one) 펼치기/접기", + "toggleTimestamp": "타임스탬프 보기/숨기기", + "toggleWrap": "$t(wrap.wrap) 설정/해제" + }, + "empty": "이 페이지에서 사용할 수 있는 키보드 단축키가 없습니다.", + "title": "키보드 단축키" + }, "showDetailsPanel": "세부 정보 패널 펼치기", "signedInAs": "로그인한 사용자", "source": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json index 8171b73685da0..77e0f84197461 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/components.json @@ -65,6 +65,7 @@ "lastDagRun_other": "마지막 {{count}}개 Dag 실행", "lastTaskInstance_one": "마지막 태스크 인스턴스", "lastTaskInstance_other": "마지막 {{count}}개 태스크 인스턴스", + "medianTotalDuration": "총: {{duration}}", "queuedDuration": "대기열 대기 시간", "runAfter": "실행 후", "runDuration": "실행 기간" @@ -136,6 +137,7 @@ "loading": "Dag 정보 로드 중...", "loadingFailed": "Dag 정보를 로드하지 못했습니다. 다시 시도해주세요.", "manualRunDenied": "이 Dag는 수동으로 실행할 수 없습니다.", + "partitionKeyHelp": "선택 사항 - 파티션된 Dag에만 적용됩니다.", "runIdHelp": "선택 사항 - 제공되지 않으면 생성됩니다.", "selectDescription": "이 Dag을(를) 단일 실행 트리거", "selectLabel": "단일 실행", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json index 30c09fb580417..0fb59ca71e13b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json @@ -42,6 +42,7 @@ }, "deadlineAlerts": { "completionRule": "{{reference}} 기준 {{interval}} 이내에 완료되어야 합니다", + "completionRuleDynamic": "{{reference}}를 기준으로 측정된 가변 시간 간격 내에 완료되어야 합니다", "count_one": "데드라인 {{count}}건", "count_other": "데드라인 {{count}}건", "referenceType": { @@ -102,11 +103,6 @@ "viewInExternal": "{{name}}에서 로그 보기 (시도 {{attempt}})", "warning": "경고" }, - "navigation": { - "navigation": "탐색: Shift+{{arrow}}", - "openGraphFilters": "태스크 필터: Ctrl+Shift+F", - "toggleGroup": "그룹 전환: Space" - }, "notFound": { "back": "뒤로", "backToDags": "Dags로 돌아가기", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dags.json index 6cf77d048e3ad..016fc47cafe3e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "모든 실행 유형", "allStates": "모든 상태", + "anyRunState": "하나 이상의 실행", "favorite": { "all": "전체", "favorite": "즐겨찾기", "unfavorite": "즐겨찾기 해제" }, + "lastRunState": "마지막 실행", "paused": { "active": "활성", "all": "모두", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dashboard.json index ff611d9718df3..651dab86befde 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dashboard.json @@ -1,4 +1,10 @@ { + "alerts": { + "seeLessContext": "접기", + "seeMoreContext": "더 보기", + "showMoreAlerts_one": "알림 +{{count}}개 더 보기", + "showMoreAlerts_other": "알림 +{{count}}개 더 보기" + }, "deadlines": { "pending": { "empty": "예정된 데드라인이 없습니다", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json index 3dd8fd0e5a417..e0c6993747bdf 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/hitl.json @@ -24,6 +24,20 @@ "success": "{{taskId}} 응답 성공", "title": "휴먼 태스크 인스턴스 - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "세부 정보를 보려면 필수 작업을 선택하세요" + }, + "list": { + "completedRequiredActions": "완료된 필수 작업 ({{count}})", + "loadError": "필수 작업을 로드하지 못했습니다", + "loadingActions": "필수 작업 로드 중...", + "pendingRequiredActions": "대기 중인 필수 작업 ({{count}})" + }, + "openReviewDrawer": "검토 패널 열기", + "pageLimitHint": "여기에는 처음 일부 작업만 표시됩니다. 전체를 보려면 \"$t(review.viewAll)\"를 사용하세요.", + "viewAll": "모든 필수 작업 보기" + }, "state": { "approvalReceived": "승인 수신됨", "approvalRequired": "승인 필요", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/assets.json index d1e5c14474902..e6cbf2a650085 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/assets.json @@ -2,6 +2,22 @@ "additional_data": "Extra data", "asset_many": "Assets", "asset_one": "Asset", + "assetStateStore": { + "add": "Voeg Asset State Store toe", + "clearAll": { + "resource": "Alle Asset State Stores", + "title": "Wis alle Asset State Stores", + "warning": "Alle Asset State Stores zullen worden gewist. Taken die deze store gebruiken om werk te coördineren, verliezen hun opgeslagen gegevens." + }, + "delete": "Verwijder Asset State Store", + "deleteWarning": "De asset zal deze opgeslagen store-invoer verliezen.", + "edit": "Bewerk Asset State Store", + "emptyState": "Asset state store slaat waarden op gescoped aan een asset identiteit, gedeeld over alle Dag runs. Workers kunnen naar de Asset State Store schrijven via de Task SDK.", + "lastUpdatedBy": "Laatst bijgewerkt door", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Watcher", + "title": "Asset State Store" + }, "consumingDags": "Consumerende Dags", "consumingTasks": "Consumerende taken", "createEvent": { @@ -25,6 +41,7 @@ }, "title": "Asset Event voor {{name}} aanmaken" }, + "events": "Events", "extra": "Extra", "group": "Groep", "lastAssetEvent": "Laatste Asset Event", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/browse.json index 134ef8fee798f..ddd2ece18369f 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/browse.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/browse.json @@ -11,6 +11,24 @@ }, "title": "Audit Log" }, + "deadlines": { + "columns": { + "alertName": "Alertnaam", + "deadlineTime": "Deadline tijd", + "status": "Status" + }, + "deadline_one": "Deadline", + "deadline_other": "Deadlines", + "filters": { + "status": "Status", + "statusOptions": { + "all": "Alles", + "missed": "Gemist", + "pending": "In afwachting" + } + }, + "title": "Deadlines" + }, "xcom": { "add": { "error": "Mislukt om XCom toe te voegen", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json index d4a33adbda7ad..f27c79562753b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/common.json @@ -18,10 +18,14 @@ "asset_other": "Assets", "assetEvent_one": "Asset Event", "assetEvent_other": "Asset Events", + "assetInactive": { + "tooltip": "Upstream asset is gedeactiveerd; de scheduler houdt partitie-evaluatie vast tot de asset het opnieuw wordt geactiveerd." + }, "backfill_one": "Backfill", "backfill_other": "Backfills", "browse": { "auditLog": "Audit Log", + "deadlines": "Deadlines", "jobs": "Jobs", "requiredActions": "Vereiste acties", "xcoms": "XComs" @@ -47,7 +51,7 @@ "latestDagVersion": "Laatste Dag versie", "latestRun": "Laatste Run", "maxActiveRuns": "Maximaal aantal actieve Runs", - "maxActiveTasks": "Maximaal aantal actieve Tasks", + "maxActiveTasks": "Maximaal aantal actieve taken", "maxConsecutiveFailedDagRuns": "Maximaal aantal opeenvolgend mislukte Dag Runs", "nextRun": "Volgende Run", "owner": "Eigenaar", @@ -141,7 +145,11 @@ "selectDateRange": "Selecteer datumbereik", "startTime": "Starttijd" }, + "fullscreen": { + "tooltip": "Druk op {{hotkey}} voor volledig scherm" + }, "generateToken": "Genereer token", + "key": "Sleutel", "logicalDate": "Logische datum", "logout": "Uitloggen", "logoutConfirmation": "Je staat op het punt om uit te loggen uit de applicatie.", @@ -171,10 +179,14 @@ "note": { "add": "Notitie toevoegen", "dagRun": "Dag Run notitie", + "edit": "Bewerk notitie", "label": "Notitie", "placeholder": "Voeg een notitie toe...", - "taskInstance": "Task Instance notitie" + "preview": "Voorbeeld", + "taskInstance": "Taakinstantie notitie", + "write": "Schrijf" }, + "overallStatus": "Algemene status", "partitionedDagRun_one": "Gepartitioneerde Dag Run", "partitionedDagRun_other": "Gepartitioneerde Dag Runs", "partitionedDagRunDetail": { @@ -198,6 +210,12 @@ }, "tooltip": "Druk op {{hotkey}} om te scrollen naar {{direction}}" }, + "search": { + "advanced": { + "description": "Zoek overal in de waarde (substring zoekopdracht). Langzamer bij grote deployments omdat het de standaard B-tree index niet kan gebruiken. Bekijk de documentatie sectie over aangepaste metadata-indexen voor details.", + "title": "Zoek overal" + } + }, "security": { "actions": "Acties", "permissions": "Permissies", @@ -219,6 +237,7 @@ "startDate": "Start datum", "state": "Status", "states": { + "awaiting_input": "Wachtend op invoer", "deferred": "Uitgesteld", "failed": "Mislukt", "no_status": "Geen status", @@ -237,36 +256,47 @@ "upstream_failed": "Upstream mislukt" }, "table": { - "completedAt": "Completed at", - "createdAt": "Created at", + "completedAt": "Voltooid op", + "createdAt": "Aangemaakt op", "filterByTag": "Filter Dags op label", "filterColumns": "Filter tabel kolommen", "filterReset_one": "Reset filter", "filterReset_other": "Reset filters", "from": "Van", - "maxActiveRuns": "Maximaal aantal active Runs", + "maxActiveRuns": "Maximaal aantal actieve Runs", "noTagsFound": "Geen labels gevonden", "tagMode": { "all": "All", "any": "Any" }, "tagPlaceholder": "Filter op label", - "to": "Naar" + "to": "Naar", + "updatedAt": "Bijgewerkt op" }, "task": { - "documentation": "Task documentatie", - "lastInstance": "Laatste Task Instance", + "dependsOnPast": "Afhankelijk van vorige", + "documentation": "Taak documentatie", + "lastInstance": "Laatste taakinstantie", "operator": "Operator", - "triggerRule": "Trigger regel" + "retries": "Pogingen", + "triggerRule": "Trigger regel", + "waitForDownstream": "Wacht op downstream" + }, + "task_one": "Taak", + "task_other": "Taken", + "taskGroup": { + "documentation": "Taaakgroep documentatie" }, - "task_one": "Task", - "task_other": "Tasks", - "taskId": "Task ID", + "taskGroup_one": "Taakgroep", + "taskGroup_other": "Taakgroepen", + "taskId": "Taak ID", "taskInstance": { + "additionalAttributes": "Extra taakinstantie attributen", "dagVersion": "Dag versie", "executor": "Executor", "executorConfig": "Executor Configuratie", "hostname": "Hostname", + "id": "ID", "maxTries": "Maximaal aantal pogingen", "pid": "PID", "pool": "Pool", @@ -274,19 +304,22 @@ "priorityWeight": "Prioriteitsgewicht", "queue": "Wachtrij", "queuedWhen": "In de wachtrij gezet om", + "renderedMapIndex": "Gerenderde Map index", "scheduledWhen": "Gepland om", + "trigger": "Trigger", "triggerer": { - "assigned": "Toegewegen Triggerer", + "assigned": "Toegewezen Triggerer", "class": "Trigger class", "createdAt": "Trigger aangemaakt op", "id": "Trigger ID", + "job": "Triggerer Job", "latestHeartbeat": "Laatste Triggerer hartslag", "title": "Triggerer informatie" }, "unixname": "Unix naam" }, - "taskInstance_one": "Task Instance", - "taskInstance_other": "Task Instances", + "taskInstance_one": "Taakinstantie", + "taskInstance_other": "Taakinstanties", "timeRange": { "last12Hours": "Laatste 12 uur", "last24Hours": "Laatste 24 uur", @@ -376,6 +409,7 @@ "mustBeAtLeast": "Moet minimaal {{min}} zijn.", "mustBeValidNumber": "Moet een geldig nummer zijn." }, + "value": "Waarde", "wrap": { "hotkey": "w", "tooltip": "Druk op {{hotkey}} om wrap te schakelen", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json index fb0a3f77950e4..763be83980afe 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json @@ -10,9 +10,12 @@ "maxRuns": "Maximaal aantal actieve Runs", "missingAndErroredRuns": "Missende en mislukte Runs", "missingRuns": "Missende Runs", + "overrideExistingParams": "Overschrijf parameters op bestaande runs", "permissionDenied": "Dry Run mislukt: Gebruiker heeft geen toestemming om backfills te maken.", "reprocessBehavior": "Reprocess gedrag", "run": "Run Backfill", + "scheduleNotBackfillable": "Het schema van deze Dag ondersteunt geen backfills", + "schedulerPriorityHint": "Backfill Dag runs worden geordend na niet-backfill Dag runs in elke scheduler cyclus. Backfill runs kunnen langer in de wachtrij blijven als er andere niet-backfill runs aanwezig zijn.", "selectDescription": "Draai deze Dag voor een geselecteerd datumbereik", "selectLabel": "Backfill", "title": "Run Backfill", @@ -57,11 +60,11 @@ } }, "durationChart": { - "duration": "Duur (seconds)", + "duration": "Duur (seconden)", "lastDagRun_one": "Laatste Dag Run", "lastDagRun_other": "Laatste {{count}} Dag Runs", - "lastTaskInstance_one": "Laatste Task Instance", - "lastTaskInstance_other": "Laatste {{count}} Task Instances", + "lastTaskInstance_one": "Laatste taakinstantie", + "lastTaskInstance_other": "Laatste {{count}} taakinstanties", "queuedDuration": "Duur in de wachtrij", "runAfter": "Run na", "runDuration": "Run duur" @@ -71,13 +74,15 @@ "files_other": "{{count}} bestanden" }, "flexibleForm": { + "durationPlaceholder": "Voer duur in ISO 8601 formaat in", "placeholder": "Selecteer waarde", "placeholderArray": "Voer elke string in op een nieuwe regel", "placeholderExamples": "Start met typen om opties te zien", - "placeholderMulti": "Selecteer een of meerder waarden", + "placeholderMulti": "Selecteer een of meerdere waarden", "validationErrorArrayNotArray": "Waarde moet een array zijn.", "validationErrorArrayNotNumbers": "Alle elementen in de array moeten nummers zijn.", "validationErrorArrayNotObject": "Alle elementen in de array moeten objecten zijn.", + "validationErrorDuration": "Ongeldig ISO 8601 duur-formaat", "validationErrorRequired": "Dit veld is verplicht" }, "graph": { @@ -89,9 +94,10 @@ "downloadImageError": "Mislukt om de afbeelding van de grafiek te downloaden.", "downloadImageErrorTitle": "Download mislukt", "otherDagRuns": "+Andere Dag Runs", - "taskCount_one": "{{count}} Task", - "taskCount_other": "{{count}} Tasks", - "taskGroup": "Task Group" + "taskCount_one": "{{count}} taak", + "taskCount_other": "{{count}} taken", + "taskGroup": "Taakgroep", + "zoomToTask": "Zoom naar geselecteerde taak" }, "limitedList": "+{{count}} meer", "limitedList.allItems": "Alle {{count}} items:", @@ -110,8 +116,8 @@ "sortedAscending": "oplopend gesorteerd", "sortedDescending": "aflopend gesorteerd", "sortedUnsorted": "ongesorteerd", - "taskTries": "Task pogingen", - "taskTryPlaceholder": "Task poging", + "taskTries": "Taakpogingen", + "taskTryPlaceholder": "Taakpoging", "team": { "selector": { "helperText": "Optioneel. Beperk het gebruik tot een specifiek team.", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json index b146e35ec870d..fda29c0f75fec 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json @@ -37,12 +37,40 @@ "code": { "bundleUrl": "Bundle URL", "noCode": "Geen code gevonden", - "parseDuration": "Parse duur:", + "parseDuration": "Vewrwerkingsduur:", "parsedAt": "Geparsed op:" }, + "deadlineAlerts": { + "completionRule": "Moet worden voltooid binnen {{interval}} van {{reference}}", + "count_one": "{{count}} deadline", + "count_other": "{{count}} deadlines", + "referenceType": { + "AverageRuntimeDeadline": "Gemiddelde uitvoertijd", + "DagRunLogicalDateDeadline": "Logische datum", + "DagRunQueuedAtDeadline": "Wachttijd" + } + }, + "deadlineStatus": { + "actual": "Werkelijk", + "expected": "Verwacht", + "finishedEarly": "Voltooid {{duration}} voor de deadline", + "finishedLate": "Voltooid {{duration}} na de deadline", + "label": "Deadline", + "met": "Behaald", + "missed": "Gemist", + "missedCount_one": "{{count}} Gemiste deadline", + "missedCount_other": "{{count}} Gemiste deadlines", + "mixedCount": "{{missedCount}} gemist, {{upcomingCount}} opkomend", + "stillRunning": "Nog bezig", + "upcoming": "Opkomend", + "upcomingCount_one": "{{count}} opkomende deadline", + "upcomingCount_other": "{{count}} opkomende deadlines" + }, "extraLinks": "Extra Links", "grid": { "buttons": { + "newerRuns": "Nieuwere runs", + "olderRuns": "Oudere runs", "resetToLatest": "Reset naar laatste", "toggleGroup": "Groepen omschakelen" }, @@ -52,6 +80,9 @@ "buttons": { "advanced": "Geavanceerd", "dagDocs": "Dag Docs" + }, + "status": { + "deactivated": "Gedeactiveerd" } }, "logs": { @@ -60,18 +91,20 @@ "critical": "CRITICAL", "debug": "DEBUG", "error": "ERROR", - "fullscreen": { - "button": "Volledig scherm", - "tooltip": "Druk {{hotkey}} voor volledig scherm" - }, "info": "INFO", "noTryNumber": "Geen poging nummer", + "search": { + "matchCount": "{{current}} van {{total}}", + "noMatches": "Geen overeenkomsten", + "placeholder": "Zoek in logs..." + }, "settings": "Loginstellingen", - "viewInExternal": "Bekijk logs in {{name}} (attempt {{attempt}})", + "viewInExternal": "Bekijk logs in {{name}} (poging {{attempt}})", "warning": "WARNING" }, "navigation": { "navigation": "Navigatie: {{arrow}}", + "openGraphFilters": "Taakfilters: Ctrl+Shift+F", "toggleGroup": "Groep in-/uitklappen: Spatie" }, "notFound": { @@ -84,19 +117,23 @@ "buttons": { "failedRun_one": "Mislukte Run", "failedRun_other": "Mislukte Runs", - "failedTask_one": "Mislukte Task", - "failedTask_other": "Mislukte Tasks", - "failedTaskInstance_one": "Mislukte Task Instance", - "failedTaskInstance_other": "Mislukte Task Instances" + "failedTask_one": "Mislukte taak", + "failedTask_other": "Mislukte taken", + "failedTaskInstance_one": "Mislukte taakinstantie", + "failedTaskInstance_other": "Mislukte taakinstanties" }, "charts": { "assetEvent_one": "Aangemaakte Asset Event", "assetEvent_other": "Aangemaakte Asset Events" }, + "deadlines": { + "showAll": "Toon alles", + "title": "Deadlines" + }, "failedLogs": { "hideLogs": "Verberg logs", "showLogs": "Toon logs", - "title": "Recente mislukte Task logs", + "title": "Recente mislukte taaklogs", "viewFullLogs": "Bekijk volledige logs" } }, @@ -115,13 +152,23 @@ "options": { "allDagDependencies": "Alle Dag afhankelijkheden", "externalConditions": "Externe omstandigheden", - "onlyTasks": "Alleen Rasks" + "onlyTasks": "Alleen taken" }, "placeholder": "Afhankelijkheden" }, "graphDirection": { "label": "Richting van de grafiek" }, + "graphFilters": { + "clearFilters": "Wis filters", + "durationGte": "Minimale duur (s)", + "durationGteHint": "Voor gemapte taken, meet de totale duur over alle instanties", + "mapIndex": "Min. map index", + "mapIndexHint": "Toont gemapte taken uitgebreid tot ten minste deze index", + "selectStatus": "Selecteer status", + "selectTaskGroup": "Selecteer taakgroep", + "title": "Taakfilters" + }, "showVersionIndicator": { "label": "Toon versie-indicator", "options": { @@ -173,18 +220,40 @@ "code": "Code", "details": "Details", "logs": "Logs", - "mappedTaskInstances_one": "Task Instance [{{count}}]", - "mappedTaskInstances_other": "Task Instances [{{count}}]", + "mappedTaskInstances_one": "Taakinstantie [{{count}}]", + "mappedTaskInstances_other": "Taakinstanties [{{count}}]", "overview": "Overzicht", "renderedTemplates": "Gerenderde templates", "requiredActions": "Vereiste acties", "runs": "Runs", - "taskInstances": "Task Instances", - "tasks": "Tasks", + "storage": "Opslag", + "taskInstances": "Taakinstanties", + "taskStateStore": "Task State Store", + "tasks": "Taken", "xcom": "XCom" }, "taskGroups": { - "collapseAll": "Alle Task Groups inklappen", - "expandAll": "Alle Task Groups uitklappen" + "collapseAll": "Alle taakgroepen inklappen", + "expandAll": "Alle taakgroepen uitklappen" + }, + "taskStateStore": { + "add": "Voeg Task State Store toe", + "clearAll": { + "resource": "Alle Task State Stores", + "title": "Wis alle Task State Stores", + "warning": "Alle Task State Stores zullen worden gewist. Taken die deze store gebruiken om extern werk bij te houden, kunnen niet worden hervat zonder opnieuw te starten vanaf het begin." + }, + "delete": "Verwijder Task State Store", + "deleteWarning": "De taak zal dit persistente geheugen verliezen. Als de taak deze sleutel gebruikt om extern werk bij te houden (bijv. een extern job-ID), kan het niet worden hervat.", + "edit": "Wijzig Task State Store", + "emptyStore": "Task state store slaat waarden op die persistent blijven over retries. Workers kunnen task state store schrijven via de Task SDK.", + "expiresAt": { + "column": "Verloopt op", + "custom": "Aangepast", + "default": "Standaard ({{interval}})", + "label": "Verloopdatum", + "never": "Nooit" + }, + "title": "Task State Store" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dags.json index e349aeb471c80..1e52b6075fb53 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dags.json @@ -25,8 +25,8 @@ "ownerLink": "Eigenaarslink voor {{owner}}", "runAndTaskActions": { "affectedTasks": { - "noItemsFound": "Geen Tasks gevonden.", - "title": "Affected Tasks: {{count}}" + "noItemsFound": "Geen taken gevonden.", + "title": "Beïnvloede taken: {{count}}" }, "clear": { "button": "Wis {{type}}", @@ -34,9 +34,14 @@ "error": "Mislukt om {{type}} te wissen", "title": "Wis {{type}}" }, + "clearAllMapped": { + "button": "Wis alle gemapte taken", + "buttonTooltip": "Druk op Shift+C om alle gemapte taakinstanties te wissen", + "title": "Wis alle gemapte taakinstanties" + }, "confirmationDialog": { - "description": "Taak is momenteel in een {{state}} status gestart door gebruiker {{user}} op {{time}}. \nDe gebruiker kan deze taak niet wissen totdat deze klaar is met uitvoeren of een gebruiker de optie \"Voorkom opnieuw uitvoeren als task bezig is\" in het dialoogvenster voor het wissen van taken uitschakelt.", - "title": "Kan Task Instance niet wissen" + "description": "Taak is momenteel in een {{state}} status gestart door gebruiker {{user}} op {{time}}. \nDe gebruiker kan deze taak niet wissen totdat deze klaar is met uitvoeren of een gebruiker de optie \"Voorkom opnieuw uitvoeren als taak bezig is\" in het dialoogvenster voor het wissen van taken uitschakelt.", + "title": "Kan taakinstanties niet wissen" }, "delete": { "button": "Verwijder {{type}}", @@ -52,7 +57,7 @@ } }, "markAs": { - "button": "Makeer {{type}} als ...", + "button": "Markeer {{type}} als ...", "buttonTooltip": { "failed": "Druk op Shift+F om te markeren als mislukt", "success": "Druk op Shift+S om te markeren als succesvol" @@ -61,12 +66,12 @@ }, "options": { "downstream": "Downstream", - "existingTasks": "Wis bestaande Tasks", + "existingTasks": "Wis bestaande taken", "future": "Toekomst", - "onlyFailed": "Wis enkel mislukte Tasks", + "onlyFailed": "Wis enkel mislukte taken", "past": "Verleden", - "preventRunningTasks": "Voorkom opnieuw uitvoeren als task bezig is", - "queueNew": "Zet nieuwe Tasks in de wachtrij", + "preventRunningTasks": "Voorkom opnieuw uitvoeren als taak bezig is", + "queueNew": "Zet nieuwe taken in de wachtrij", "runOnLatestVersion": "Voer uit met de nieuwste bundelversie", "upstream": "Upstream" } @@ -76,7 +81,7 @@ "clear": "Zoekopdracht wissen", "dags": "Zoek Dags", "hotkey": "+K", - "tasks": "Zoek Tasks" + "tasks": "Zoek taken" }, "sort": { "displayName": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dashboard.json index 62b0c6953649f..650290ed0f757 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dashboard.json @@ -1,4 +1,18 @@ { + "deadlines": { + "pending": { + "empty": "Geen aankomende deadlines", + "title": "Aankomende deadlines" + }, + "recentlyMissed": { + "empty": "Geen gemiste deadlines", + "title": "Gemiste deadlines" + }, + "showMore": "Toon meer", + "title": "Deadlines" + }, + "deferredSlotsNotCounted": "Uitgestelde taken niet meegeteld als sloten: {{count}}", + "deferredSlotsNotCountedTooltip": "Uitgestelde taken die in de balk worden weergegeven, worden meegeteld in de poolsloten. Uitgestelde taken die onder de balk worden weergegeven, zijn afkomstig van pools die uitgestelde taken niet in de sloten meetellen.", "favorite": { "favoriteDags_one": "Eerste {{count}} favoriete Dags", "favoriteDags_other": "Eerste {{count}} favoriete Dags", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/hitl.json index 2748dff18c2d4..03ae3a04a4150 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/hitl.json @@ -24,6 +24,20 @@ "success": "{{taskId}} reactie succesvol", "title": "Human Task Instance - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "Selecteer een vereiste actie om details te zien" + }, + "list": { + "completedRequiredActions": "Voltooide vereiste acties ({{count}})", + "loadError": "Kan vereiste acties niet laden", + "loadingActions": "Vereiste acties laden...", + "pendingRequiredActions": "In afwachting van vereiste acties ({{count}})" + }, + "openReviewDrawer": "Open Review Drawer", + "pageLimitHint": "Alleen de eerste paar acties worden hier weergegeven. Gebruik \"$t(review.viewAll)\" om ze allemaal te zien.", + "viewAll": "Bekijk alle vereiste acties" + }, "state": { "approvalReceived": "Goedkeuring ontvangen", "approvalRequired": "Goedkeuring vereist", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json index eb569300a98e2..84868e951310b 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/admin.json @@ -191,6 +191,7 @@ "title": "Pomiń" } }, + "parsingFile": "Przetwarzanie pliku...", "title": "Importuj zmienne", "upload": "Prześlij plik JSON", "uploadPlaceholder": "Prześlij plik JSON zawierający zmienne (np. {\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/assets.json index 7a16a402475dc..09b340eafba24 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/assets.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/assets.json @@ -4,18 +4,21 @@ "asset_many": "Zasobów", "asset_one": "Zasób", "asset_other": "Zasoby", - "assetStore": { - "add": "Dodaj magazyn zasobów", + "assetStateStore": { + "add": "Dodaj wpis magazynu stanu zasobu", "clearAll": { - "resource": "cały magazyn zasobów", - "title": "Wyczyść cały magazyn zasobów", - "warning": "Cały magazyn zasobów zostanie wyczyszczony. Zadania, które używają tego magazynu do koordynowania pracy, utracą swoje zapisane dane." + "resource": "całego magazynu stanu zasobu", + "title": "Wyczyść cały magazyn stanu zasobu", + "warning": "Cały magazyn stanu zasobu zostanie wyczyszczony. Zadania, które używają go do koordynacji pracy, utracą zachowane dane." }, - "delete": "Usuń magazyn zasobów", - "deleteWarning": "Zasób utraci ten zapisany wpis magazynu.", - "edit": "Edytuj magazyn zasobów", - "emptyState": "Magazyn zasobów przechowuje wartości powiązane z identyfikatorem zasobu, współdzielone między wszystkimi uruchomieniami Dagów. Procesy robocze mogą zapisywać do magazynu zasobów za pomocą Task SDK.", - "title": "Magazyn zasobów" + "delete": "Usuń wpis magazynu stanu zasobu", + "deleteWarning": "Zasób utraci ten zachowany wpis magazynu stanu.", + "edit": "Edytuj wpis magazynu stanu zasobu", + "emptyState": "Magazyn stanu zasobu przechowuje wartości przypisane do tożsamości zasobu, współdzielone przez wszystkie wykonania Dagów. Workery mogą zapisywać do magazynu stanu zasobu przez Task SDK.", + "lastUpdatedBy": "Ostatnio zaktualizowane przez", + "lastUpdatedByApi": "API", + "lastUpdatedByWatcher": "Watcher", + "title": "Magazyn stanu zasobu" }, "consumingDags": "Przetwarzanie Dagów", "consumingTasks": "Przetwarzanie zadań", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json index 4ea9fde38493d..9a96058635f1d 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/common.json @@ -82,6 +82,7 @@ "expectedDuration": "Oczekiwany Czas Trwania", "lastSchedulingDecision": "Ostatnia decyzja harmonogramu", "mappedPartitionKey": "Zmapowany klucz partycji", + "partitionDate": "Data partycji", "partitionKey": "Klucz partycji", "queuedAt": "Zakolejkowano o", "runAfter": "Wykonaj po", @@ -157,6 +158,9 @@ "selectDateRange": "Wybierz zakres dat", "startTime": "Czas rozpoczęcia" }, + "fullscreen": { + "tooltip": "Naciśnij {{hotkey}}, aby przejść na pełny ekran" + }, "generateToken": "Wygeneruj token", "key": "Klucz", "logicalDate": "Data logiczna", @@ -188,9 +192,12 @@ "note": { "add": "Dodaj notatkę", "dagRun": "Notatki wykonania", + "edit": "Edytuj notatkę", "label": "Notatka", "placeholder": "Dodaj notatkę...", - "taskInstance": "Notatka instancji zadania" + "preview": "Podgląd", + "taskInstance": "Notatka instancji zadania", + "write": "Napisz" }, "overallStatus": "Stan ogólny", "partitionedDagRun_few": "Partycjonowane wykonania Dagów", @@ -235,6 +242,47 @@ }, "selectLanguage": "Wybierz język", "selected": "Wybrano", + "shortcuts": { + "categories": { + "code": "Kod", + "dagView": "Widok Daga", + "filters": "Filtry", + "global": "Globalne", + "logs": "Logi", + "navigation": "Nawigacja", + "runActions": "Akcje wykonań i zadań", + "search": "Wyszukiwanie" + }, + "descriptions": { + "clearRun": "Wyczyść wykonanie", + "clearTaskInstance": "Wyczyść instancję zadania", + "downloadLogs": "Pobierz logi", + "focusFilterSearch": "Przejdź do wyszukiwania filtrów", + "focusLogSearch": "Szukaj w logach", + "focusSearch": "Przejdź do wyszukiwania", + "markRunFailed": "Oznacz wykonanie jako nieudane", + "markRunSuccess": "Oznacz wykonanie jako udane", + "markTaskFailed": "Oznacz zadanie jako nieudane", + "markTaskGroupFailed": "Oznacz grupę zadań jako nieudaną", + "markTaskGroupSuccess": "Oznacz grupę zadań jako udaną", + "markTaskSuccess": "Oznacz zadanie jako udane", + "navigateTasks": "Nawiguj po zadaniach", + "openGraphFilters": "Otwórz filtry grafu", + "scrollBottom": "Przewiń do dołu", + "scrollTop": "Przewiń do góry", + "searchDags": "Szukaj Dagów", + "showHelp": "Pokaż skróty klawiszowe", + "toggleExpand": "Rozwiń lub zwiń wszystkie grupy", + "toggleFullscreen": "Przełącz pełny ekran", + "toggleGraphGrid": "Przełącz widok grafu / siatki", + "toggleSource": "Przełącz źródła", + "toggleTaskGroup": "Rozwiń lub zwiń grupę zadań", + "toggleTimestamp": "Przełącz znaczniki czasu", + "toggleWrap": "Przełącz zawijanie" + }, + "empty": "Na tej stronie nie ma dostępnych skrótów klawiszowych.", + "title": "Skróty klawiszowe" + }, "showDetailsPanel": "Pokaż panel szczegółów", "signedInAs": "Zalogowano jako", "source": { @@ -309,10 +357,12 @@ "taskGroup_other": "Grupy zadań", "taskId": "Identyfikator Zadania", "taskInstance": { + "additionalAttributes": "Dodatkowe atrybuty instancji zadania", "dagVersion": "Wersja Daga", "executor": "Wykonawca", "executorConfig": "Konfiguracja wykonawcy", "hostname": "Nazwa hosta", + "id": "ID", "maxTries": "Maksymalna liczba prób", "pid": "PID", "pool": "Pula", @@ -322,11 +372,13 @@ "queuedWhen": "Zakolejkowano o", "renderedMapIndex": "Wyrenderowany indeks mapowania", "scheduledWhen": "Zaplanowano o", + "trigger": "Wyzwalacz", "triggerer": { "assigned": "Przypisany wyzwalacz", "class": "Klasa wyzwalacza", "createdAt": "Czas utworzenia wyzwalacza", "id": "Identyfikator wyzwalacza", + "job": "Zadanie wyzwalacza", "latestHeartbeat": "Ostatni heartbeat wyzwalacza", "title": "Informacje o wyzwalaczu" }, diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json index ce3310c039186..b9846e160f3dc 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/components.json @@ -73,6 +73,7 @@ "lastTaskInstance_many": "Ostatnich {{count}} instancji zadania", "lastTaskInstance_one": "Ostatnia instancja zadania", "lastTaskInstance_other": "Ostatnie {{count}} instancje zadania", + "medianTotalDuration": "Łącznie: {{duration}}", "queuedDuration": "Czas oczekiwania", "runAfter": "Uruchom po", "runDuration": "Czas trwania wykonania" @@ -153,6 +154,7 @@ "loading": "Ładowanie informacji o Dagach...", "loadingFailed": "Nie udało się załadować informacji o Dagach. Spróbuj ponownie.", "manualRunDenied": "Ręczne uruchamianie nie jest dozwolone dla tego Daga", + "partitionKeyHelp": "Opcjonalne - dotyczy tylko Dagów partycjonowanych", "runIdHelp": "Opcjonalne - zostanie wygenerowane, jeśli nie podano", "selectDescription": "Wyzwól pojedyncze wykonanie", "selectLabel": "Pojedyncze wykonanie", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json index a8c500309f3d3..6b2369bb34cd9 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json @@ -97,10 +97,6 @@ "critical": "CRITICAL", "debug": "DEBUG", "error": "ERROR", - "fullscreen": { - "button": "Pełny ekran", - "tooltip": "Naciśnij {{hotkey}}, aby przejść do pełnego ekranu" - }, "info": "INFO", "noTryNumber": "Brak numeru próby", "search": { @@ -112,11 +108,6 @@ "viewInExternal": "Zobacz logi w {{name}} (próba {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "Przewiń: {{arrow}}", - "openGraphFilters": "Filtry zadań: Ctrl+Shift+F", - "toggleGroup": "Przełącz grupę: Space" - }, "notFound": { "back": "Wróć", "backToDags": "Powrót do Dagów", @@ -248,7 +239,7 @@ "runs": "Wykonania", "storage": "Magazyn", "taskInstances": "Instancje zadań", - "taskStore": "Magazyn zadań", + "taskStateStore": "Magazyn stanu zadania", "tasks": "Zadania", "xcom": "XCom" }, @@ -256,17 +247,17 @@ "collapseAll": "Zwiń wszystkie grupy zadań", "expandAll": "Rozwiń wszystkie grupy zadań" }, - "taskStore": { - "add": "Dodaj magazyn zadań", + "taskStateStore": { + "add": "Dodaj wpis magazynu stanu zadania", "clearAll": { - "resource": "cały magazyn zadań", - "title": "Wyczyść cały magazyn zadań", - "warning": "Cały magazyn zadań zostanie wyczyszczony. Zadania, które używają tego magazynu do śledzenia zewnętrznej pracy, nie będą mogły jej wznowić bez ponownego uruchomienia." + "resource": "całego magazynu stanu zadania", + "title": "Wyczyść cały magazyn stanu zadania", + "warning": "Cały magazyn stanu zadania zostanie wyczyszczony. Zadania, które używają go do śledzenia pracy zewnętrznej, nie będą mogły jej wznowić bez uruchomienia od nowa." }, - "delete": "Usuń magazyn zadań", - "deleteWarning": "Zadanie utraci te zapisane dane. Jeśli zadanie używa tego klucza do śledzenia zewnętrznej pracy (np. identyfikatora zewnętrznego zadania), nie będzie mogło jej wznowić.", - "edit": "Edytuj magazyn zadań", - "emptyStore": "Magazyn zadań przechowuje wartości, które są zachowywane między ponownymi próbami. Procesy robocze mogą zapisywać do magazynu zadań za pomocą Task SDK.", + "delete": "Usuń wpis magazynu stanu zadania", + "deleteWarning": "Zadanie utraci te zachowane dane. Jeśli używa tego klucza do śledzenia pracy zewnętrznej (np. zewnętrznego ID zadania), nie będzie mogło jej wznowić.", + "edit": "Edytuj wpis magazynu stanu zadania", + "emptyStore": "Magazyn stanu zadania przechowuje wartości zachowywane pomiędzy ponownymi próbami. Workery mogą zapisywać do magazynu stanu zadania przez Task SDK.", "expiresAt": { "column": "Wygasa o", "custom": "Niestandardowy", @@ -274,6 +265,6 @@ "label": "Wygaśnięcie", "never": "Nigdy" }, - "title": "Magazyn zadań" + "title": "Magazyn stanu zadania" } } diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json index 16f9916f6aaa4..1d2b3ae285e1f 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "Wszystkie Typy Wykonań Dagów", "allStates": "Wszystkie Stany", + "anyRunState": "Dowolne wykonanie", "favorite": { "all": "Wszystkie", "favorite": "Ulubione", "unfavorite": "Nieulubione" }, + "lastRunState": "Ostatnie wykonanie", "paused": { "active": "Aktywne", "all": "Wszystkie", @@ -89,8 +91,8 @@ "desc": "Sortuj według Nazwy Wyświetlanej (Z-A)" }, "lastRunStartDate": { - "asc": "Sortuj według Daty Rozpoczęcia Ostatniego Wykonania (Najwcześniejsze-Najnowsze)", - "desc": "Sortuj według Daty Rozpoczęcia Ostatniego Wykonania (Najnowsze-Najwcześniejsze)" + "asc": "Sortuj według Daty Ostatniego Wykonania (Najwcześniejsze-Najnowsze)", + "desc": "Sortuj według Daty Ostatniego Wykonania (Najnowsze-Najwcześniejsze)" }, "lastRunState": { "asc": "Sortuj według Stanu Ostatniego Wykonania (A-Z)", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dashboard.json index 9ef2ef1494f78..2ae2b6babd394 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dashboard.json @@ -1,4 +1,24 @@ { + "alerts": { + "seeLessContext": "Pokaż mniej", + "seeMoreContext": "Pokaż więcej", + "showMoreAlerts_few": "+{{count}} alerty więcej", + "showMoreAlerts_many": "+{{count}} alertów więcej", + "showMoreAlerts_one": "+{{count}} alert więcej", + "showMoreAlerts_other": "+{{count}} alerty więcej" + }, + "deadlines": { + "pending": { + "empty": "Brak nadchodzących terminów", + "title": "Nadchodzące" + }, + "recentlyMissed": { + "empty": "Brak niedotrzymanych terminów", + "title": "Niedotrzymane terminy" + }, + "showMore": "Pokaż więcej", + "title": "Terminy" + }, "deferredSlotsNotCounted": "Odłożone, ale nieliczone do slotów: {{count}}", "deferredSlotsNotCountedTooltip": "Odłożone zadania pokazane na pasku są liczone do slotów puli. Odłożone zadania pokazane pod paskiem pochodzą z pul, które liczą sloty, nie licząc odłożonych zadań.", "favorite": { @@ -18,7 +38,7 @@ "metaDatabase": "Baza Danych Meta", "scheduler": "Planer zadań", "status": "Stan", - "triggerer": "Cyngiel", + "triggerer": "Wyzwalacz", "unhealthy": "Nieprawidłowy" }, "history": "Historia", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json index 9ab8a3337522f..a8e9585e8bbff 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/hitl.json @@ -28,6 +28,20 @@ "success": "Odpowiedź dla {{taskId}} została pomyślnie wysłana", "title": "Instancja zadania wymagająca interwencji człowieka - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "Wybierz wymaganą akcję, aby zobaczyć szczegóły" + }, + "list": { + "completedRequiredActions": "Zakończone wymagane akcje ({{count}})", + "loadError": "Nie udało się załadować wymaganych akcji", + "loadingActions": "Ładowanie wymaganych akcji...", + "pendingRequiredActions": "Oczekujące wymagane akcje ({{count}})" + }, + "openReviewDrawer": "Otwórz panel recenzji", + "pageLimitHint": "Wyświetlono tutaj tylko kilka pierwszych akcji. Użyj \"$t(review.viewAll)\", aby zobaczyć wszystkie.", + "viewAll": "Zobacz wszystkie wymagane akcje" + }, "state": { "approvalReceived": "Zatwierdzenie otrzymane", "approvalRequired": "Wymagane zatwierdzenie", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json index 7770759b5e78e..60b91f86bfd61 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "Günlükleri {{name}} içinde görüntüle (deneme {{attempt}})", "warning": "UYARI" }, - "navigation": { - "navigation": "Gezin: {{arrow}}", - "openGraphFilters": "Görev Filtreleri: Ctrl+Shift+F", - "toggleGroup": "Grubu aç/kapat: Space" - }, "notFound": { "back": "Geri Dön", "backToDags": "Dag'lere Geri Dön", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json index 6e9664e06f944..bd7e7401a0aa1 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/admin.json @@ -177,6 +177,7 @@ "title": "非严格模式" } }, + "parsingFile": "正在解析文件...", "title": "导入变量", "upload": "上传 JSON 文件", "uploadPlaceholder": "上传包含变量的 JSON 文件 (例如:{\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json index 7db7f7939c2e5..786070010f730 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/common.json @@ -72,6 +72,7 @@ "expectedDuration": "预计耗时", "lastSchedulingDecision": "最后调度决策", "mappedPartitionKey": "映射分区键", + "partitionDate": "分区日期", "partitionKey": "分区键", "queuedAt": "开始排队时间", "runAfter": "最早可执行时间", @@ -145,6 +146,9 @@ "selectDateRange": "选择日期范围", "startTime": "开始时间" }, + "fullscreen": { + "tooltip": "按下 {{hotkey}} 进入全屏" + }, "generateToken": "生成令牌", "key": "键", "logicalDate": "逻辑日期", @@ -176,10 +180,14 @@ "note": { "add": "添加笔记", "dagRun": "Dag 执行笔记", + "edit": "编辑笔记", "label": "笔记", "placeholder": "添加笔记...", - "taskInstance": "任务实例笔记" + "preview": "预览", + "taskInstance": "任务实例笔记", + "write": "编写" }, + "overallStatus": "总体状态", "partitionedDagRun_one": "分区 Dag 执行", "partitionedDagRun_other": "分区 Dag 执行", "partitionedDagRunDetail": { @@ -218,6 +226,47 @@ }, "selectLanguage": "选择语言", "selected": "已选择", + "shortcuts": { + "categories": { + "code": "代码", + "dagView": "Dag 视图", + "filters": "筛选", + "global": "全局", + "logs": "日志", + "navigation": "导航", + "runActions": "执行与任务操作", + "search": "搜索" + }, + "descriptions": { + "clearRun": "清除 $t(dagRun_one)", + "clearTaskInstance": "清除 $t(taskInstance_one)", + "downloadLogs": "下载日志", + "focusFilterSearch": "聚焦筛选搜索框", + "focusLogSearch": "搜索日志", + "focusSearch": "聚焦搜索框", + "markRunFailed": "标记 $t(dagRun_one) 为失败", + "markRunSuccess": "标记 $t(dagRun_one) 为成功", + "markTaskFailed": "标记 $t(task_one) 为失败", + "markTaskGroupFailed": "标记 $t(taskGroup_one) 为失败", + "markTaskGroupSuccess": "标记 $t(taskGroup_one) 为成功", + "markTaskSuccess": "标记 $t(task_one) 为成功", + "navigateTasks": "导航 $t(task_other)", + "openGraphFilters": "打开图形筛选", + "scrollBottom": "滚动到最下方", + "scrollTop": "滚动到最上方", + "searchDags": "搜索 $t(dag_other)", + "showHelp": "显示 $t(shortcuts.title)", + "toggleExpand": "展开或收起所有分组", + "toggleFullscreen": "切换全屏", + "toggleGraphGrid": "切换图形 / 网格视图", + "toggleSource": "切换源代码", + "toggleTaskGroup": "展开或收起 $t(taskGroup_one)", + "toggleTimestamp": "切换时间戳", + "toggleWrap": "切换 $t(wrap.wrap)" + }, + "empty": "此页面没有可用的键盘快捷键。", + "title": "键盘快捷键" + }, "showDetailsPanel": "显示详细信息", "signedInAs": "当前登录身份", "source": { @@ -267,10 +316,13 @@ "updatedAt": "更新时间" }, "task": { + "dependsOnPast": "依赖过去", "documentation": "任务文档", "lastInstance": "最后实例", "operator": "任务操作器", - "triggerRule": "触发规则" + "retries": "重试次数", + "triggerRule": "触发规则", + "waitForDownstream": "等待下游" }, "task_one": "任务", "task_other": "任务", @@ -281,10 +333,12 @@ "taskGroup_other": "任务分组", "taskId": "任务 ID", "taskInstance": { + "additionalAttributes": "任务实例附加属性", "dagVersion": "Dag 版本", "executor": "执行器", "executorConfig": "执行器配置", "hostname": "主机名称", + "id": "ID", "maxTries": "最大尝试次数", "pid": "PID", "pool": "资源池", @@ -294,13 +348,15 @@ "queuedWhen": "开始排队时间", "renderedMapIndex": "已渲染映射索引", "scheduledWhen": "开始调度时间", + "trigger": "触发器", "triggerer": { - "assigned": "指派的触发器", + "assigned": "指派的触发者", "class": "触发器类别", "createdAt": "触发器创建时间", "id": "触发器 ID", - "latestHeartbeat": "最新触发器心跳时间", - "title": "触发器信息" + "job": "触发者作业", + "latestHeartbeat": "最新触发者心跳时间", + "title": "触发者信息" }, "unixname": "Unix 名称" }, diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json index 4660fe3afd32c..4728920cc858e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json @@ -65,6 +65,7 @@ "lastDagRun_other": "最近 {{count}} 次 Dag 执行", "lastTaskInstance_one": "最近 1 次任务实例", "lastTaskInstance_other": "最近 {{count}} 次任务实例", + "medianTotalDuration": "总计:{{duration}}", "queuedDuration": "排队等候时间", "runAfter": "最早可执行时间", "runDuration": "执行持续时间" @@ -136,6 +137,7 @@ "loading": "正在加载 Dag 信息...", "loadingFailed": "加载 Dag 信息失败,请重试。", "manualRunDenied": "此 Dag 不允许手动执行", + "partitionKeyHelp": "选填 - 仅适用于分区 Dag", "runIdHelp": "选填 - 若未提供将会自动生成", "selectDescription": "触发此 Dag 单次执行", "selectLabel": "单次执行", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json index 25dcfaf83c228..6a0c4613be05c 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json @@ -106,11 +106,6 @@ "viewInExternal": "在 {{name}} 中查看日志(重试 {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "导航: {{arrow}}", - "openGraphFilters": "任务筛选器: Ctrl+Shift+F", - "toggleGroup": "展开/收起分组: 空格键" - }, "notFound": { "back": "返回", "backToDags": "返回 Dags", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json index db646b91d80a4..bc9c9cf5cdb81 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "全部执行类型", "allStates": "全部状态", + "anyRunState": "任意执行", "favorite": { "all": "全部", "favorite": "已加入收藏", "unfavorite": "未加入收藏" }, + "lastRunState": "最近一次执行", "paused": { "active": "已启用", "all": "全部", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json index 011d479933a0e..c10a202e3944e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dashboard.json @@ -1,4 +1,22 @@ { + "alerts": { + "seeLessContext": "查看更少", + "seeMoreContext": "查看更多", + "showMoreAlerts_one": "另有 {{count}} 条警报", + "showMoreAlerts_other": "另有 {{count}} 条警报" + }, + "deadlines": { + "pending": { + "empty": "没有即将到期的截止期限", + "title": "即将到期" + }, + "recentlyMissed": { + "empty": "没有错过的截止期限", + "title": "已错过的截止期限" + }, + "showMore": "显示更多", + "title": "截止期限" + }, "deferredSlotsNotCounted": "未计入配额的延迟任务:{{count}}", "deferredSlotsNotCountedTooltip": "条形图中显示的延迟任务会计入资源池配额。条形图下方显示的延迟任务来自不将延迟任务计入配额的资源池。", "favorite": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json index 4548c5770675b..a2fecb02ddb04 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/hitl.json @@ -24,6 +24,20 @@ "success": "任务 {{taskId}} 响应成功", "title": "人类参与流程任务实例 - {{taskId}}" }, + "review": { + "detail": { + "selectRequiredAction": "选择一个待操作的任务实例以查看详情" + }, + "list": { + "completedRequiredActions": "已完成的待操作任务实例 ({{count}})", + "loadError": "无法加载待操作的任务实例", + "loadingActions": "正在加载待操作的任务实例...", + "pendingRequiredActions": "待处理的待操作任务实例 ({{count}})" + }, + "openReviewDrawer": "打开审阅抽屉", + "pageLimitHint": "此处仅显示前几项待操作的任务实例。使用 \"$t(review.viewAll)\" 查看全部。", + "viewAll": "查看全部待操作的任务实例" + }, "state": { "approvalReceived": "已批准", "approvalRequired": "需要批准", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json index a67809370026a..8479fde62d5ea 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/admin.json @@ -177,6 +177,7 @@ "title": "跳過" } }, + "parsingFile": "正在解析檔案...", "title": "匯入變數", "upload": "上傳 JSON 檔案", "uploadPlaceholder": "上傳包含變數的 JSON 檔案 (例如:{\"key\": \"value\", ...})" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json index a98d200635ce3..f6a8833763567 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/common.json @@ -72,8 +72,8 @@ "expectedDuration": "預計時長", "lastSchedulingDecision": "最後排程決策", "mappedPartitionKey": "映射分區鍵", - "partitionDate": "資產分區日期", - "partitionKey": "資產分區鍵", + "partitionDate": "資源分區日期", + "partitionKey": "資源分區鍵", "queuedAt": "開始排隊時間", "runAfter": "最早可執行時間", "runType": "執行類型", @@ -193,8 +193,8 @@ "partitionedDagRunDetail": { "receivedAssetEvents": "收到的資源事件" }, - "pendingDagRun_one": "待執行的 Dag 執行", - "pendingDagRun_other": "待執行的 Dag 執行", + "pendingDagRun_one": "{{count}} 個待執行的 Dag 執行", + "pendingDagRun_other": "{{count}} 個待執行的 Dag 執行", "reset": "重置", "runId": "執行 ID", "runTypes": { @@ -226,6 +226,47 @@ }, "selectLanguage": "選擇語言", "selected": "已選取", + "shortcuts": { + "categories": { + "code": "程式碼", + "dagView": "Dag 檢視", + "filters": "篩選條件", + "global": "全域", + "logs": "日誌", + "navigation": "導覽", + "runActions": "執行與任務操作", + "search": "搜尋" + }, + "descriptions": { + "clearRun": "清除 $t(dagRun_one)", + "clearTaskInstance": "清除 $t(taskInstance_one)", + "downloadLogs": "下載日誌", + "focusFilterSearch": "聚焦篩選搜尋欄", + "focusLogSearch": "搜尋日誌", + "focusSearch": "聚焦搜尋欄", + "markRunFailed": "將 $t(dagRun_one) 標記為失敗", + "markRunSuccess": "將 $t(dagRun_one) 標記為成功", + "markTaskFailed": "將 $t(task_one) 標記為失敗", + "markTaskGroupFailed": "將 $t(taskGroup_one) 標記為失敗", + "markTaskGroupSuccess": "將 $t(taskGroup_one) 標記為成功", + "markTaskSuccess": "將 $t(task_one) 標記為成功", + "navigateTasks": "瀏覽 $t(task_other)", + "openGraphFilters": "開啟圖表篩選條件", + "scrollBottom": "捲動到底部", + "scrollTop": "捲動到頂部", + "searchDags": "搜尋 $t(dag_other)", + "showHelp": "顯示 $t(shortcuts.title)", + "toggleExpand": "展開或收合所有群組", + "toggleFullscreen": "切換全螢幕", + "toggleGraphGrid": "切換圖表/網格檢視", + "toggleSource": "切換來源", + "toggleTaskGroup": "展開或收合 $t(taskGroup_one)", + "toggleTimestamp": "切換時間戳記", + "toggleWrap": "切換 $t(wrap.wrap)" + }, + "empty": "此頁面沒有可用的鍵盤快捷鍵。", + "title": "鍵盤快捷鍵" + }, "showDetailsPanel": "顯示詳細資訊", "signedInAs": "登入身分:", "source": { diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json index 44889c7d2ce7c..3d8fc5e64fec5 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/components.json @@ -65,6 +65,7 @@ "lastDagRun_other": "最近 {{count}} 次 Dag 執行", "lastTaskInstance_one": "最近 1 次任務實例", "lastTaskInstance_other": "最近 {{count}} 次任務實例", + "medianTotalDuration": "總計: {{duration}}", "queuedDuration": "排隊等候時間", "runAfter": "最早可執行時間", "runDuration": "執行持續時間" @@ -129,13 +130,14 @@ "triggerDag": { "button": "觸發", "dataInterval": "資料區間", - "dataIntervalAuto": "依邏輯日期與時間表推斷", + "dataIntervalAuto": "依邏輯日期與排程規則推斷", "dataIntervalManual": "手動指定", "intervalEnd": "結束", "intervalStart": "開始", "loading": "正在載入 Dag 資訊...", "loadingFailed": "載入 Dag 資訊失敗,請重試。", "manualRunDenied": "此 Dag 不允許手動執行", + "partitionKeyHelp": "選填 - 僅適用於分區的 Dag", "runIdHelp": "選填 - 若未提供將會自動產生", "selectDescription": "觸發此 Dag 單次執行", "selectLabel": "單次執行", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json index 2d95ee93a61fd..401a19ccbd19e 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json @@ -42,6 +42,7 @@ }, "deadlineAlerts": { "completionRule": "必須在 {{reference}}後 {{interval}} 內完成", + "completionRuleDynamic": "必須在 {{reference}}後的一段變動期間內完成", "count_one": "{{count}} 個期限", "count_other": "{{count}} 個期限", "referenceType": { @@ -102,11 +103,6 @@ "viewInExternal": "在 {{name}} 中檢視日誌(嘗試 {{attempt}})", "warning": "WARNING" }, - "navigation": { - "navigation": "導航: {{arrow}}", - "openGraphFilters": "任務篩選條件: Ctrl+Shift+F", - "toggleGroup": "展開/收合群組: 空白鍵" - }, "notFound": { "back": "返回", "backToDags": "返回 Dag 列表", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dags.json index a6a87c87d172e..e7c8daf93f26a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dags.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dags.json @@ -10,11 +10,13 @@ "filters": { "allRunTypes": "全部執行類型", "allStates": "全部狀態", + "anyRunState": "全部執行", "favorite": { "all": "全部", "favorite": "已加為最愛", "unfavorite": "未加為最愛" }, + "lastRunState": "最後執行狀態", "paused": { "active": "啟用中", "all": "全部", diff --git a/airflow-core/src/airflow/ui/rules/core.js b/airflow-core/src/airflow/ui/rules/core.js index 48fcce1f39aa9..8ed46f24ffd29 100644 --- a/airflow-core/src/airflow/ui/rules/core.js +++ b/airflow-core/src/airflow/ui/rules/core.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/i18n.js b/airflow-core/src/airflow/ui/rules/i18n.js index fe96bd19e71cc..811dea1d252ff 100644 --- a/airflow-core/src/airflow/ui/rules/i18n.js +++ b/airflow-core/src/airflow/ui/rules/i18n.js @@ -16,11 +16,9 @@ * specific language governing permissions and limitations * under the License. */ - /* eslint-disable @typescript-eslint/no-unsafe-argument */ - /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import jsoncParser from "jsonc-eslint-parser"; +import * as jsoncParser from "jsonc-eslint-parser"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; diff --git a/airflow-core/src/airflow/ui/rules/i18next.js b/airflow-core/src/airflow/ui/rules/i18next.js index 1ba9fc3ded75a..740ee20c8627b 100644 --- a/airflow-core/src/airflow/ui/rules/i18next.js +++ b/airflow-core/src/airflow/ui/rules/i18next.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/perfectionist.js b/airflow-core/src/airflow/ui/rules/perfectionist.js index de0aaf1ca3b56..6054079ef998f 100644 --- a/airflow-core/src/airflow/ui/rules/perfectionist.js +++ b/airflow-core/src/airflow/ui/rules/perfectionist.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/prettier.js b/airflow-core/src/airflow/ui/rules/prettier.js index 970c5c6ffb9ef..9fa5cdae0b8a0 100644 --- a/airflow-core/src/airflow/ui/rules/prettier.js +++ b/airflow-core/src/airflow/ui/rules/prettier.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/react.js b/airflow-core/src/airflow/ui/rules/react.js index 2427c0f6374a8..497110f217392 100644 --- a/airflow-core/src/airflow/ui/rules/react.js +++ b/airflow-core/src/airflow/ui/rules/react.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/stylistic.js b/airflow-core/src/airflow/ui/rules/stylistic.js index 3307be64c3401..416b9a6196f95 100644 --- a/airflow-core/src/airflow/ui/rules/stylistic.js +++ b/airflow-core/src/airflow/ui/rules/stylistic.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/typescript.js b/airflow-core/src/airflow/ui/rules/typescript.js index 71501b3db5d3c..cceb7b676c916 100644 --- a/airflow-core/src/airflow/ui/rules/typescript.js +++ b/airflow-core/src/airflow/ui/rules/typescript.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/rules/unicorn.js b/airflow-core/src/airflow/ui/rules/unicorn.js index e4d0d528876a3..304943f317815 100644 --- a/airflow-core/src/airflow/ui/rules/unicorn.js +++ b/airflow-core/src/airflow/ui/rules/unicorn.js @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - /** * @import { FlatConfig } from "@typescript-eslint/utils/ts-eslint"; */ diff --git a/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx b/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx index 716160d260095..03809a0a7f60b 100644 --- a/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx +++ b/airflow-core/src/airflow/ui/src/components/AnsiRenderer.tsx @@ -131,7 +131,7 @@ const createChakraProps = (bundle: AnserJsonEntry) => { case "underline": props.textDecoration = "underline"; break; - // eslint-disable-next-line unicorn/no-useless-switch-case + case null: default: break; diff --git a/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.test.tsx b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.test.tsx new file mode 100644 index 0000000000000..c8856d0eab90e --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.test.tsx @@ -0,0 +1,48 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import "@testing-library/jest-dom"; +import { render, screen } from "@testing-library/react"; +import { describe, expect, it } from "vitest"; + +import type { AssetEventResponse } from "openapi/requests/types.gen"; +import { Wrapper } from "src/utils/Wrapper"; + +import { AssetEvent } from "./AssetEvent"; + +const baseEvent = { + asset_id: 1, + created_dagruns: [], + id: 1, + source_map_index: -1, + timestamp: "2025-01-01T00:00:00Z", +} satisfies Partial as AssetEventResponse; + +describe("AssetEvent", () => { + it("does not render a partition key line when partition_key is null", () => { + render(, { wrapper: Wrapper }); + + expect(screen.queryByText(/dagRun\.partitionKey/u)).not.toBeInTheDocument(); + }); + + it("renders the partition key line when partition_key is set", () => { + render(, { wrapper: Wrapper }); + + expect(screen.getByText("dagRun.partitionKey: foo")).toBeInTheDocument(); + }); +}); diff --git a/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.tsx b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.tsx index eef73e9c98371..48ec0a3ffe21f 100644 --- a/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.tsx +++ b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvent.tsx @@ -95,13 +95,16 @@ export const AssetEvent = ({ - {event.partition_key === undefined ? undefined : ( - - - {rootTranslate("dagRun.partitionKey")}: {event.partition_key} - - - )} + { + // eslint-disable-next-line no-eq-null, eqeqeq + event.partition_key == null ? undefined : ( + + + {rootTranslate("dagRun.partitionKey")}: {event.partition_key} + + + ) + } {Object.keys(extra).length >= 1 ? : undefined} ); diff --git a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx index 6cbc3aa08b004..c4c040a1c1bc5 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx @@ -17,12 +17,13 @@ * under the License. */ import { useDisclosure } from "@chakra-ui/react"; -import { useHotkeys } from "react-hotkeys-hook"; import { useTranslation } from "react-i18next"; import { CgRedo } from "react-icons/cg"; import type { DAGRunResponse } from "openapi/requests/types.gen"; import { IconButton } from "src/components/ui"; +import { SHORTCUTS } from "src/context/keyboardShortcuts"; +import { useShortcut } from "src/hooks/useShortcut"; import ClearRunDialog from "./ClearRunDialog"; @@ -35,13 +36,13 @@ const ClearRunButton = ({ dagRun, isHotkeyEnabled = false }: Props) => { const { onClose, onOpen, open } = useDisclosure(); const { t: translate } = useTranslation(); - useHotkeys( - "shift+c", - () => { + useShortcut({ + ...SHORTCUTS.runActions.clearRun, + callback: () => { onOpen(); }, - { enabled: isHotkeyEnabled }, - ); + options: { enabled: isHotkeyEnabled }, + }); return ( <> diff --git a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx index 425ce9f82364c..c864f0b047c7f 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx @@ -24,6 +24,7 @@ import { CgRedo } from "react-icons/cg"; import { useDagServiceGetDagDetails } from "openapi/queries"; import type { DAGRunResponse } from "openapi/requests/types.gen"; import { ActionAccordion } from "src/components/ActionAccordion"; +import { getRunOnLatestVersionState } from "src/components/Clear/TaskInstance/runOnLatestVersion"; import { useRerunWithLatestVersion } from "src/components/Clear/useRerunWithLatestVersion"; import { Checkbox, Dialog } from "src/components/ui"; import SegmentedControl from "src/components/ui/SegmentedControl"; @@ -91,14 +92,18 @@ const ClearRunDialog = ({ dagRun, onClose, open }: Props) => { onSuccessConfirm: handleClose, }); - // Check if DAG versions differ (works for both bundle-versioned and local bundles) - const latestDagVersionNumber = dagDetails?.latest_dag_version?.version_number; - const dagRunVersionNumber = dagRun.dag_versions.at(-1)?.version_number; - const versionsDiffer = - latestDagVersionNumber !== undefined && - dagRunVersionNumber !== undefined && - latestDagVersionNumber !== dagRunVersionNumber; - const shouldShowBundleVersionOption = versionsDiffer && !onlyNew; + // Non-versioned bundles (e.g. LocalDagBundle) always leave bundle_version null and + // resolve to the latest serialized Dag at run time, so "run on latest" is a no-op there. + // Offer it only when re-running on the latest would actually change the outcome: + // the run's Dag version differs from the latest while the bundle is versioned + // (latest bundle_version present), or the run's bundle version differs from the latest. + const { shouldShowRunOnLatestOption } = getRunOnLatestVersionState({ + latestBundleVersion: dagDetails?.bundle_version, + latestDagVersionNumber: dagDetails?.latest_dag_version?.version_number, + selectedBundleVersion: dagRun.bundle_version, + selectedDagVersionNumber: dagRun.dag_versions.at(-1)?.version_number, + }); + const shouldShowBundleVersionOption = shouldShowRunOnLatestOption && !onlyNew; return ( { + useShortcut({ + ...SHORTCUTS.runActions.clearTaskInstance, + callback: () => { if (onOpen && selectedInstance) { onOpen(selectedInstance); } else { onOpenInternal(); } }, - { enabled: isHotkeyEnabled }, - ); + options: { enabled: isHotkeyEnabled }, + }); const label = allMapped ? isHotkeyEnabled diff --git a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.test.ts b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.test.ts index 2936e2b91910d..1f3d6ba4d3c63 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.test.ts +++ b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.test.ts @@ -22,32 +22,41 @@ import { getRunOnLatestVersionState } from "./runOnLatestVersion"; describe("getRunOnLatestVersionState", () => { it.each([ + { + expectedDagVersionsDiffer: true, + expectedShouldShowRunOnLatestOption: false, + latestDagVersionNumber: 3, + name: "does not show when Dag versions differ but no bundle version is present (non-versioned bundle)", + selectedDagVersionNumber: 2, + }, { expectedDagVersionsDiffer: true, expectedShouldShowRunOnLatestOption: true, + latestBundleVersion: "bundle-b", latestDagVersionNumber: 3, - name: "shows and defaults on when DAG version numbers differ", + name: "shows when Dag versions differ on a versioned bundle even if the run has no recorded bundle version", + selectedBundleVersion: null, selectedDagVersionNumber: 2, }, { expectedDagVersionsDiffer: false, expectedShouldShowRunOnLatestOption: false, latestDagVersionNumber: 3, - name: "does not show when DAG version numbers match and there is no bundle difference", + name: "does not show when Dag version numbers match and there is no bundle difference", selectedDagVersionNumber: 3, }, { expectedDagVersionsDiffer: false, expectedShouldShowRunOnLatestOption: false, latestDagVersionNumber: undefined, - name: "does not treat a missing latest DAG version number as different", + name: "does not treat a missing latest Dag version number as different", selectedDagVersionNumber: 3, }, { expectedDagVersionsDiffer: false, expectedShouldShowRunOnLatestOption: false, latestDagVersionNumber: 3, - name: "does not treat a missing selected DAG version number as different", + name: "does not treat a missing selected Dag version number as different", selectedDagVersionNumber: undefined, }, { diff --git a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.ts b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.ts index 7bbd2daf9040c..fa183b37d0c06 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.ts +++ b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/runOnLatestVersion.ts @@ -55,6 +55,7 @@ export const getRunOnLatestVersionState = ({ return { dagVersionsDiffer, - shouldShowRunOnLatestOption: dagVersionsDiffer || shouldShowForBundleVersion, + shouldShowRunOnLatestOption: + (dagVersionsDiffer && hasBundleVersion(latestBundleVersion)) || shouldShowForBundleVersion, }; }; diff --git a/airflow-core/src/airflow/ui/src/components/ConfirmationModal.tsx b/airflow-core/src/airflow/ui/src/components/ConfirmationModal.tsx index f4c8a92007fe9..f862929fbcc95 100644 --- a/airflow-core/src/airflow/ui/src/components/ConfirmationModal.tsx +++ b/airflow-core/src/airflow/ui/src/components/ConfirmationModal.tsx @@ -33,7 +33,13 @@ export const ConfirmationModal = ({ children, header, onConfirm, onOpenChange, o const { t: translate } = useTranslation("common"); return ( - + {header} diff --git a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx index 8008307fabf40..b558249ff1d9f 100644 --- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx +++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx @@ -25,9 +25,9 @@ import { LineElement, BarElement, Filler, + Legend, Tooltip, } from "chart.js"; -import type { PartialEventContext } from "chartjs-plugin-annotation"; import annotationPlugin from "chartjs-plugin-annotation"; import dayjs from "dayjs"; import { Bar } from "react-chartjs-2"; @@ -37,8 +37,15 @@ import { useNavigate } from "react-router-dom"; import type { TaskInstanceResponse, GridRunsResponse } from "openapi/requests/types.gen"; import { useTimezone } from "src/context/timezone"; import { getComputedCSSVariableValue } from "src/theme"; -import { DEFAULT_DATETIME_FORMAT, formatDate, renderDuration } from "src/utils/datetimeUtils"; +import { + DEFAULT_DATETIME_FORMAT, + formatDate, + getDurationTickStep, + renderCompactDuration, + renderDuration, +} from "src/utils/datetimeUtils"; import { buildTaskInstanceUrl } from "src/utils/links"; +import { median } from "src/utils/median"; ChartJS.register( CategoryScale, @@ -47,15 +54,12 @@ ChartJS.register( BarElement, LineElement, Filler, + Legend, Tooltip, annotationPlugin, ); -const average = (ctx: PartialEventContext, index: number) => { - const values: Array | undefined = ctx.chart.data.datasets[index]?.data as Array | undefined; - - return values === undefined ? 0 : values.reduce((initial, next) => initial + next, 0) / values.length; -}; +const CHART_HEIGHT = "280px"; type RunResponse = GridRunsResponse | TaskInstanceResponse; @@ -70,6 +74,24 @@ const getDuration = (start: string, end: string | null) => { return dayjs.duration(endDate.diff(startDate)).asSeconds(); }; +const getQueuedDuration = (entry: RunResponse, kind: "Dag Run" | "Task Instance") => { + if (kind === "Dag Run") { + const run = entry as GridRunsResponse; + + return run.queued_at !== null && run.start_date !== null && run.queued_at < run.start_date + ? getDuration(run.queued_at, run.start_date) + : 0; + } + + const taskInstance = entry as TaskInstanceResponse; + + return taskInstance.queued_when !== null && + taskInstance.start_date !== null && + taskInstance.queued_when < taskInstance.start_date + ? getDuration(taskInstance.queued_when, taskInstance.start_date) + : 0; +}; + const getTickLabelFormat = (entries: Array): string => { if (entries.length < 2) { return "HH:mm:ss"; @@ -121,28 +143,28 @@ export const DurationChart = ({ } }); - const runAnnotation = { - borderColor: "grey", - borderWidth: 1, - label: { - content: (ctx: PartialEventContext) => renderDuration(average(ctx, 1), false) ?? "0", - display: true, - position: "end", - }, - scaleID: "y", - value: (ctx: PartialEventContext) => average(ctx, 1), - }; + const queuedDurations = entries.map((entry) => getQueuedDuration(entry, kind)); + const runDurations = entries.map((entry) => + entry.start_date === null ? 0 : getDuration(entry.start_date, entry.end_date), + ); + // Bars stack queued under run, so the reference line tracks the same total the + // reader sees at the top of each bar. + const totalDurations = runDurations.map((duration, index) => duration + (queuedDurations[index] ?? 0)); + const medianTotal = median(totalDurations); - const queuedAnnotation = { + const medianAnnotation = { borderColor: "grey", + borderDash: [6, 4], borderWidth: 1, label: { - content: (ctx: PartialEventContext) => renderDuration(average(ctx, 0), false) ?? "0", + content: translate("durationChart.medianTotalDuration", { + duration: renderCompactDuration(medianTotal), + }), display: true, - position: "end", + position: "start", }, scaleID: "y", - value: (ctx: PartialEventContext) => average(ctx, 0), + value: medianTotal, }; return ( @@ -152,134 +174,122 @@ export const DurationChart = ({ ? translate("durationChart.lastDagRun", { count: entries.length }) : translate("durationChart.lastTaskInstance", { count: entries.length })} - { - switch (kind) { - case "Dag Run": { - const run = entry as GridRunsResponse; - - return run.queued_at !== null && run.start_date !== null && run.queued_at < run.start_date - ? Number(getDuration(run.queued_at, run.start_date)) - : 0; - } - case "Task Instance": { - const taskInstance = entry as TaskInstanceResponse; - - return taskInstance.queued_when !== null && - taskInstance.start_date !== null && - taskInstance.queued_when < taskInstance.start_date - ? Number(getDuration(taskInstance.queued_when, taskInstance.start_date)) - : 0; - } - default: - return 0; - } - }), - label: translate("durationChart.queuedDuration"), - }, - { - backgroundColor: entries.map( - (entry: RunResponse) => - (entry.state ? stateColorMap[entry.state] : undefined) ?? "oklch(0.5 0 0)", - ), - data: entries.map((entry: RunResponse) => - entry.start_date === null ? 0 : Number(getDuration(entry.start_date, entry.end_date)), - ), - label: translate("durationChart.runDuration"), - }, - ], - labels: entries.map((entry: RunResponse) => dayjs(entry.run_after).format(DEFAULT_DATETIME_FORMAT)), - }} - datasetIdKey="id" - options={{ - animation: isAutoRefreshing ? false : undefined, - onClick: (_event, elements) => { - const [element] = elements; - - if (!element) { - return; - } - - switch (kind) { - case "Dag Run": { - const entry = entries[element.index] as GridRunsResponse | undefined; - const baseUrl = `/dags/${entry?.dag_id}/runs/${entry?.run_id}`; - - void Promise.resolve(navigate(baseUrl)); - break; + {/* Height is fixed because the chart now flexes horizontally: with Chart.js' + default 2:1 aspect ratio a wide monitor would otherwise scale it past + 1000px tall. */} + + + (entry.state ? stateColorMap[entry.state] : undefined) ?? "oklch(0.5 0 0)", + ), + data: runDurations, + label: translate("durationChart.runDuration"), + }, + ], + labels: entries.map((entry: RunResponse) => + dayjs(entry.run_after).format(DEFAULT_DATETIME_FORMAT), + ), + }} + datasetIdKey="id" + options={{ + animation: isAutoRefreshing ? false : undefined, + maintainAspectRatio: false, + onClick: (_event, elements) => { + const [element] = elements; + + if (!element) { + return; } - case "Task Instance": { - const entry = entries[element.index] as TaskInstanceResponse | undefined; - if (entry === undefined) { + switch (kind) { + case "Dag Run": { + const entry = entries[element.index] as GridRunsResponse | undefined; + const baseUrl = `/dags/${entry?.dag_id}/runs/${entry?.run_id}`; + + void Promise.resolve(navigate(baseUrl)); break; } + case "Task Instance": { + const entry = entries[element.index] as TaskInstanceResponse | undefined; + + if (entry === undefined) { + break; + } - const baseUrl = buildTaskInstanceUrl({ - currentPathname: location.pathname, - dagId: entry.dag_id, - isMapped: entry.map_index >= 0, - mapIndex: entry.map_index.toString(), - runId: entry.dag_run_id, - taskId: entry.task_id, - }); - - void Promise.resolve(navigate(baseUrl)); - break; + const baseUrl = buildTaskInstanceUrl({ + currentPathname: location.pathname, + dagId: entry.dag_id, + isMapped: entry.map_index >= 0, + mapIndex: entry.map_index.toString(), + runId: entry.dag_run_id, + taskId: entry.task_id, + }); + + void Promise.resolve(navigate(baseUrl)); + break; + } + default: } - default: - } - }, - onHover: (_event, elements, chart) => { - chart.canvas.style.cursor = elements.length > 0 ? "pointer" : "default"; - }, - plugins: { - annotation: { - annotations: { - queuedAnnotation, - runAnnotation, - }, }, - tooltip: { - callbacks: { - label: (context) => { - const datasetLabel = context.dataset.label ?? ""; + onHover: (_event, elements, chart) => { + chart.canvas.style.cursor = elements.length > 0 ? "pointer" : "default"; + }, + plugins: { + annotation: { + annotations: { + medianAnnotation, + }, + }, + legend: { + display: true, + position: "bottom", + }, + tooltip: { + callbacks: { + label: (context) => { + const datasetLabel = context.dataset.label ?? ""; - const formatted = renderDuration(context.parsed.y, false) ?? "0"; + const formatted = renderDuration(context.parsed.y, false) ?? "0"; - return datasetLabel ? `${datasetLabel}: ${formatted}` : formatted; + return datasetLabel ? `${datasetLabel}: ${formatted}` : formatted; + }, }, }, }, - }, - responsive: true, - scales: { - x: { - stacked: true, - ticks: { - callback: (_value, index) => - formatDate(entries[index]?.run_after, selectedTimezone, getTickLabelFormat(entries)), - maxTicksLimit: 3, + responsive: true, + scales: { + x: { + stacked: true, + ticks: { + callback: (_value, index) => + formatDate(entries[index]?.run_after, selectedTimezone, getTickLabelFormat(entries)), + maxTicksLimit: 3, + }, + title: { align: "end", display: true, text: translate("common:dagRun.runAfter") }, }, - title: { align: "end", display: true, text: translate("common:dagRun.runAfter") }, - }, - y: { - ticks: { - callback: (value) => { - const num = typeof value === "number" ? value : Number(value); - - return renderDuration(num, false) ?? "0"; + y: { + beginAtZero: true, + stacked: true, + ticks: { + callback: (value) => + renderCompactDuration(typeof value === "number" ? value : Number(value)), + stepSize: getDurationTickStep(Math.max(...totalDurations, 0)), }, + title: { align: "end", display: true, text: translate("common:duration") }, }, - title: { align: "end", display: true, text: translate("common:duration") }, }, - }, - }} - /> + }} + /> + ); }; diff --git a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx index 32bfa29231849..09f1c5d3ee4ba 100644 --- a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx +++ b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx @@ -18,11 +18,12 @@ */ import { HStack } from "@chakra-ui/react"; import { useRef } from "react"; -import { useHotkeys } from "react-hotkeys-hook"; import { LuRegex } from "react-icons/lu"; import { AdvancedSearchToggle } from "src/components/AdvancedSearchToggle"; +import { SHORTCUTS } from "src/context/keyboardShortcuts"; import { useAdvancedSearch } from "src/hooks/useAdvancedSearch"; +import { useShortcut } from "src/hooks/useShortcut"; import { InputWithAddon } from "../../ui"; import { FilterPill } from "../FilterPill"; @@ -42,15 +43,15 @@ export const TextSearchFilter = ({ filter, onChange, onRemove }: FilterPluginPro onChange(newValue || undefined); }; - useHotkeys( - "mod+k", - () => { + useShortcut({ + ...SHORTCUTS.search.focusFilterSearch, + callback: () => { if (!filter.config.hotkeyDisabled) { hotkeyInputRef.current?.focus(); } }, - { enabled: !filter.config.hotkeyDisabled, preventDefault: true }, - ); + options: { enabled: !filter.config.hotkeyDisabled, preventDefault: true }, + }); const isAdvanced = showAdvancedToggle && advanced.enabled; const stringValue = hasValue && typeof filter.value === "string" ? filter.value : ""; diff --git a/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx b/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx index 39921fa80f2ef..b17ab9b77c134 100644 --- a/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx +++ b/airflow-core/src/airflow/ui/src/components/FlexibleForm/FieldBool.tsx @@ -37,8 +37,10 @@ export const FieldBool = ({ name, namespace = "default" }: FlexibleFormElementPr checked={Boolean(param.value)} disabled={disabled} id={`element_${name}`} + justifyContent="flex-end" name={`element_${name}`} onCheckedChange={(event) => onCheck(event.checked)} + width="full" /> ); }; diff --git a/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.test.tsx b/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.test.tsx new file mode 100644 index 0000000000000..0332c129dfbe4 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.test.tsx @@ -0,0 +1,49 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import "@testing-library/jest-dom"; +import { render, screen } from "@testing-library/react"; +import { MemoryRouter, Route, Routes } from "react-router-dom"; +import { describe, expect, it } from "vitest"; + +import { BaseWrapper } from "src/utils/Wrapper"; + +import { TaskLink } from "./TaskLink"; + +describe("TaskLink", () => { + it("removes the selected try when linking to another task", () => { + render( + + + } + path="/dags/:dagId/runs/:runId/tasks/:taskId" + /> + + , + { wrapper: BaseWrapper }, + ); + + expect(screen.getByRole("link", { name: "one_try" })).toHaveAttribute( + "href", + "/dags/test_dag/runs/test_run/tasks/one_try?log_level=error", + ); + }); +}); diff --git a/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.tsx b/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.tsx index fb96238601f85..5ec36b34c2460 100644 --- a/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.tsx +++ b/airflow-core/src/airflow/ui/src/components/Graph/TaskLink.tsx @@ -20,6 +20,7 @@ import { forwardRef } from "react"; import { useParams, useSearchParams, Link as RouterLink } from "react-router-dom"; import { TaskName, type TaskNameProps } from "src/components/TaskName"; +import { SearchParamsKeys } from "src/constants/searchParams"; import { taskNodeSeparator } from "src/utils/assetGraph"; type Props = { @@ -55,8 +56,12 @@ export const TaskLink = forwardRef(({ id, isGroup, isM ? "" : `/tasks/${taskId}${isMapped && urlTaskId !== taskId && runId !== undefined ? "/mapped" : ""}`; + const targetSearchParams = new URLSearchParams(searchParams); + + targetSearchParams.delete(SearchParamsKeys.TRY_NUMBER); + return ( - + ); diff --git a/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx b/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx index 5d8affeca3059..0efe7dbbb81a3 100644 --- a/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx +++ b/airflow-core/src/airflow/ui/src/components/Graph/TaskNode.tsx @@ -19,6 +19,7 @@ import { Box, Button, Flex, HStack, LinkOverlay, Text } from "@chakra-ui/react"; import type { NodeProps, Node as NodeType } from "@xyflow/react"; import { useTranslation } from "react-i18next"; +import { AiOutlineGroup } from "react-icons/ai"; import { TaskIcon } from "src/assets/TaskIcon"; import { StateBadge } from "src/components/StateBadge"; @@ -112,7 +113,7 @@ export const TaskNode = ({ width={`${width + (isSelected ? 4 : 0)}px`} > - + {isGroup ? : } { const { t: translate } = useTranslation(["dag", "tasks"]); @@ -140,7 +141,11 @@ export const GraphTaskFilters = () => { const [isOpen, setIsOpen] = useState(false); - useHotkeys("mod+shift+f", () => setIsOpen(true), { preventDefault: true }); + useShortcut({ + ...SHORTCUTS.filters.openGraphFilters, + callback: () => setIsOpen(true), + options: { preventDefault: true }, + }); const panelTitle = translate("dag:panel.graphFilters.title"); diff --git a/airflow-core/src/airflow/ui/src/components/JsonEditor.test.tsx b/airflow-core/src/airflow/ui/src/components/JsonEditor.test.tsx new file mode 100644 index 0000000000000..555bf6ad42a1b --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/JsonEditor.test.tsx @@ -0,0 +1,86 @@ +/*! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import "@testing-library/jest-dom"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; + +import { JsonEditor } from "./JsonEditor"; + +vi.mock("src/components/MonacoEditor", () => ({ + default: ({ + onChange, + value, + }: { + readonly onChange?: (value: string | undefined) => void; + readonly value?: string; + }) => ( +