|
| 1 | +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. |
| 2 | + |
| 3 | +import type { SemanticMigration } from '../../types.js'; |
| 4 | + |
| 5 | +// #29308. An accept-set narrowing of `DatasourceSchema.name` with no |
| 6 | +// conversion: a datasource named after a literal the datasource admin API |
| 7 | +// mounts beside its by-name read (`drivers`, the driver catalog) is refused. |
| 8 | +// The new name, and every object `datasource` / `datasourceMapping` rule that |
| 9 | +// routes to it, only the author can pick. Same class as |
| 10 | +// stack-datasource-host-reserved-name-refused. |
| 11 | +export const entry: SemanticMigration = { |
| 12 | + id: 'datasource-name-route-shadowed-refused', |
| 13 | + surface: 'a datasource whose `name` is one of `ROUTE_SHADOWED_DATASOURCE_NAMES` (today `drivers`), ' |
| 14 | + + 'e.g. defineDatasource({ name: \'drivers\', driver: \'postgres\', config: { … } }), in ' |
| 15 | + + '`defineDatasource`, a stack\'s `datasources`, `os validate`, `os build` and the metadata save door ' |
| 16 | + + '(`PUT /api/v1/meta/datasource/drivers`)', |
| 17 | + replacement: 'The same datasource under another snake_case name (e.g. `driver_registry`), with every ' |
| 18 | + + 'object that names it (`datasource`, or a `datasourceMapping` rule) pointed at the new name. ⛔ NOT ' |
| 19 | + + 'mechanically convertible: the new name is the author\'s call.', |
| 20 | + reason: |
| 21 | + 'The datasource admin API mounts the driver catalog at `GET /api/v1/datasources/drivers`, ahead of ' |
| 22 | + + 'the by-name read `GET /api/v1/datasources/:name`, so a datasource named `drivers` was stored and ' |
| 23 | + + 'listed while its detail read (the load of its Setup edit form) always answered the catalog. The ' |
| 24 | + + 'admin create door already refused the name; `DatasourceSchema.name` accepted it, so the same ' |
| 25 | + + 'unreachable datasource was still minted from code and through the metadata save door. The schema ' |
| 26 | + + 'now refuses every name in `ROUTE_SHADOWED_DATASOURCE_NAMES`, the one list the admin routes mount ' |
| 27 | + + 'from, with an `invalid_format` issue at `name` naming the name and the route; the published JSON ' |
| 28 | + + 'Schema carries the refusal as a second `pattern`. Measured producers: none in this repository.', |
| 29 | + acceptanceCriteria: |
| 30 | + 'No datasource is named `drivers`; `defineStack`, `os validate` and `os build` report no issue at ' |
| 31 | + + '`name` (or `datasources.N.name`) reading "Datasource name \'drivers\' is reserved", and the ' |
| 32 | + + 'metadata save door answers 200 for the renamed datasource. A stored `sys_metadata` datasource row ' |
| 33 | + + 'named `drivers` still loads, with `_diagnostics` reading `valid: false` and carrying this refusal, ' |
| 34 | + + 'and its next metadata save is refused; nothing rewrites it. Through the admin door that row stays ' |
| 35 | + + 'listed and removable, and a `label`/`active`-only edit still saves.', |
| 36 | +}; |
0 commit comments