Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/8165-translatefn-one-authority.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
---

Re-point `saveAdvisoryToast`'s `TranslateFn` at its one authority,
`writeWarningToast` (objectui#8165), and shrink the `KNOWN_COLLISIONS` baseline
in `scripts/__tests__/one-authority-per-exported-name-6273.test.ts` by that
site. Type-level only: the declaration was byte-identical to the one it now
re-exports, the name is on no package's published face, and `export type { X }
from '…'` erases at build — so no package is released by this change.
34 changes: 32 additions & 2 deletions packages/app-shell/src/providers/saveAdvisoryToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,39 @@
*/

import type { MetadataSaveAdvisoryEvent } from '@object-ui/data-objectstack';
import type { TranslateFn } from './writeWarningToast.js';

/** i18next's `t`, narrowed to what this module uses. */
export type TranslateFn = (key: string, options?: Record<string, unknown>) => string;
/**
* i18next's `t`, narrowed to what this module uses — RE-EXPORTED from
* `writeWarningToast`, never re-declared.
*
* This module carried its own byte-identical copy until objectui#8165. The
* objectui#6172 甲/A1 ruling is that every exported name has exactly one
* authority, and
* `scripts/__tests__/one-authority-per-exported-name-6273.test.ts` had been
* carrying `TranslateFn` as accepted debt across three files. The remedy that
* gate names is exactly this: `export type { X } from '<the-owner>'` is a
* re-export, not a second declaration, and the gate does not count it. ⛔ Its
* baseline is SHRINK-ONLY, so the entry lost this site in the same PR.
*
* Why `writeWarningToast` is the one pointed at — read off the tree rather
* than decided here:
*
* - `AdapterProvider` is the single caller of all three emitters, and it
* already imports `TranslateFn` from `./writeWarningToast.js` and passes
* that one value into `emitSaveAdvisories` alongside the other two.
* - `metadataReadWarningToast.ts` re-points at it for the same reason, and
* `file-size-guard.ts` names it in its own docblock as the established
* pattern it was copied from.
*
* ⚠️ The THIRD site — `packages/fields/src/widgets/file-size-guard.ts` — is
* deliberately NOT re-pointed and stays on the baseline. `@object-ui/app-shell`
* DEPENDS ON `@object-ui/fields`, so a re-export in that direction is a package
* cycle, and this name is on neither package's published face. Retiring that
* copy means moving the authority DOWN into a package both depend on — a
* different change, and one nobody has ruled on (objectui#8165 reports it).
*/
export type { TranslateFn } from './writeWarningToast.js';

/**
* Where the message goes. Structurally satisfied by sonner's `toast`, which is
Expand Down
22 changes: 21 additions & 1 deletion scripts/__tests__/one-authority-per-exported-name-6273.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,27 @@ const KNOWN_COLLISIONS: ReadonlyMap<string, readonly string[]> = new Map([
['RecordDetailDrawerProps', ['packages/plugin-dashboard/src/RecordDetailDrawer.tsx', 'packages/plugin-detail/src/RecordDetailDrawer.tsx']],
['SchemaNode', ['packages/sdui-parser/src/types.ts', 'packages/types/src/base.ts']],
['ThemeProviderProps', ['packages/providers/src/types.ts', 'packages/react/src/context/ThemeContext.tsx']],
['TranslateFn', ['packages/app-shell/src/providers/saveAdvisoryToast.ts', 'packages/app-shell/src/providers/writeWarningToast.ts', 'packages/fields/src/widgets/file-size-guard.ts']],
// `TranslateFn` lost its `packages/app-shell/src/providers/saveAdvisoryToast.ts`
// site in objectui#8165. All three declarations were BYTE-IDENTICAL when that
// was measured (86 bytes each, one sha256 across the three), so there was no
// shape to reconcile; and the authority did not need choosing, because
// `AdapterProvider` is the single caller of all three emitters and already
// imported the type from `./writeWarningToast.js`, passing that one value into
// each of them. `saveAdvisoryToast.ts` now re-exports it, which this gate does
// not count.
//
// ⚠️ The `packages/fields` site STAYS, and that is a measurement rather than an
// oversight. The re-export remedy is dependency-illegal there:
// `@object-ui/app-shell` DEPENDS ON `@object-ui/fields`, so pointing fields at
// app-shell is a package cycle — and `TranslateFn` is on neither package's
// published face (`app-shell/src/index.ts` names it nowhere and has no star
// re-export; `fields/src/index.tsx` stars 50-odd widget modules but not
// `file-size-guard.js`, and none of its three importers re-export the name), so
// there would be nothing to import either. Retiring the last copy means moving
// the authority DOWN into a package both depend on — the `KanbanSchema` route
// above — which publishes a new name from that package and is a decision
// nobody has made. objectui#8165 reports it instead of guessing.
['TranslateFn', ['packages/app-shell/src/providers/writeWarningToast.ts', 'packages/fields/src/widgets/file-size-guard.ts']],
['UndoRedoState', ['packages/plugin-designer/src/hooks/useUndoRedo.ts', 'packages/types/src/ui-action.ts']],
['UserDataAdapter', ['packages/app-shell/src/context/UserStateAdapters.tsx', 'packages/data-objectstack/src/userState.ts']],
// `ValidationFunction` sat here, colliding between
Expand Down
Loading