Update outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users - #27945
Conversation
- product_updates is nullable - module_bar is nullable - default_language and project_color are NOT nullable
- sorted to match @directus/types declaration
- sorted to match @directus/types declaration
- status now includes 'inactive-license'
Gives MODULE_BAR_DEFAULT an explicit (SettingsModuleBarLink | SettingsModuleBarModule)[] annotation instead of a bare literal, so it structurally satisfies the discriminated union instead of widening `type` to `string`. Drops the now-unneeded `as Settings['module_bar']` cast on system-modules.vue's withDefaults default, which was masking the same issue since directus#18490. Also fixes DEFAULT_REPORT_FEATURE_URL, stale since the roadmap moved to .com. Fixes directus#27943
…de errors" This reverts commit 245c4df5d3f4 Cherry-picked temporarily to confirm this branch has no new vue-tsc errors. Rebase onto main after directus#27943 merges to pick up the real change.
module_bar has no default and no NOT NULL constraint in the database, so it can be NULL. valueToPreview called .flatMap() directly on the value with no null check, which would crash the Settings > Project Settings UI. Guards with (value ?? MODULE_BAR_DEFAULT), matching the pattern already used elsewhere in this file. Refs directus#27943
…ype-drift-resolve # Conflicts: # packages/types/src/settings.ts
Verified issue #28042 and submitted PR for fix #28043 (draft due to PR limit for contributors but easy to review I think) |
AFAIK, we don't have the same relational typing in packages/types as we do in the SDK setup. In general, we only model the field types we need there, which is typically just the id. So this adjustment seems expected for this relation.
I'd leave it for now, no meaningful improvement to doing so atm. |
ComfortablyCoding
left a comment
There was a problem hiding this comment.
Thanks for the PR! Please see comments below.
Co-authored-by: daedalus <44623501+ComfortablyCoding@users.noreply.github.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #27945 +/- ##
==========================================
+ Coverage 69.95% 70.11% +0.16%
==========================================
Files 2453 2456 +3
Lines 167691 168560 +869
Branches 16542 16844 +302
==========================================
+ Hits 117304 118193 +889
+ Misses 50387 50367 -20
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
directus_files, directus_collections, directus_deployments, directus_settings, and directus_users
What's Changed
Corrects nullability, missing fields, and one stale field across
sdk/src/schema/*.tsandpackages/types/src/*.tsfordirectus_files,directus_collections,directus_deployments(+ projects/runs),directus_settings, anddirectus_users, based on an audit against the DB migrations and runtime behavior. Links below point atmainand cite the DB migration or runtime code backing each claim.directus_filessdk: addedcreated_on(non-null) andtus_id/tus_data(nullable) was missing entirely.tus_id/tus_data,created_on/uploaded_onsplitsdk:uploaded_onis now nullable - no default since the old NOT NULLuploaded_onwas renamed tocreated_onin the same migration linked above.directus_collectionssdk: addedautosave_revision_interval(nullable) tometawas missing from sdk only.migration
directus_deployments/directus_deployment_projects/directus_deployment_runssdk:providernarrowed fromstringto'vercel' | 'netlify', matching the enforced values incontrollers/deployment.ts. Judgment call - see Review Notes.sdk: addedwebhook_ids,webhook_secret,last_synced_at(DirectusDeployment) andurl,framework,deployable(DirectusDeploymentProject) was missing entirely.migration
packages/types: addeduser_createdtoStoredProjectandStoredRunas nullable:fkcolumns(migration),
sdk+packages/types:deployment_runs.statusis now nullable. DB column has no default(migration), and the API's own internal type already treats it as nullable
(
deployment-runs.ts).directus_settingssdk: reordered to matchpackages/types/src/settings.ts's field order.sdk: addedpublic_favicon,mcp_oauth_enabled/_dcr_enabled/_cimd_enabled,project_owner,project_usage,org_name,product_updates,project_statuswas missing entirely.public_favicon,mcp_oauth_*,project_owner/project_usage/org_name/product_updates/project_statuspackages/types: addedmcp_oauth_dcr_enabled,mcp_oauth_cimd_enabled,project_status- same columns as above, missing here too (not sdk-only, as originally assumed).sdk+packages/types:product_updatesis now nullable - DB column has noNOT NULL(sameproject-ownermigration linked above).sdk:project_urlis now nullable - column has no default, never made NOT NULL.sdk+packages/types:project_coloris now non-null - a later migration hardened it toNOT NULLwith a backfill.migration
packages/types:module_baris now nullable - column has no default.packages/types:default_languageis now non-null - column was createdNOT NULLfrom the start.migration
app: added a null guard insystem-modules.vue'svalueToPreviewfor themodule_barnullability change above. See Review Notes.directus_userssdk: reordered to matchpackages/types/src/users.ts's field order.sdk: removed the phantomthemefield. The column was renamed toappearanceand split intotheme_dark/theme_lighthere:migration
(
packages/typesnever had this field).sdk: addedtext_direction(non-null) was missing from sdk only.migration
sdk+packages/types: added'inactive-license'to thestatusunion.choices list,
constant
sdk: tightenedappearanceto'auto' | 'dark' | 'light' | null', matching its 3-value choices list andpackages/types's existing typing.Tested Scenarios
pnpm --filter @directus/types build+pnpm --filter app exec vue-tsc --noEmit -p .after each field correction, to catch downstream breakage inapp/.Dry-run: cherry-picked Fix a type error in the module bar default configuration #27944's commit onto this branch to simulate the merge order, confirmed it clears theMerge order respected.MODULE_BAR_DEFAULTcascade with no new errors, then reverted it back out since it will land as its own squash-merged commit.Review Notes / Questions / Concerns
providernarrowed to'vercel' | 'netlify'- this was a judgment call, not backed by an established repo convention. The API enforces exactly these two values (controllers/deployment.ts), so a literal union matches real behavior better thanstring. Butsdk/src/schema/*.tshas no established pattern for this - the only precedent isdirectus_users.status, which is already typed as an inline literal union in bothsdkandpackages/types. There's no named/exported constant or type alias convention to reuse instead (e.g. notype DeploymentProvider = ...anywhere insdk/src/schema). Went with an inline literal union to matchstatus's existing style. Flagging in case there's a preferred convention I'm not aware of, or reviewers would rather this stay asstring?uploaded_onnullability is correct, but theremay beis a bug inonUploadFinish.outdated:
uploaded_onis nullable by design: a TUS (resumable) upload creates a placeholder record before the upload completes, souploaded_onis legitimately unset at that point.However,
onUploadFinishnever appears to setuploaded_onon completion - the finalupdateOnecall only includestus_id/tus_data/metadatafromextractMetadata(), none of which touchuploaded_on. If that's right, a file finished via TUS may keepuploaded_on: nullindefinitely. Compare with the regular (non-TUS) upload path, which sets it explicitly:files.ts:196.Not verified against a live TUS upload. Is this a known/intentional gap, and should it be fixed here or filed separately?
#27945 (comment)
Should
packages/typesmodel relational-field expansion consistently foruser_created-style fields?files.ts/versions.tstype these as plainstring | null(:fkonly);comments.ts/shares.tstype them asstring | User(allows an expanded object). The newStoredProject/StoredRun.user_createdfields went withstring | null, matching the majority. Runtime-wise, theuser-created/user-updatedspecials only ever resolve to a raw UUID ornull- theUser-object option comes from generic Directus field-expansion (any M2O relation can expand via thefieldsquery param), not something specific to these two files. There's no existing convention to defer to. Keepstring | nullas the default going forward, or standardize onstring | Usereverywhere?The pre-existing, unrelated
Field[]error at line 255 is untouched.I sorted the order for
directus_usersanddirectus_settingsin the SDK to match the listed order in Types because I was struggling to verify parity with the difference in order, it makes it harder to review the changes but easier to implement the fix (and maintain later). Sorry in advance.Is it worth it look at breaking out AI Settings into it's own object so it's easier to manage/review?
Probably worth cleaning up sort order with groupings with a comment for better readability. I did not do that here.
outdated:
settings.module_bar: runtime guard added here; the type-safety cascade it exposed is fixed by Fix a type error in the module bar default configuration #27944 (fix/27943-module-bar-default-typing, offmain), which this PR is blocked on.app/src/interfaces/_system/system-modules/system-modules.vue'svalueToPreviewcalled.flatMap(...)onSettings['module_bar']with no null check. Added a guard ((value ?? MODULE_BAR_DEFAULT).flatMap(...), matching howuse-visual-editing.ts:22andmodule-bar.vue:21already handle it) - that's fixed here.Making
module_barcorrectly nullable also surfaces 10vue-tscerrors in the same file (confirmed via a cherry-pick-and-revert dry run), all rooted inMODULE_BAR_DEFAULT(app/src/constants.ts) being an untyped array literal that doesn't structurally matchSettingsModuleBarLink | SettingsModuleBarModule, plus oneInferDefaulterror from thewithDefaultsfactory'sas Settings['module_bar']cast widening to includenull. That's fixed in Fix a type error in the module bar default configuration #27944: an explicit type annotation onMODULE_BAR_DEFAULT, and dropping the now-unneeded cast on the factory default. Fix a type error in the module bar default configuration #27944 merges first; this branch rebases ontomainonce it lands.Checklist
@directus/specs)@directus/sdk) updated to reflect the changes@directus/types) updated to reflect the changes@directus/system-data) updated for changes to system collections/fields/relations