Compare commits
10
Commits
v0.4.0
...
shared-base
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f2f3f0af1 | ||
|
|
e4b8c0f6aa | ||
|
|
68d5d46ec0 | ||
|
|
5f2e310f61 | ||
|
|
057162e45b | ||
|
|
46e30909c7 | ||
|
|
b2f2de2bd4 | ||
|
|
1b9202edf1 | ||
|
|
730e5902a5 | ||
|
|
f56d2811cb |
@@ -0,0 +1,25 @@
|
|||||||
|
# Contrôles de .github/workflows/ci.yml sur Gitea, par le workflow commun avalon-vanguard/ci.
|
||||||
|
# Ce dossier fait ignorer .github/workflows par Gitea ; GitHub continue d'exécuter les siens
|
||||||
|
# (CI, Pages, publication npm). Les contrôles post-build (points d'entrée, démo, types publiés,
|
||||||
|
# page de docs) sont regroupés dans le script « check ».
|
||||||
|
#
|
||||||
|
# node.yml lance « npm test », pas « test:coverage » : vitest.config.ts ne fixe aucun seuil de
|
||||||
|
# couverture et rien ne lit le rapport lcov, donc les mêmes tests décident du résultat.
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
pull_request:
|
||||||
|
branches: [main, develop]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
verify:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
node: [20.x, 22.x, 24.x]
|
||||||
|
uses: avalon-vanguard/ci/.gitea/workflows/node.yml@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
secrets: inherit
|
||||||
@@ -34,12 +34,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: npm run build
|
||||||
- name: Verify published entry points load
|
- name: Verify published entry points load
|
||||||
run: |
|
run: node scripts/check-entry-points.mjs
|
||||||
node --input-type=module -e "import * as m from './dist/esm/index.js'; if (typeof m.toInstance !== 'function') throw new Error('ESM entry point broken');"
|
|
||||||
node --input-type=commonjs -e "const m = require('./dist/cjs/index.js'); if (typeof m.toInstance !== 'function') throw new Error('CJS entry point broken');"
|
|
||||||
node --input-type=module -e "import { standardDecorators } from './dist/esm/vite.js'; if (standardDecorators().enforce !== 'pre') throw new Error('ESM cereale/vite broken');"
|
|
||||||
node --input-type=commonjs -e "const { standardDecorators } = require('./dist/cjs/vite.js'); if (standardDecorators().enforce !== 'pre') throw new Error('CJS cereale/vite broken');"
|
|
||||||
node --input-type=module -e "import * as m from './dist/cereale.min.js'; if (typeof m.toInstanceSync !== 'function') throw new Error('flat bundle broken');"
|
|
||||||
- name: Run Demo
|
- name: Run Demo
|
||||||
run: npm run demo
|
run: npm run demo
|
||||||
- name: Published types stand alone
|
- name: Published types stand alone
|
||||||
|
|||||||
@@ -4,10 +4,28 @@ name: Publish to npm
|
|||||||
# not a decision to make it public and immutable, and npm's 72-hour unpublish window makes the
|
# not a decision to make it public and immutable, and npm's 72-hour unpublish window makes the
|
||||||
# second one hard to take back. Run this workflow from the Actions tab when you mean it.
|
# second one hard to take back. Run this workflow from the Actions tab when you mean it.
|
||||||
#
|
#
|
||||||
# Before the first real run:
|
# Authentication is by **trusted publishing** (OIDC): npm exchanges the workflow's
|
||||||
# 1. Create an npm automation token and add it as the NPM_TOKEN repository secret.
|
# short-lived GitHub identity token for a publish token scoped to this package, so no
|
||||||
# 2. Run once with dry_run left as `true` and read the file list it prints.
|
# long-lived npm token has to exist. To enable it, on npmjs.com → the cereale package →
|
||||||
# 3. Run again with dry_run set to `false`.
|
# Settings → Trusted publisher → GitHub Actions, set:
|
||||||
|
#
|
||||||
|
# Organization or user: avalon-vanguard
|
||||||
|
# Repository: cereale
|
||||||
|
# Workflow filename: release.yml
|
||||||
|
# Environment: (leave blank — this workflow does not use one)
|
||||||
|
#
|
||||||
|
# The workflow filename must match this file's name, and the Environment field must be
|
||||||
|
# blank unless a matching `environment:` is added to the publish job; npm checks both
|
||||||
|
# against the OIDC claims and refuses the exchange if either disagrees.
|
||||||
|
#
|
||||||
|
# NPM_TOKEN is kept as a fallback. npm's OIDC step is deliberately non-throwing — if the
|
||||||
|
# trusted publisher is not configured, or the CLI is too old, it logs and falls through
|
||||||
|
# to token auth. That makes the switch safe to land before the registry side is set up.
|
||||||
|
# Once a real run shows OIDC working, the NPM_TOKEN secret can be deleted.
|
||||||
|
#
|
||||||
|
# Before a real run:
|
||||||
|
# 1. Run once with dry_run left as `true` and read the file list it prints.
|
||||||
|
# 2. Run again with dry_run set to `false`.
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
@@ -18,7 +36,7 @@ on:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write # required for npm provenance
|
id-token: write # the OIDC identity npm exchanges, and provenance
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
@@ -37,6 +55,21 @@ jobs:
|
|||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
|
# Node 22 bundles npm 10.x, which has no OIDC support at all — it would skip
|
||||||
|
# trusted publishing in silence and fall back to token auth. Trusted publishing
|
||||||
|
# landed in npm 11.5.0 (lib/utils/oidc.js), so the version is raised and then
|
||||||
|
# asserted rather than assumed.
|
||||||
|
- name: Use an npm that can do trusted publishing
|
||||||
|
run: |
|
||||||
|
npm install -g npm@latest
|
||||||
|
V=$(npm --version)
|
||||||
|
echo "npm $V"
|
||||||
|
MAJ=${V%%.*}; REST=${V#*.}; MIN=${REST%%.*}
|
||||||
|
if [ "$MAJ" -lt 11 ] || { [ "$MAJ" -eq 11 ] && [ "$MIN" -lt 5 ]; }; then
|
||||||
|
echo "::error::npm $V has no OIDC support; trusted publishing needs >= 11.5.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
@@ -72,12 +105,28 @@ jobs:
|
|||||||
run: npm run verify
|
run: npm run verify
|
||||||
|
|
||||||
- name: Show exactly what would ship
|
- name: Show exactly what would ship
|
||||||
|
# `npm publish --dry-run` performs the OIDC token exchange before it short-circuits
|
||||||
|
# (publish.js calls oidc() ahead of every dryRun branch), so this step is also the
|
||||||
|
# trusted-publishing smoke test — a dry run proves the exchange without publishing.
|
||||||
|
#
|
||||||
|
# verbose, because npm's OIDC step is non-throwing: at the default log level a
|
||||||
|
# successful exchange and a silent fallback to token auth look identical. Success
|
||||||
|
# prints `oidc Successfully retrieved and set token`; if that line is missing,
|
||||||
|
# trusted publishing did not engage. (The reasons it skips are logged at silly.)
|
||||||
|
env:
|
||||||
|
NPM_CONFIG_LOGLEVEL: verbose
|
||||||
run: npm publish --dry-run
|
run: npm publish --dry-run
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
if: ${{ inputs.dry_run == false }}
|
if: ${{ inputs.dry_run == false }}
|
||||||
|
# --provenance stays explicit. Under OIDC npm would enable it on its own for a
|
||||||
|
# public repo, but only when the flag was left at its default; asking for it
|
||||||
|
# directly just skips that auto-enable and reaches the same place. On the token
|
||||||
|
# fallback path it is the only thing that produces an attestation at all.
|
||||||
run: npm publish --provenance --access public
|
run: npm publish --provenance --access public
|
||||||
env:
|
env:
|
||||||
|
# Fallback only. Ignored once the trusted publisher is configured, because npm
|
||||||
|
# sets its own short-lived token before reading credentials.
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
- name: Summary
|
- name: Summary
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
@avalon-vanguard:registry=https://git.avalonvanguard.com/api/packages/avalon-vanguard/npm/
|
||||||
@@ -5,6 +5,20 @@ All notable changes to this project are documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.4.1] - 2026-08-20
|
||||||
|
|
||||||
|
No code changes. Every emitted file is byte-identical to 0.4.0 except the banner line of
|
||||||
|
`dist/cereale.min.js`, which carries the version string. This exists because the README
|
||||||
|
inside the 0.4.0 tarball is the one npmjs.com renders, and it said the package was not on
|
||||||
|
npm: *"`npm install cereale` does not resolve to this library — the name is unclaimed on
|
||||||
|
the registry."* True when it was written, nonsense on the package page of the thing it
|
||||||
|
describes.
|
||||||
|
|
||||||
|
0.4.0 was the first publish, so nothing could have carried the corrected text: the docs
|
||||||
|
could only be fixed after the registry proved the claim wrong. The install instructions,
|
||||||
|
the landing page panel, and the "what cereale is not" entry now say `npm install cereale`,
|
||||||
|
and the README carries an npm version badge.
|
||||||
|
|
||||||
## [0.4.0] - 2026-08-05
|
## [0.4.0] - 2026-08-05
|
||||||
|
|
||||||
### `cereale/min` — one file, no bundler
|
### `cereale/min` — one file, no bundler
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# Cereale
|
# Cereale
|
||||||
|
|
||||||
|
[](https://www.npmjs.com/package/cereale)
|
||||||
[](https://github.com/avalon-vanguard/cereale/actions/workflows/ci.yml)
|
[](https://github.com/avalon-vanguard/cereale/actions/workflows/ci.yml)
|
||||||
[](https://avalon-vanguard.github.io/cereale/)
|
[](https://avalon-vanguard.github.io/cereale/)
|
||||||
[](https://github.com/avalon-vanguard/cereale/blob/main/package.json)
|
[](https://github.com/avalon-vanguard/cereale/blob/main/package.json)
|
||||||
@@ -79,20 +80,13 @@ entity, anything with behaviour attached. Reach for Zod when you just want the d
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Not on npm yet: `npm install cereale` does **not** resolve to this library — the name is
|
|
||||||
unclaimed on the registry. Installing straight from GitHub will not work either, because the
|
|
||||||
build output is not committed. Until the first publish, install from a clone:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/avalon-vanguard/cereale
|
npm install cereale
|
||||||
cd cereale
|
|
||||||
npm install && npm run build
|
|
||||||
npm pack # → cereale-0.4.0.tgz
|
|
||||||
|
|
||||||
# then, from your own project
|
|
||||||
npm install ../cereale/cereale-0.4.0.tgz
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Published with [provenance](https://www.npmjs.com/package/cereale), so the registry carries a
|
||||||
|
verified attestation linking the tarball to the commit it was built from.
|
||||||
|
|
||||||
Cereale uses **TC39 standard decorators** (since 0.2.0), so no `experimentalDecorators` flag:
|
Cereale uses **TC39 standard decorators** (since 0.2.0), so no `experimentalDecorators` flag:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|||||||
+11
-16
@@ -410,7 +410,7 @@ footer { border-top: 1px solid var(--border); padding-block: 2.5rem; color: var(
|
|||||||
|
|
||||||
<header class="nav">
|
<header class="nav">
|
||||||
<div class="wrap nav-inner">
|
<div class="wrap nav-inner">
|
||||||
<a class="brand" href="#top"><svg class="mark" width="10" height="18" viewBox="0 0 10 18" aria-hidden="true" focusable="false"><rect x="4" y="0" width="2" height="18" fill="currentColor" opacity=".3"/><rect x="0" y="2" width="10" height="2" fill="currentColor"/><rect x="0" y="6" width="10" height="2" fill="currentColor"/><rect x="0" y="10" width="10" height="2" fill="currentColor"/><rect x="0" y="14" width="10" height="2" fill="currentColor"/></svg>cereale <span class="badge" id="version-badge">v0.4.0</span></a>
|
<a class="brand" href="#top"><svg class="mark" width="10" height="18" viewBox="0 0 10 18" aria-hidden="true" focusable="false"><rect x="4" y="0" width="2" height="18" fill="currentColor" opacity=".3"/><rect x="0" y="2" width="10" height="2" fill="currentColor"/><rect x="0" y="6" width="10" height="2" fill="currentColor"/><rect x="0" y="10" width="10" height="2" fill="currentColor"/><rect x="0" y="14" width="10" height="2" fill="currentColor"/></svg>cereale <span class="badge" id="version-badge">v0.4.1</span></a>
|
||||||
<nav class="nav-links" aria-label="Primary">
|
<nav class="nav-links" aria-label="Primary">
|
||||||
<a class="nav-hide" href="#guarantee">Guarantee</a>
|
<a class="nav-hide" href="#guarantee">Guarantee</a>
|
||||||
<a class="nav-hide" href="#playground">Playground</a>
|
<a class="nav-hide" href="#playground">Playground</a>
|
||||||
@@ -814,22 +814,15 @@ export default defineConfig({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class="compare-label"><span class="pill pill-bad">not on npm yet</span> installing it today</p>
|
<p class="compare-label"><span class="pill pill-ok">on npm</span> installing it</p>
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<div class="code-head"><span class="name">shell</span></div>
|
<div class="code-head"><span class="name">shell</span></div>
|
||||||
<pre><code data-lang="text" id="install-shell">git clone https://github.com/avalon-vanguard/cereale
|
<pre><code data-lang="text">npm install cereale</code></pre>
|
||||||
cd cereale
|
|
||||||
npm install && npm run build
|
|
||||||
npm pack # → cereale-0.4.0.tgz
|
|
||||||
|
|
||||||
# then, from your own project
|
|
||||||
npm install ../cereale/cereale-0.4.0.tgz</code></pre>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="pg-note">
|
<p class="pg-note">
|
||||||
<code class="inline-code">npm install cereale</code> does <strong>not</strong> resolve to
|
Published from CI with <strong>provenance</strong>, so the registry carries a verified
|
||||||
this library — the name is unclaimed on the registry. Installing straight from GitHub
|
attestation linking the tarball to the commit it was built from — visible on the
|
||||||
will not work either: the build output is not committed, so the package would arrive
|
<a href="https://www.npmjs.com/package/cereale">package page</a>.
|
||||||
without its <code class="inline-code">dist/</code>.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -998,9 +991,11 @@ npm install ../cereale/cereale-0.4.0.tgz</code></pre>
|
|||||||
cannot reach. Both are errors rather than silent no-ops.</p>
|
cannot reach. Both are errors rather than silent no-ops.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="note-item">
|
<div class="note-item">
|
||||||
<h3>It is not on npm yet</h3>
|
<h3>It is still 0.x</h3>
|
||||||
<p><span class="js-version">0.4.0</span> lives in the repository. <code class="inline-code">npm install cereale</code> does not
|
<p><span class="js-version">0.4.1</span> is published, and under semver a 0.x minor bump
|
||||||
resolve to this library — build it from source until it is published.</p>
|
is allowed to break you. Pin the version until 1.0; the
|
||||||
|
<a href="https://github.com/avalon-vanguard/cereale/blob/main/CHANGELOG.md">changelog</a>
|
||||||
|
says what moved and why.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// Generated by scripts/build-docs.mjs — do not edit.
|
// Generated by scripts/build-docs.mjs — do not edit.
|
||||||
window.CEREALE_META = {
|
window.CEREALE_META = {
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,12 +43,6 @@
|
|||||||
Array.prototype.forEach.call(document.querySelectorAll('.js-version'), function (el) {
|
Array.prototype.forEach.call(document.querySelectorAll('.js-version'), function (el) {
|
||||||
el.textContent = meta.version;
|
el.textContent = meta.version;
|
||||||
});
|
});
|
||||||
// The install snippet names the tarball npm pack produces; keep it tied to the
|
|
||||||
// same package.json fact the badge uses instead of hand-bumping it each release.
|
|
||||||
var shell = document.getElementById('install-shell');
|
|
||||||
if (shell) {
|
|
||||||
shell.textContent = shell.textContent.replace(/cereale-[\d.]+\.tgz/g, 'cereale-' + meta.version + '.tgz');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (decoratorCount) {
|
if (decoratorCount) {
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.js-dec-count'), function (el) {
|
Array.prototype.forEach.call(document.querySelectorAll('.js-dec-count'), function (el) {
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
import eslint from '@eslint/js';
|
import avalonBase from '@avalon-vanguard/config/eslint';
|
||||||
import tseslint from 'typescript-eslint';
|
import tseslint from 'typescript-eslint';
|
||||||
import globals from 'globals';
|
import globals from 'globals';
|
||||||
|
|
||||||
@@ -6,8 +6,8 @@ export default tseslint.config(
|
|||||||
{
|
{
|
||||||
ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'docs/**'],
|
ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'docs/**'],
|
||||||
},
|
},
|
||||||
eslint.configs.recommended,
|
// @eslint/js recommended + typescript-eslint recommended, shared across avalon-vanguard
|
||||||
...tseslint.configs.recommended,
|
avalonBase,
|
||||||
{
|
{
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
|
|||||||
Generated
+35
-2
@@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "cereale",
|
"name": "cereale",
|
||||||
"version": "0.3.0",
|
"version": "0.4.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cereale",
|
"name": "cereale",
|
||||||
"version": "0.3.0",
|
"version": "0.4.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@avalon-vanguard/config": "^1.0.0",
|
||||||
"@babel/standalone": "^8.0.4",
|
"@babel/standalone": "^8.0.4",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@swc/core": "^1.15.47",
|
"@swc/core": "^1.15.47",
|
||||||
@@ -26,6 +27,38 @@
|
|||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@avalon-vanguard/config": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://git.avalonvanguard.com/api/packages/avalon-vanguard/npm/%40avalon-vanguard%2Fconfig/-/1.0.0/config-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ySojd0OONRb9N9KT4CJeyLf5GUrfRP8jxfPTMRv3HUk7gld4VuzZd16lW774SfLkMBMOUYVVf9SKBMO+JATTTA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@eslint/js": "^10.0.0",
|
||||||
|
"angular-eslint": "^22.0.0",
|
||||||
|
"eslint": "^10.0.0",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"typescript": "^6.0.0",
|
||||||
|
"typescript-eslint": "^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@eslint/js": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"angular-eslint": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"eslint": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"typescript-eslint": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
"version": "7.29.7",
|
"version": "7.29.7",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cereale",
|
"name": "cereale",
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"description": "Strongly typed JSON mapping and validation for TypeScript classes \u2014 validated domain objects, not validated data. A zero-dependency replacement for class-validator + class-transformer, on TC39 standard decorators.",
|
"description": "Strongly typed JSON mapping and validation for TypeScript classes \u2014 validated domain objects, not validated data. A zero-dependency replacement for class-validator + class-transformer, on TC39 standard decorators.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/cjs/index.js",
|
"main": "./dist/cjs/index.js",
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
"build:docs": "node scripts/build-docs.mjs",
|
"build:docs": "node scripts/build-docs.mjs",
|
||||||
"demo": "node --no-warnings=ExperimentalWarning --loader ts-node/esm src/example.ts",
|
"demo": "node --no-warnings=ExperimentalWarning --loader ts-node/esm src/example.ts",
|
||||||
"type-check": "tsc --noEmit",
|
"type-check": "tsc --noEmit",
|
||||||
|
"typecheck": "npm run type-check",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"test:watch": "vitest",
|
"test:watch": "vitest",
|
||||||
"test:coverage": "vitest run --coverage",
|
"test:coverage": "vitest run --coverage",
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
"lint:fix": "eslint . --fix",
|
"lint:fix": "eslint . --fix",
|
||||||
"verify": "npm run type-check && npm run lint && npm run test && npm run build && npm run check:types && npm run check:docs",
|
"verify": "npm run type-check && npm run lint && npm run test && npm run build && npm run check:types && npm run check:docs",
|
||||||
"prepublishOnly": "npm run verify",
|
"prepublishOnly": "npm run verify",
|
||||||
|
"check": "node scripts/check-entry-points.mjs && npm run demo && npm run check:types && npm run check:docs && npm run check:docs-sync",
|
||||||
"check:docs": "node scripts/check-docs.mjs",
|
"check:docs": "node scripts/check-docs.mjs",
|
||||||
"check:types": "node scripts/check-types.mjs",
|
"check:types": "node scripts/check-types.mjs",
|
||||||
"check:docs-sync": "npm run build:docs && node scripts/check-docs-sync.mjs"
|
"check:docs-sync": "npm run build:docs && node scripts/check-docs-sync.mjs"
|
||||||
@@ -79,6 +81,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://avalon-vanguard.github.io/cereale/",
|
"homepage": "https://avalon-vanguard.github.io/cereale/",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@avalon-vanguard/config": "^1.0.0",
|
||||||
"@babel/standalone": "^8.0.4",
|
"@babel/standalone": "^8.0.4",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@swc/core": "^1.15.47",
|
"@swc/core": "^1.15.47",
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": ["local>avalon-vanguard/renovate-config"]
|
||||||
|
}
|
||||||
@@ -49,6 +49,27 @@ await writeFile(
|
|||||||
`window.CEREALE_META = ${JSON.stringify({ version: pkg.version, node: pkg.engines.node }, null, 2)};\n`
|
`window.CEREALE_META = ${JSON.stringify({ version: pkg.version, node: pkg.engines.node }, null, 2)};\n`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 2b. The same version, stamped into the two spots in index.html that page.js later
|
||||||
|
// overwrites from meta.js. Those are the no-JavaScript fallbacks: correct in a browser,
|
||||||
|
// stale in a text reader or a scraper, and hand-bumped until now — they went stale on
|
||||||
|
// 0.4.0 and again on 0.4.1. Stamping them here means the docs-sync gate catches the
|
||||||
|
// drift instead of a reviewer. The regexes are asserted, so if the markup is renamed
|
||||||
|
// the build fails loudly rather than silently stamping nothing.
|
||||||
|
const indexPath = path.join(docs, 'index.html');
|
||||||
|
let index = await readFile(indexPath, 'utf8');
|
||||||
|
const stamps = [
|
||||||
|
[/(<span class="badge" id="version-badge">)v[\d.]+(<\/span>)/, `$1v${pkg.version}$2`],
|
||||||
|
[/(<span class="js-version">)[\d.]+(<\/span>)/g, `$1${pkg.version}$2`],
|
||||||
|
];
|
||||||
|
for (const [re, replacement] of stamps) {
|
||||||
|
if (!re.test(index)) {
|
||||||
|
console.error(`build-docs: nothing in docs/index.html matched ${re} — the version fallback markup moved.`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
index = index.replace(re, replacement);
|
||||||
|
}
|
||||||
|
await writeFile(indexPath, index);
|
||||||
|
|
||||||
// 3. The compiler errors the page quotes, produced by actually running the compiler. If a
|
// 3. The compiler errors the page quotes, produced by actually running the compiler. If a
|
||||||
// snippet the page calls a compile error ever compiles, this fails the build.
|
// snippet the page calls a compile error ever compiles, this fails the build.
|
||||||
const { byCase, problems } = await collectDiagnostics(root);
|
const { byCase, problems } = await collectDiagnostics(root);
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Fails if a published entry point does not load from dist/: `.` and `./vite`, each as ESM
|
||||||
|
* and as CommonJS, and the flat `./min` bundle. Run after `npm run build` (first step of
|
||||||
|
* `npm run check`). Moved here from inline `node -e` lines in .github/workflows/ci.yml so
|
||||||
|
* that the GitHub and Gitea workflows run the same check.
|
||||||
|
*/
|
||||||
|
import { createRequire } from 'node:module';
|
||||||
|
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
const assert = (ok, what) => {
|
||||||
|
if (!ok) throw new Error(`${what} broken`);
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(typeof (await import('../dist/esm/index.js')).toInstance === 'function', 'ESM entry point');
|
||||||
|
assert(typeof require('../dist/cjs/index.js').toInstance === 'function', 'CJS entry point');
|
||||||
|
assert((await import('../dist/esm/vite.js')).standardDecorators().enforce === 'pre', 'ESM cereale/vite');
|
||||||
|
assert(require('../dist/cjs/vite.js').standardDecorators().enforce === 'pre', 'CJS cereale/vite');
|
||||||
|
assert(typeof (await import('../dist/cereale.min.js')).toInstanceSync === 'function', 'flat bundle');
|
||||||
+4
-10
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
// Visit https://aka.ms/tsconfig to read more about this file
|
// Visit https://aka.ms/tsconfig to read more about this file
|
||||||
|
// Shared (@avalon-vanguard/config/tsconfig/library.json): sourceMap, declaration,
|
||||||
|
// declarationMap, noImplicitReturns, noImplicitOverride, noFallthroughCasesInSwitch,
|
||||||
|
// isolatedModules, skipLibCheck.
|
||||||
|
"extends": "@avalon-vanguard/config/tsconfig/library.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
// File Layout
|
// File Layout
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
@@ -11,27 +15,17 @@
|
|||||||
"lib": ["ESNext", "ESNext.Decorators"],
|
"lib": ["ESNext", "ESNext.Decorators"],
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
|
|
||||||
// Other Outputs
|
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
|
|
||||||
// Stricter Typechecking Options
|
// Stricter Typechecking Options
|
||||||
"noUncheckedIndexedAccess": true,
|
"noUncheckedIndexedAccess": true,
|
||||||
"exactOptionalPropertyTypes": true,
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
// Style Options
|
// Style Options
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noImplicitOverride": true,
|
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
|
|
||||||
// Recommended Options
|
// Recommended Options
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"strictPropertyInitialization": false,
|
"strictPropertyInitialization": false,
|
||||||
"isolatedModules": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
|
|
||||||
// NOTE: no `experimentalDecorators`. v2 uses TC39 standard decorators, which is what
|
// NOTE: no `experimentalDecorators`. v2 uses TC39 standard decorators, which is what
|
||||||
// gives ClassFieldDecoratorContext<This, Value> and therefore compile-time checking of
|
// gives ClassFieldDecoratorContext<This, Value> and therefore compile-time checking of
|
||||||
|
|||||||
Reference in New Issue
Block a user