🔊 feat!: make the three silent failures loud
Every change here answers one question: where does cereale currently fail
without saying so?
**Vite 8 / Vitest 4 drop decorators silently.** Both transform with oxc,
which does not implement the standard decorator transform and does not
report that. `vitest` prints "0 test" beside a bare SyntaxError, and
`vite build` reports success while emitting a bundle that throws on first
import. Ship the plugin that fixes it as `cereale/vite`, transforming with
esbuild and falling back to tsc — cereale depends on neither. The library's
own suite now runs through it, so it is exercised by every test.
**Legacy decorators died opaquely.** With `experimentalDecorators: true`,
still the default in most existing TypeScript projects, decorators are
invoked as (prototype, "name") and cereale raised "TypeError: Cannot convert
undefined or null to object". All decorators now resolve metadata through
one checkpoint that names the tsconfig setting instead, and reject
application to a method, getter or accessor field.
**Values JSON cannot carry were emptied.** A populated Map serialized to
{}, a Uint8Array to index-keyed noise, a bigint straight through so the
caller's own JSON.stringify threw somewhere unrelated. All now raise
JsonMappingError naming the property path and both ways out. Covers what a
@JsonSerialize serializer returns, sync or async. Circular-reference and
depth errors name the path too.
Also fixed: defineRule on a subclass with no decorators of its own wrote
the rule into its base class, because the base's metadata object is
inherited through the static prototype chain and `??=` found it non-nullish.
The README's toolchain table (tsc, esbuild, swc ✅, oxc ❌) is now executed
by a test rather than asserted, and the positioning leads with
class-validator + class-transformer, the stack cereale actually replaces,
rather than Zod, which it deliberately is not.
193 -> 249 tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
This commit is contained in:
+3
-27
@@ -1,34 +1,10 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { transform } from 'esbuild';
|
||||
import { standardDecorators } from './src/vite.js';
|
||||
|
||||
/**
|
||||
* Transpiles test sources with esbuild instead of oxc.
|
||||
*
|
||||
* Vitest 4 transforms with oxc, which does not yet implement the TC39 standard decorator
|
||||
* transform — it leaves the syntax in place and Node then fails to parse it, reporting
|
||||
* "0 test" rather than an error. esbuild and tsc both implement it, so the library's own
|
||||
* build (`tsc`) and consumers bundling with esbuild or Vite are unaffected; only the test
|
||||
* runner needs this. Remove it once oxc gains standard-decorator support.
|
||||
* The library's own tests run through the plugin the library ships, so that `cereale/vite`
|
||||
* is exercised by every test run rather than only by the one test that asserts it exists.
|
||||
*/
|
||||
function standardDecorators() {
|
||||
return {
|
||||
name: 'cereale:standard-decorators',
|
||||
enforce: 'pre' as const,
|
||||
async transform(code: string, id: string) {
|
||||
if (!/\.ts$/.test(id) || id.includes('node_modules')) return null;
|
||||
const result = await transform(code, {
|
||||
loader: 'ts',
|
||||
target: 'es2022',
|
||||
sourcefile: id,
|
||||
sourcemap: true,
|
||||
// Standard semantics, not the legacy ones: the library reads context.metadata.
|
||||
tsconfigRaw: { compilerOptions: { experimentalDecorators: false, useDefineForClassFields: true } },
|
||||
});
|
||||
return { code: result.code, map: result.map };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [standardDecorators()],
|
||||
test: {
|
||||
|
||||
Reference in New Issue
Block a user