Skip to content

Commit 97ff24e

Browse files
MajorTalclaude
andcommitted
fix(ci): green the build — pre-existing biome lint + astro readonly-array errors
These failed CI (Lint + Type Check (Astro) steps) on main independent of the auth/deploy work — surfaced while monitoring CI for the patchDeploy fix: - functions/kychon-api.js: noUselessTernary (input.published === false ? false : true -> input.published !== false; behavior-equivalent). - tests/unit/i18n.test.js: move the noDocumentCookie biome-ignore directive to sit directly above the document.cookie write (it was 3 comment lines off, so the suppression was unused AND the violation unsuppressed). - src/lib/build-events.ts + build-announcements.ts: getAllBuildEvents / getAllBuildAnnouncements returned readonly arrays not assignable to the mutable BlockRenderContext.buildEvents/buildAnnouncements + EventsPageApp props — return a shallow copy so the type matches and the shared cache stays protected. - biome format + organizeImports auto-fixes on 3 test files. Verified: biome check ., astro check (0 errors), tsc --project tsconfig.scripts.json, vitest 1050/1050 — all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 55a3218 commit 97ff24e

7 files changed

Lines changed: 27 additions & 21 deletions

functions/kychon-api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1452,7 +1452,7 @@ async function createPageWithNav(input, _actor) {
14521452
requires_auth: requiresAuth,
14531453
show_in_nav: showInNav,
14541454
nav_position: navPosition,
1455-
published: input.published === false ? false : true,
1455+
published: input.published !== false,
14561456
});
14571457

14581458
const changed = [changedObject('page', page.id ?? slug)];

