diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 988a8fd..b2b8684 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: node-version: 22 cache: pnpm - run: pnpm install --frozen-lockfile + - run: pnpm check:publisher # Fails if any derived version reference (examples pins, README CDN # pins, sibling package versions) lags the core package version. - run: pnpm check:versions diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index f35a07d..1db13e0 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -26,6 +26,7 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile + - run: pnpm build:publisher - run: pnpm verify diff --git a/package.json b/package.json index 6d98958..013a658 100644 --- a/package.json +++ b/package.json @@ -16,15 +16,18 @@ "build": "pnpm -r build", "test": "pnpm -r test", "typecheck": "pnpm -r typecheck", - "verify": "pnpm check:brand && pnpm check:versions && pnpm build && pnpm typecheck && pnpm test", + "verify": "pnpm check:publisher && pnpm check:brand && pnpm check:versions && pnpm build && pnpm typecheck && pnpm test", "sync:versions": "node scripts/sync-versions.mjs", "check:versions": "node scripts/sync-versions.mjs --check", "check:brand": "node scripts/check-brand-assets.mjs", "build:pages": "node scripts/build-pages.mjs", - "changeset": "changeset" + "changeset": "changeset", + "build:publisher": "node scripts/build-publisher.mjs", + "check:publisher": "node scripts/build-publisher.mjs --check" }, "devDependencies": { "@changesets/cli": "^2.27.10", + "@devslab/site-kit": "0.8.0", "jsdom": "^25.0.1", "tsup": "^8.3.5", "typescript": "^5.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b49419..48a33e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@changesets/cli': specifier: ^2.27.10 version: 2.31.1 + '@devslab/site-kit': + specifier: 0.8.0 + version: 0.8.0(solid-js@1.9.15) jsdom: specifier: ^25.0.1 version: 25.0.1 @@ -342,6 +345,32 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} + '@devslab/dds-css@0.8.0': + resolution: {integrity: sha512-PxibTv92uMzU3rKtOesFUOSR5x3RWp3JHoO9LBidlqwFOjg37+Wd/Y7prLA8mw7USJ1FnF/R5Q4xHDJHk3iCAQ==} + + '@devslab/dds-icons@0.8.0': + resolution: {integrity: sha512-kspidNuH1A1E9euuVYlsw5D+vLsPZf01+lGShyB186ru7UEsLkz3epdNH9ry+OPx4lloGYzigyyqq1jwBK8Ofg==} + + '@devslab/dds-solid@0.8.0': + resolution: {integrity: sha512-Q05I3QeiaIJga1ixgw+usw3U9Oc4V8tps8mv/Jylu1B0uip4IiAILIM2sePaeJe/ciGfRTxJRsAtprqfyk9I/w==} + peerDependencies: + solid-js: 1.9.15 + + '@devslab/dds-tokens@0.8.0': + resolution: {integrity: sha512-lI/K50/jbKFWjlnTIBce23xry7JbJ1Io461VwUjpLvTAxTrZ5vee9ybosSMSTIs/BDWQidt6V80ghZxsGjX5yg==} + + '@devslab/site-kit@0.8.0': + resolution: {integrity: sha512-m2J6/GH7zid3db+BhoN/2GGUg4tlOsDamXBLFjJg+r8JqDgUv5QyocM5tPgqhW6G/jwKIxS0cZo8RcJJAvU7gQ==} + peerDependencies: + '@tanstack/solid-router': 1.170.30 + '@tanstack/solid-start': 1.168.47 + solid-js: 1.9.15 + peerDependenciesMeta: + '@tanstack/solid-router': + optional: true + '@tanstack/solid-start': + optional: true + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -1125,6 +1154,9 @@ packages: resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} engines: {node: '>=18'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -1879,6 +1911,16 @@ packages: engines: {node: '>=10'} hasBin: true + seroval-plugins@1.5.6: + resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.6: + resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==} + engines: {node: '>=10'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1898,6 +1940,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + solid-js@1.9.15: + resolution: {integrity: sha512-EeiY2xfpZJqPLjXspVEKjAII4yv8NyG//NxZ3IpOFHdUNnnTyL0uJOeS9LWGvA7cFCz5y94cjFwYlmw5Luncsg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2914,6 +2959,24 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} + '@devslab/dds-css@0.8.0': {} + + '@devslab/dds-icons@0.8.0': {} + + '@devslab/dds-solid@0.8.0(solid-js@1.9.15)': + dependencies: + '@devslab/dds-css': 0.8.0 + '@devslab/dds-icons': 0.8.0 + '@devslab/dds-tokens': 0.8.0 + solid-js: 1.9.15 + + '@devslab/dds-tokens@0.8.0': {} + + '@devslab/site-kit@0.8.0(solid-js@1.9.15)': + dependencies: + '@devslab/dds-solid': 0.8.0(solid-js@1.9.15) + solid-js: 1.9.15 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -3564,6 +3627,8 @@ snapshots: '@asamuzakjp/css-color': 3.2.0 rrweb-cssom: 0.8.0 + csstype@3.2.3: {} + data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -4649,6 +4714,12 @@ snapshots: semver@7.8.5: {} + seroval-plugins@1.5.6(seroval@1.5.6): + dependencies: + seroval: 1.5.6 + + seroval@1.5.6: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -4661,6 +4732,12 @@ snapshots: slash@3.0.0: {} + solid-js@1.9.15: + dependencies: + csstype: 3.2.3 + seroval: 1.5.6 + seroval-plugins: 1.5.6(seroval@1.5.6) + source-map-js@1.2.1: {} source-map@0.7.6: {} diff --git a/scripts/build-publisher.mjs b/scripts/build-publisher.mjs new file mode 100644 index 0000000..535b55a --- /dev/null +++ b/scripts/build-publisher.mjs @@ -0,0 +1,28 @@ +import { readFile, writeFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import { renderPublisherHtml } from '@devslab/site-kit'; +import { DEVSLAB_PUBLISHER } from '@devslab/site-kit/devslab'; + +// The checked-in HTML remains crawlable without JavaScript or a package registry. +const pages = ["site/index.html"]; +const root = new URL('../', import.meta.url); +const start = ''; +const end = ''; +const template = start + renderPublisherHtml(DEVSLAB_PUBLISHER) + end; +for (const page of pages) { + const target = new URL(page, root); + const source = await readFile(target, 'utf8'); + const rendered = template.replace(/\r?\n/g, source.includes('\r\n') ? '\r\n' : '\n'); + const from = source.indexOf(start); + const through = source.indexOf(end); + if (from < 0 || through < from || source.indexOf(start, from + start.length) !== -1) { + throw new Error('Expected one publisher marker pair in ' + page); + } + const result = source.slice(0, from) + rendered + source.slice(through + end.length); + if (process.argv.includes('--check')) { + if (result !== source) throw new Error('Stale publisher in ' + page + '; run build:publisher'); + } else if (result !== source) { + await writeFile(target, result); + } + console.log('Publisher verified: ' + fileURLToPath(target)); +} diff --git a/site/index.html b/site/index.html index cba9c1e..23e938a 100644 --- a/site/index.html +++ b/site/index.html @@ -575,7 +575,8 @@