src/lib/build-announcements.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ export async function ensureBuildAnnouncementsLoaded(): Promise<void> {
109109
* Return the unfiltered build-time announcements cache. Used by
110110
* `.astro` frontmatter to stamp `ctx.buildAnnouncements` once per
111111
* page render; `blocks.ts:ANNOUNCEMENTS_FEED.render` slices it
112-
* (`limit` from the block's config) synchronously.
112+
* (`limit` from the block's config) synchronously. Returns a shallow copy so
113+
* callers (mutable `BlockRenderContext.buildAnnouncements`) can't mutate the
114+
* shared cache.
113115
*/
114-
export function getAllBuildAnnouncements(): readonly Announcement[] | null {
115-
return cache;
116+
export function getAllBuildAnnouncements(): Announcement[] | null {
117+
return cache ? cache.slice() : null;
116118
}
117119

118120
/** Test-only: clear the cache between test runs. */

src/lib/build-events.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,12 @@ export function getBuildEvents(filter: BuildEventsFilter, count: number): Event[
163163
* stamp `ctx.buildEvents` once per page render so each `events_list`
164164
* block can apply its own filter+count synchronously. Prefer
165165
* `getBuildEvents(filter, count)` when you want a single block's
166-
* sliced view — this is the raw cache.
166+
* sliced view. Returns a shallow copy so callers (mutable
167+
* `BlockRenderContext.buildEvents`, `EventsPageApp` props) can't mutate the
168+
* shared cache.
167169
*/
168-
export function getAllBuildEvents(): readonly Event[] | null {
169-
return cache;
170+
export function getAllBuildEvents(): Event[] | null {
171+
return cache ? cache.slice() : null;
170172
}
171173

172174
/** Test-only: clear the cache between test runs. */

tests/unit/capability-api-query-handlers.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,9 @@ describe('Capability API query handlers', () => {
222222

223223
it('gates members.list / members.get on site_config.directory_public for anonymous actors', async () => {
224224
// Without directory_public set, anonymous is denied.
225-
await expect(
226-
runCapabilityQuery('members.list', {}, { actor: anonymousActor, db: sampleDb() }),
227-
).rejects.toThrow(/permission denied for members.list/i);
225+
await expect(runCapabilityQuery('members.list', {}, { actor: anonymousActor, db: sampleDb() })).rejects.toThrow(
226+
/permission denied for members.list/i,
227+
);
228228

229229
// With directory_public=true, anonymous can list — sensitive
230230
// fields (email, custom_fields) stay redacted by memberRow.
@@ -263,7 +263,7 @@ describe('Capability API query handlers', () => {
263263
{},
264264
{ actor: memberActor, db: sampleDb() },
265265
)) as JsonObject;
266-
expect((memberListPrivate.rows as JsonObject[])).toHaveLength(1);
266+
expect(memberListPrivate.rows as JsonObject[]).toHaveLength(1);
267267
});
268268

269269
it('implements events, registration options, RSVPs, announcements, and resources', async () => {

tests/unit/i18n.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ describe('i18n.js', () => {
3333
vi.resetModules();
3434
mockFetch.mockReset();
3535
localStorage._data = {};
36-
// biome-ignore lint/suspicious/noDocumentCookie: this is a mocked document
37-
// for unit tests, not a real browser context — the Cookie Store API isn't
38-
// available here. Production cookie write at src/lib/i18n.ts:setLanguage
39-
// is in biome's ignore list.
36+
// Mocked document for unit tests, not a real browser context — the Cookie
37+
// Store API isn't available here. Production cookie write at
38+
// src/lib/i18n.ts:setLanguage is in biome's ignore list.
39+
// biome-ignore lint/suspicious/noDocumentCookie: mocked document for unit tests
4040
document.cookie = '';
4141

4242
// Default mock: brand.json returns en

tests/unit/kychon-image-blurhash-data-url.test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
* These tests assert that behavior at the `kychonImageHtml` boundary
1616
* (`lqipDataUri` is internal to the module and not exported separately).
1717
*/
18-
import { describe, expect, it } from 'vitest';
18+
1919
import type { AssetRef } from '@run402/astro';
20+
import { describe, expect, it } from 'vitest';
2021
import { kychonImageHtml } from '../../src/lib/kychon-image';
2122

2223
// A well-formed PNG data URL that's deliberately distinct from anything
2324
// the blurhash decoder would actually produce — lets the assertion confirm
2425
// the value came from the AssetRef field, not from a decode.
25-
const SENTINEL_DATA_URL =
26-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAQElEQVRFAEQOPYHa0eTL';
26+
const SENTINEL_DATA_URL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAQElEQVRFAEQOPYHa0eTL';
2727

2828
// A real-shape blurhash string the decoder can process. Used to exercise
2929
// the fallback path; the test asserts on the data-URL prefix, not the
@@ -79,8 +79,7 @@ describe('kychon-image v1.54 blurhash_data_url fast path', () => {
7979
// `blurhash_data_url` is a v1.54 field not yet in @run402/astro@0.2.5's
8080
// AssetRef type; cast locally to attach it. `blurhash` is also set to
8181
// prove the fast path WINS over the fallback when both are available.
82-
(ref as AssetRef & { blurhash_data_url?: string | null }).blurhash_data_url =
83-
SENTINEL_DATA_URL;
82+
(ref as AssetRef & { blurhash_data_url?: string | null }).blurhash_data_url = SENTINEL_DATA_URL;
8483
ref.blurhash = SAMPLE_BLURHASH;
8584

8685
const html = kychonImageHtml(ref, 'hero', { sizes: '100vw' });

tests/unit/main-zone-signature.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ describe('computeMainZoneSignature', () => {
6565
const b = baseSection({ id: 'sec-2', position: 1, section_type: 'promo_cards' });
6666
const sig1 = computeMainZoneSignature({ sections: [a, b], manifestGeneratedAt: null });
6767
const sig2 = computeMainZoneSignature({
68-
sections: [{ ...a, position: 1 }, { ...b, position: 0 }],
68+
sections: [
69+
{ ...a, position: 1 },
70+
{ ...b, position: 0 },
71+
],
6972
manifestGeneratedAt: null,
7073
});
7174
expect(sig1).not.toBe(sig2);

0 commit comments

Comments
 (0)