@fairfox/polly 0.27.3 → 0.27.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/mesh-node.js +4 -2
- package/dist/src/mesh-node.js.map +3 -3
- package/dist/tools/quality/src/check-shared-components.d.ts +88 -0
- package/dist/tools/quality/src/cli.js +133 -16
- package/dist/tools/quality/src/cli.js.map +4 -3
- package/dist/tools/quality/src/index.d.ts +1 -0
- package/dist/tools/quality/src/index.js +136 -17
- package/dist/tools/quality/src/index.js.map +4 -3
- package/package.json +1 -1
package/dist/src/mesh-node.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/mesh-node.ts
|
|
2
|
-
import { readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname } from "node:path";
|
|
3
4
|
import { createInterface } from "node:readline/promises";
|
|
4
5
|
|
|
5
6
|
// src/shared/lib/keyring-storage.ts
|
|
@@ -229,6 +230,7 @@ function fileKeyringStorage(path) {
|
|
|
229
230
|
}
|
|
230
231
|
},
|
|
231
232
|
save: async (keyring) => {
|
|
233
|
+
await mkdir(dirname(path), { recursive: true });
|
|
232
234
|
const text = serialiseKeyring(keyring);
|
|
233
235
|
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
234
236
|
await writeFile(tmp, text, { mode: 384 });
|
|
@@ -301,4 +303,4 @@ export {
|
|
|
301
303
|
bootstrapCliKeyring
|
|
302
304
|
};
|
|
303
305
|
|
|
304
|
-
//# debugId=
|
|
306
|
+
//# debugId=D7A1C6B7D879C69A64756E2164756E21
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/mesh-node.ts", "../../src/shared/lib/keyring-storage.ts", "../../src/shared/lib/encryption.ts", "../../src/shared/lib/signing.ts", "../../src/shared/lib/pairing.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * @fairfox/polly/mesh/node — Node/Bun conveniences for mesh state.\n *\n * The core mesh API (`createMeshClient`, `$meshState`, the keyring storage\n * interface) is runtime-agnostic and ships from `@fairfox/polly/mesh`. This\n * module adds the Node-specific wiring that makes CLIs, cron jobs, and\n * always-on bridges first-class peers on the mesh:\n *\n * - {@link fileKeyringStorage} — durable, human-inspectable keyring store\n * backed by `node:fs`. Atomic writes, missing-file returns `null`.\n * - {@link bootstrapCliKeyring} — wraps {@link fileKeyringStorage} with the\n * first-run pairing UX described in the RFC: generate an identity if\n * no keyring exists, print the public-key fingerprint, read a pairing\n * token from stdin, apply it, and save.\n * - {@link readPairingTokenFromStdin} — low-level prompt helper for\n * consumers that want to compose their own bootstrap.\n *\n * What this module deliberately does **not** do: pick a Node WebRTC\n * implementation. `werift` (pure TypeScript, installs everywhere) and\n * `@roamhq/wrtc` (C++ binding, faster DataChannel, platform-dependent\n * binaries) are both valid choices; the consumer `bun add`s whichever fits\n * their deployment and passes the class into `createMeshClient({ rtc })`.\n *\n * @example\n * ```ts\n * import { createMeshClient } from \"@fairfox/polly/mesh\";\n * import { bootstrapCliKeyring, fileKeyringStorage } from \"@fairfox/polly/mesh/node\";\n * import { RTCPeerConnection } from \"werift\";\n *\n * const storage = fileKeyringStorage(\"./keyring.json\");\n * const keyring = await bootstrapCliKeyring({ storage });\n *\n * const client = await createMeshClient({\n * signaling: { url: \"wss://example.com/polly/signaling\", peerId: \"cli-a1b2\" },\n * rtc: { RTCPeerConnection },\n * keyring,\n * });\n * ```\n */\n\nimport { readFile, rename, writeFile } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline/promises\";\nimport {\n deserialiseKeyring,\n type KeyringStorage,\n serialiseKeyring,\n} from \"./shared/lib/keyring-storage\";\nimport type { MeshKeyring } from \"./shared/lib/mesh-network-adapter\";\nimport { applyPairingToken, decodePairingToken } from \"./shared/lib/pairing\";\nimport { generateSigningKeyPair } from \"./shared/lib/signing\";\n\n// Re-export runtime-agnostic pieces so a Node consumer only needs one\n// import site.\nexport type { KeyringStorage } from \"./shared/lib/keyring-storage\";\nexport {\n deserialiseKeyring,\n memoryKeyringStorage,\n serialiseKeyring,\n} from \"./shared/lib/keyring-storage\";\n\n/**\n * Filesystem-backed keyring storage. Reads and writes the serialised\n * keyring at {@link path} using the canonical JSON+base64 format. The save\n * path uses a write-to-tmp-then-rename dance so concurrent readers never\n * observe a half-written file; a crash mid-write leaves the previous\n * keyring intact.\n */\nexport function fileKeyringStorage(path: string): KeyringStorage {\n return {\n load: async () => {\n try {\n const text = await readFile(path, \"utf-8\");\n return deserialiseKeyring(text);\n } catch (err) {\n if (isFileNotFound(err)) return null;\n throw err;\n }\n },\n save: async (keyring) => {\n const text = serialiseKeyring(keyring);\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, text, { mode: 0o600 });\n await rename(tmp, path);\n },\n };\n}\n\n/** Options for {@link bootstrapCliKeyring}. */\nexport interface BootstrapCliKeyringOptions {\n /** Where to persist the keyring. On subsequent runs this file is loaded\n * and returned without prompting. */\n storage: KeyringStorage;\n /** Stream to print pairing prompts to. Defaults to `process.stderr` so\n * pipelines that consume stdout are not polluted. */\n promptStream?: NodeJS.WritableStream;\n /** Stream to read the pairing token from. Defaults to `process.stdin`. */\n inputStream?: NodeJS.ReadableStream;\n /** Override the clock (for tests). Forwarded to {@link applyPairingToken}. */\n now?: () => number;\n}\n\n/**\n * First-run-or-return flow for Node CLIs.\n *\n * - If the storage has a keyring saved, load and return it.\n * - Otherwise: generate a fresh Ed25519 identity, print the public-key\n * fingerprint to `promptStream`, read one line from `inputStream`\n * (expected to be a base64 pairing token), apply it, save, return.\n *\n * Token *issuance* is deliberately out of scope for this helper — the\n * expected UX is that a trusted device (a browser on the authorising\n * user's laptop) mints the token and the user pastes it into the CLI's\n * stdin. Node processes that need to issue tokens can use\n * {@link createPairingToken} from the main mesh export.\n */\nexport async function bootstrapCliKeyring(\n options: BootstrapCliKeyringOptions\n): Promise<MeshKeyring> {\n const existing = await options.storage.load();\n if (existing !== null) return existing;\n\n const identity = generateSigningKeyPair();\n const keyring: MeshKeyring = {\n identity,\n knownPeers: new Map(),\n documentKeys: new Map(),\n revokedPeers: new Set(),\n };\n\n const promptStream = options.promptStream ?? process.stderr;\n const fingerprint = fingerprintPublicKey(identity.publicKey);\n promptStream.write(\n [\n \"\",\n \"Polly mesh-state CLI bootstrap\",\n \"──────────────────────────────\",\n `Fingerprint: ${fingerprint}`,\n \"\",\n \"Authorise this peer on a trusted device (open the pairing UI, enter\",\n \"the fingerprint above, copy the generated token). Then paste the\",\n \"pairing token below and press enter.\",\n \"\",\n ].join(\"\\n\")\n );\n\n const token = await readPairingTokenFromStdin({\n promptStream,\n inputStream: options.inputStream ?? process.stdin,\n });\n\n const applyOptions = options.now ? { now: options.now } : {};\n applyPairingToken(token, keyring, applyOptions);\n\n await options.storage.save(keyring);\n promptStream.write(`Pairing applied. Keyring saved.\\n`);\n return keyring;\n}\n\n/**\n * Prompt for and read a pairing token from a readable stream (stdin by\n * default). Returns the decoded, validated token. Throws\n * {@link PairingError} on malformed input — callers should surface that\n * message to the user and retry.\n */\nexport async function readPairingTokenFromStdin(\n options: { promptStream?: NodeJS.WritableStream; inputStream?: NodeJS.ReadableStream } = {}\n) {\n const rl = createInterface({\n input: options.inputStream ?? process.stdin,\n output: options.promptStream ?? process.stderr,\n });\n try {\n const line = await rl.question(\"pairing-token> \");\n return decodePairingToken(line.trim());\n } finally {\n rl.close();\n }\n}\n\n/** Short, human-readable fingerprint of a public key. */\nfunction fingerprintPublicKey(publicKey: Uint8Array): string {\n // First 8 bytes, hex-encoded, colon-grouped — familiar from SSH.\n const slice = publicKey.slice(0, 8);\n const hex = Array.from(slice)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return hex.match(/.{2}/g)?.join(\":\") ?? hex;\n}\n\nfunction isFileNotFound(err: unknown): boolean {\n return typeof err === \"object\" && err !== null && \"code\" in err && err.code === \"ENOENT\";\n}\n",
|
|
5
|
+
"/**\n * @fairfox/polly/mesh/node — Node/Bun conveniences for mesh state.\n *\n * The core mesh API (`createMeshClient`, `$meshState`, the keyring storage\n * interface) is runtime-agnostic and ships from `@fairfox/polly/mesh`. This\n * module adds the Node-specific wiring that makes CLIs, cron jobs, and\n * always-on bridges first-class peers on the mesh:\n *\n * - {@link fileKeyringStorage} — durable, human-inspectable keyring store\n * backed by `node:fs`. Atomic writes, missing-file returns `null`.\n * - {@link bootstrapCliKeyring} — wraps {@link fileKeyringStorage} with the\n * first-run pairing UX described in the RFC: generate an identity if\n * no keyring exists, print the public-key fingerprint, read a pairing\n * token from stdin, apply it, and save.\n * - {@link readPairingTokenFromStdin} — low-level prompt helper for\n * consumers that want to compose their own bootstrap.\n *\n * What this module deliberately does **not** do: pick a Node WebRTC\n * implementation. `werift` (pure TypeScript, installs everywhere) and\n * `@roamhq/wrtc` (C++ binding, faster DataChannel, platform-dependent\n * binaries) are both valid choices; the consumer `bun add`s whichever fits\n * their deployment and passes the class into `createMeshClient({ rtc })`.\n *\n * @example\n * ```ts\n * import { createMeshClient } from \"@fairfox/polly/mesh\";\n * import { bootstrapCliKeyring, fileKeyringStorage } from \"@fairfox/polly/mesh/node\";\n * import { RTCPeerConnection } from \"werift\";\n *\n * const storage = fileKeyringStorage(\"./keyring.json\");\n * const keyring = await bootstrapCliKeyring({ storage });\n *\n * const client = await createMeshClient({\n * signaling: { url: \"wss://example.com/polly/signaling\", peerId: \"cli-a1b2\" },\n * rtc: { RTCPeerConnection },\n * keyring,\n * });\n * ```\n */\n\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { createInterface } from \"node:readline/promises\";\nimport {\n deserialiseKeyring,\n type KeyringStorage,\n serialiseKeyring,\n} from \"./shared/lib/keyring-storage\";\nimport type { MeshKeyring } from \"./shared/lib/mesh-network-adapter\";\nimport { applyPairingToken, decodePairingToken } from \"./shared/lib/pairing\";\nimport { generateSigningKeyPair } from \"./shared/lib/signing\";\n\n// Re-export runtime-agnostic pieces so a Node consumer only needs one\n// import site.\nexport type { KeyringStorage } from \"./shared/lib/keyring-storage\";\nexport {\n deserialiseKeyring,\n memoryKeyringStorage,\n serialiseKeyring,\n} from \"./shared/lib/keyring-storage\";\n\n/**\n * Filesystem-backed keyring storage. Reads and writes the serialised\n * keyring at {@link path} using the canonical JSON+base64 format. The save\n * path uses a write-to-tmp-then-rename dance so concurrent readers never\n * observe a half-written file; a crash mid-write leaves the previous\n * keyring intact.\n */\nexport function fileKeyringStorage(path: string): KeyringStorage {\n return {\n load: async () => {\n try {\n const text = await readFile(path, \"utf-8\");\n return deserialiseKeyring(text);\n } catch (err) {\n if (isFileNotFound(err)) return null;\n throw err;\n }\n },\n save: async (keyring) => {\n // First-run on a fresh machine often points this storage at a\n // path whose parent directory hasn't been created yet (the\n // typical `~/.fairfox/keyring.json` shape). mkdir -p the parent\n // up front so the write-to-tmp step doesn't fail at open().\n await mkdir(dirname(path), { recursive: true });\n const text = serialiseKeyring(keyring);\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n await writeFile(tmp, text, { mode: 0o600 });\n await rename(tmp, path);\n },\n };\n}\n\n/** Options for {@link bootstrapCliKeyring}. */\nexport interface BootstrapCliKeyringOptions {\n /** Where to persist the keyring. On subsequent runs this file is loaded\n * and returned without prompting. */\n storage: KeyringStorage;\n /** Stream to print pairing prompts to. Defaults to `process.stderr` so\n * pipelines that consume stdout are not polluted. */\n promptStream?: NodeJS.WritableStream;\n /** Stream to read the pairing token from. Defaults to `process.stdin`. */\n inputStream?: NodeJS.ReadableStream;\n /** Override the clock (for tests). Forwarded to {@link applyPairingToken}. */\n now?: () => number;\n}\n\n/**\n * First-run-or-return flow for Node CLIs.\n *\n * - If the storage has a keyring saved, load and return it.\n * - Otherwise: generate a fresh Ed25519 identity, print the public-key\n * fingerprint to `promptStream`, read one line from `inputStream`\n * (expected to be a base64 pairing token), apply it, save, return.\n *\n * Token *issuance* is deliberately out of scope for this helper — the\n * expected UX is that a trusted device (a browser on the authorising\n * user's laptop) mints the token and the user pastes it into the CLI's\n * stdin. Node processes that need to issue tokens can use\n * {@link createPairingToken} from the main mesh export.\n */\nexport async function bootstrapCliKeyring(\n options: BootstrapCliKeyringOptions\n): Promise<MeshKeyring> {\n const existing = await options.storage.load();\n if (existing !== null) return existing;\n\n const identity = generateSigningKeyPair();\n const keyring: MeshKeyring = {\n identity,\n knownPeers: new Map(),\n documentKeys: new Map(),\n revokedPeers: new Set(),\n };\n\n const promptStream = options.promptStream ?? process.stderr;\n const fingerprint = fingerprintPublicKey(identity.publicKey);\n promptStream.write(\n [\n \"\",\n \"Polly mesh-state CLI bootstrap\",\n \"──────────────────────────────\",\n `Fingerprint: ${fingerprint}`,\n \"\",\n \"Authorise this peer on a trusted device (open the pairing UI, enter\",\n \"the fingerprint above, copy the generated token). Then paste the\",\n \"pairing token below and press enter.\",\n \"\",\n ].join(\"\\n\")\n );\n\n const token = await readPairingTokenFromStdin({\n promptStream,\n inputStream: options.inputStream ?? process.stdin,\n });\n\n const applyOptions = options.now ? { now: options.now } : {};\n applyPairingToken(token, keyring, applyOptions);\n\n await options.storage.save(keyring);\n promptStream.write(`Pairing applied. Keyring saved.\\n`);\n return keyring;\n}\n\n/**\n * Prompt for and read a pairing token from a readable stream (stdin by\n * default). Returns the decoded, validated token. Throws\n * {@link PairingError} on malformed input — callers should surface that\n * message to the user and retry.\n */\nexport async function readPairingTokenFromStdin(\n options: { promptStream?: NodeJS.WritableStream; inputStream?: NodeJS.ReadableStream } = {}\n) {\n const rl = createInterface({\n input: options.inputStream ?? process.stdin,\n output: options.promptStream ?? process.stderr,\n });\n try {\n const line = await rl.question(\"pairing-token> \");\n return decodePairingToken(line.trim());\n } finally {\n rl.close();\n }\n}\n\n/** Short, human-readable fingerprint of a public key. */\nfunction fingerprintPublicKey(publicKey: Uint8Array): string {\n // First 8 bytes, hex-encoded, colon-grouped — familiar from SSH.\n const slice = publicKey.slice(0, 8);\n const hex = Array.from(slice)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return hex.match(/.{2}/g)?.join(\":\") ?? hex;\n}\n\nfunction isFileNotFound(err: unknown): boolean {\n return typeof err === \"object\" && err !== null && \"code\" in err && err.code === \"ENOENT\";\n}\n",
|
|
6
6
|
"/**\n * keyring-storage — persistence abstraction for {@link MeshKeyring}.\n *\n * The keyring itself is a plain structural object of `Map`s, `Set`s, and a\n * signing keypair; it is deliberately not coupled to any persistence layer.\n * This module defines a storage interface that applications implement once\n * for their runtime (IndexedDB, the filesystem, a keychain, a secret\n * manager, whatever) and wire into {@link createMeshClient} via its\n * `keyring.storage` option.\n *\n * A canonical JSON-with-base64 serialisation is provided by\n * {@link serialiseKeyring} and {@link deserialiseKeyring}. It is inspectable\n * by humans, survives manual edits, and round-trips every field of the\n * keyring. Storage implementations that write plain strings (files,\n * localStorage, `kv` stores) can lean on these helpers; storage\n * implementations that persist structured data (IndexedDB, a keychain API)\n * can serialise differently if they prefer.\n */\n\nimport type { MeshKeyring } from \"./mesh-network-adapter\";\nimport type { SigningKeyPair } from \"./signing\";\n\n/**\n * A load/save pair for a single {@link MeshKeyring}. Implementations are\n * free to choose where and how the keyring is stored; the factory only\n * cares that `load()` returns the previously-saved keyring or `null`, and\n * that `save(keyring)` durably persists it.\n */\nexport interface KeyringStorage {\n /** Load the previously-saved keyring, or return `null` if none exists.\n * Implementations may throw for truly exceptional conditions (disk\n * errors, permission failures); a missing keyring is not exceptional. */\n load(): Promise<MeshKeyring | null>;\n /** Durably persist the keyring. Implementations should atomically replace\n * any existing stored value; partial writes must not leave the store in\n * an inconsistent state. */\n save(keyring: MeshKeyring): Promise<void>;\n}\n\n/**\n * In-memory storage. Useful for tests, ephemeral tools, and the first-run\n * bootstrap path where the keyring only lives for the duration of the\n * process. Calling `save` holds the keyring in a closed-over variable;\n * `load` returns it on subsequent calls within the same process.\n */\nexport function memoryKeyringStorage(): KeyringStorage {\n let stored: MeshKeyring | null = null;\n return {\n load: async () => stored,\n save: async (keyring) => {\n stored = keyring;\n },\n };\n}\n\n// ─── Canonical JSON+base64 serialisation ───────────────────────────────────\n\ninterface SerialisedKeyring {\n version: 1;\n identity: { publicKey: string; secretKey: string };\n knownPeers: Record<string, string>;\n documentKeys: Record<string, string>;\n revokedPeers: string[];\n revocationAuthority?: string[];\n}\n\n/**\n * Encode a {@link MeshKeyring} to a canonical JSON string. Every\n * `Uint8Array` field (identity keys, public keys, document keys) is\n * base64-encoded; `Map`s and `Set`s become plain objects and arrays. The\n * output is pretty-printed so a human operator can eyeball or hand-edit\n * the file on disk.\n */\nexport function serialiseKeyring(keyring: MeshKeyring): string {\n const payload: SerialisedKeyring = {\n version: 1,\n identity: {\n publicKey: bytesToBase64(keyring.identity.publicKey),\n secretKey: bytesToBase64(keyring.identity.secretKey),\n },\n knownPeers: mapToBase64Record(keyring.knownPeers),\n documentKeys: mapToBase64Record(keyring.documentKeys),\n revokedPeers: [...keyring.revokedPeers],\n };\n if (keyring.revocationAuthority && keyring.revocationAuthority.size > 0) {\n payload.revocationAuthority = [...keyring.revocationAuthority];\n }\n return JSON.stringify(payload, null, 2);\n}\n\n/**\n * Decode a keyring from the format produced by {@link serialiseKeyring}.\n * Throws with a descriptive message when the input is malformed, so\n * corrupt storage surfaces as an actionable error rather than a silent\n * downgrade.\n */\nexport function deserialiseKeyring(text: string): MeshKeyring {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (err) {\n throw new Error(`KeyringStorage: keyring payload is not valid JSON: ${(err as Error).message}`);\n }\n if (!raw || typeof raw !== \"object\") {\n throw new Error(\"KeyringStorage: keyring payload is not an object\");\n }\n const r = raw as Partial<SerialisedKeyring>;\n if (r.version !== 1) {\n throw new Error(`KeyringStorage: unsupported keyring version: ${String(r.version)}`);\n }\n if (!r.identity || typeof r.identity !== \"object\") {\n throw new Error(\"KeyringStorage: keyring payload is missing identity\");\n }\n const identity: SigningKeyPair = {\n publicKey: base64ToBytes(r.identity.publicKey),\n secretKey: base64ToBytes(r.identity.secretKey),\n };\n const keyring: MeshKeyring = {\n identity,\n knownPeers: base64RecordToMap(r.knownPeers ?? {}),\n documentKeys: base64RecordToMap(r.documentKeys ?? {}),\n revokedPeers: new Set(r.revokedPeers ?? []),\n };\n if (r.revocationAuthority && r.revocationAuthority.length > 0) {\n keyring.revocationAuthority = new Set(r.revocationAuthority);\n }\n return keyring;\n}\n\nfunction mapToBase64Record(map: Map<string, Uint8Array>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of map) {\n out[key] = bytesToBase64(value);\n }\n return out;\n}\n\nfunction base64RecordToMap(record: Record<string, string>): Map<string, Uint8Array> {\n const out = new Map<string, Uint8Array>();\n for (const [key, value] of Object.entries(record)) {\n out.set(key, base64ToBytes(value));\n }\n return out;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n // btoa is available in browsers, Node 16+, and Bun.\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n",
|
|
7
7
|
"/**\n * encryption — symmetric authenticated encryption for Polly's $meshState\n * primitive (Phase 2). Wraps tweetnacl's secretbox (XSalsa20-Poly1305) with\n * a small Polly-flavoured API so the rest of the codebase never imports\n * tweetnacl directly.\n *\n * Every $meshState document has a per-document symmetric key that is\n * provisioned to authorised peers at pairing time and never held by any\n * server. Outgoing operations are encrypted under this key before they\n * touch the network adapter; incoming operations are decrypted on receipt.\n * The signing layer in {@link signing.ts} provides authenticity (proof of\n * who sent the message); this layer provides confidentiality (the bytes\n * are unreadable to anything that does not hold the document key).\n *\n * tweetnacl's secretbox uses a 32-byte symmetric key and a 24-byte nonce.\n * The output of `nacl.secretbox` is the ciphertext concatenated with a\n * 16-byte Poly1305 authentication tag. We package the nonce + ciphertext\n * into a single binary blob using a small length-prefixed envelope so the\n * receiver can recover the nonce without out-of-band coordination.\n *\n * - {@link generateDocumentKey} returns a fresh 32-byte symmetric key.\n *\n * - {@link encrypt} produces a sealed blob from a payload and a key.\n *\n * - {@link decrypt} recovers the payload from a sealed blob and a key.\n * Returns undefined if the blob is malformed or the authentication\n * tag does not match (i.e. wrong key or tampered ciphertext) — the\n * undefined signal lets call sites distinguish \"wrong key\" from\n * \"structurally invalid\" without throwing.\n *\n * - {@link sealEnvelope} and {@link openEnvelope} are convenience helpers\n * that wrap encrypt/decrypt in a structured EncryptedEnvelope shape so\n * the mesh transport layer can handle the binary plumbing uniformly.\n */\n\nimport nacl from \"tweetnacl\";\n\n/** Length in bytes of a secretbox symmetric key. */\nexport const KEY_BYTES = 32;\n/** Length in bytes of a secretbox nonce. */\nexport const NONCE_BYTES = 24;\n/** Length in bytes of the Poly1305 authentication tag. */\nexport const TAG_BYTES = 16;\n\n/**\n * A sealed blob suitable for storage or network transmission. The wire\n * layout is the concatenation of the nonce and the ciphertext+tag from\n * tweetnacl. Callers should not depend on the exact bytes — round-trip\n * through {@link encrypt} / {@link decrypt} or the envelope helpers.\n */\nexport type SealedBytes = Uint8Array;\n\n/** Errors thrown by the encryption subsystem. */\nexport class EncryptionError extends Error {\n readonly code: \"invalid-key-length\" | \"decrypt-failed\" | \"envelope-malformed\";\n constructor(message: string, code: EncryptionError[\"code\"]) {\n super(message);\n this.name = \"EncryptionError\";\n this.code = code;\n }\n}\n\n/**\n * Generate a fresh 32-byte symmetric document key. Calls into tweetnacl's\n * CSPRNG.\n */\nexport function generateDocumentKey(): Uint8Array {\n return nacl.randomBytes(KEY_BYTES);\n}\n\n/**\n * Encrypt a payload under a symmetric key. The returned blob includes a\n * fresh nonce so the receiver does not need any out-of-band coordination\n * to decrypt.\n */\nexport function encrypt(payload: Uint8Array, key: Uint8Array): SealedBytes {\n if (key.length !== KEY_BYTES) {\n throw new EncryptionError(\n `secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`,\n \"invalid-key-length\"\n );\n }\n const nonce = nacl.randomBytes(NONCE_BYTES);\n const ciphertext = nacl.secretbox(payload, nonce, key);\n const out = new Uint8Array(NONCE_BYTES + ciphertext.length);\n out.set(nonce, 0);\n out.set(ciphertext, NONCE_BYTES);\n return out;\n}\n\n/**\n * Decrypt a sealed blob under a symmetric key. Returns the original\n * payload on success. Returns undefined if the blob is too short to\n * contain a nonce and tag, or if the authentication tag does not match\n * (which indicates either a wrong key or a tampered ciphertext).\n *\n * The undefined return is deliberate: call sites typically want to fall\n * back to a different key or surface a \"could not decrypt\" message rather\n * than catching an exception. Use {@link decryptOrThrow} when an exception\n * is preferred.\n */\nexport function decrypt(sealed: SealedBytes, key: Uint8Array): Uint8Array | undefined {\n if (key.length !== KEY_BYTES) {\n throw new EncryptionError(\n `secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`,\n \"invalid-key-length\"\n );\n }\n if (sealed.length < NONCE_BYTES + TAG_BYTES) {\n return undefined;\n }\n const nonce = sealed.subarray(0, NONCE_BYTES);\n const ciphertext = sealed.subarray(NONCE_BYTES);\n const opened = nacl.secretbox.open(ciphertext, nonce, key);\n return opened ?? undefined;\n}\n\n/**\n * Decrypt a sealed blob, throwing {@link EncryptionError} on failure\n * instead of returning undefined.\n */\nexport function decryptOrThrow(sealed: SealedBytes, key: Uint8Array): Uint8Array {\n const opened = decrypt(sealed, key);\n if (!opened) {\n throw new EncryptionError(\n `Failed to decrypt sealed blob: wrong key, malformed input, or tampered ciphertext.`,\n \"decrypt-failed\"\n );\n }\n return opened;\n}\n\n/**\n * A high-level structured envelope combining encryption with a small\n * amount of metadata the receiver needs to find the right key. The mesh\n * network adapter uses this shape on the wire.\n */\nexport interface EncryptedEnvelope {\n /** Stable identifier for the document this payload belongs to. The\n * receiver looks this up in its local key store to find the right key. */\n documentId: string;\n /** Sealed blob containing the encrypted payload plus its nonce. */\n sealed: SealedBytes;\n}\n\n/**\n * Encrypt a payload and pack it into an {@link EncryptedEnvelope} along\n * with the document id.\n */\nexport function sealEnvelope(\n payload: Uint8Array,\n documentId: string,\n key: Uint8Array\n): EncryptedEnvelope {\n return {\n documentId,\n sealed: encrypt(payload, key),\n };\n}\n\n/**\n * Decrypt an {@link EncryptedEnvelope} using the given key. Throws on\n * failure for symmetry with {@link sealEnvelope}.\n */\nexport function openEnvelope(envelope: EncryptedEnvelope, key: Uint8Array): Uint8Array {\n return decryptOrThrow(envelope.sealed, key);\n}\n\n/**\n * Serialise an {@link EncryptedEnvelope} to a single binary blob.\n *\n * Wire format:\n *\n * [4 bytes BE: documentId byte length]\n * [N bytes: documentId UTF-8]\n * [remaining: sealed blob (nonce + ciphertext + tag)]\n */\nexport function encodeEncryptedEnvelope(envelope: EncryptedEnvelope): Uint8Array {\n const idBytes = new TextEncoder().encode(envelope.documentId);\n const out = new Uint8Array(4 + idBytes.length + envelope.sealed.length);\n const view = new DataView(out.buffer);\n view.setUint32(0, idBytes.length, false);\n out.set(idBytes, 4);\n out.set(envelope.sealed, 4 + idBytes.length);\n return out;\n}\n\n/**\n * Deserialise a binary envelope produced by {@link encodeEncryptedEnvelope}.\n * Throws on malformed input.\n */\nexport function decodeEncryptedEnvelope(bytes: Uint8Array): EncryptedEnvelope {\n if (bytes.length < 4) {\n throw new EncryptionError(\n `Encrypted envelope too short: ${bytes.length} bytes.`,\n \"envelope-malformed\"\n );\n }\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const idLen = view.getUint32(0, false);\n if (bytes.length < 4 + idLen) {\n throw new EncryptionError(\n `Encrypted envelope truncated: declared id length ${idLen}, total ${bytes.length}.`,\n \"envelope-malformed\"\n );\n }\n const documentId = new TextDecoder().decode(bytes.subarray(4, 4 + idLen));\n const sealed = bytes.slice(4 + idLen);\n return { documentId, sealed };\n}\n",
|
|
8
8
|
"/**\n * signing — Ed25519 signing and verification for Polly's $meshState\n * primitive (Phase 2). Wraps tweetnacl with a small Polly-flavoured API\n * so the rest of the codebase never imports tweetnacl directly.\n *\n * Every operation that flows through a $meshState transport is signed by\n * the originating peer's private key before transmission and verified by\n * every receiving peer against a known public-key set before being applied.\n * This is the Byzantine-tolerance mechanism: a peer whose private key is\n * compromised can be revoked through a further signed operation, after\n * which honest peers reject anything signed by the revoked key.\n *\n * tweetnacl uses the Ed25519 curve. Public keys and signatures are 32 and\n * 64 bytes respectively, which keeps the per-op overhead small enough that\n * signing every Automerge sync message is feasible even on mobile.\n *\n * The shape of the wrapper:\n *\n * - {@link generateSigningKeyPair} produces a new Ed25519 keypair. The\n * private key never leaves the device that generated it; the public\n * key is gossiped through the access set.\n *\n * - {@link sign} produces a 64-byte detached signature over a payload.\n *\n * - {@link verify} checks a payload against a signature and a public\n * key. Returns boolean rather than throwing so call sites can handle\n * verification failure as a normal control-flow case.\n *\n * - {@link signEnvelope} and {@link openEnvelope} package payload + sender\n * id + signature into a single binary envelope, which is what the mesh\n * network adapter actually puts on the wire.\n */\n\nimport nacl from \"tweetnacl\";\n\n/** Length in bytes of an Ed25519 public key. */\nexport const PUBLIC_KEY_BYTES = 32;\n/** Length in bytes of an Ed25519 secret (private) key. */\nexport const SECRET_KEY_BYTES = 64;\n/** Length in bytes of an Ed25519 detached signature. */\nexport const SIGNATURE_BYTES = 64;\n\n/**\n * An Ed25519 keypair. The {@link publicKey} is safe to share with peers;\n * the {@link secretKey} must never leave the device.\n */\nexport interface SigningKeyPair {\n publicKey: Uint8Array;\n secretKey: Uint8Array;\n}\n\n/**\n * A signed envelope. The wire format is the concatenation of the sender id\n * length, the sender id bytes, the signature, and the payload. Callers\n * shouldn't rely on the exact layout — use {@link signEnvelope} and\n * {@link openEnvelope} to round-trip.\n */\nexport interface SignedEnvelope {\n /** Stable sender peer identifier (UTF-8 string). The receiving side uses\n * this to look up the sender's public key in the document's access set. */\n senderId: string;\n /** The original payload bytes, untouched. */\n payload: Uint8Array;\n /** 64-byte Ed25519 signature over the payload. */\n signature: Uint8Array;\n}\n\n/** Errors thrown by the signing subsystem. */\nexport class SigningError extends Error {\n readonly code:\n | \"invalid-secret-key\"\n | \"invalid-public-key\"\n | \"invalid-signature-length\"\n | \"envelope-malformed\";\n\n constructor(message: string, code: SigningError[\"code\"]) {\n super(message);\n this.name = \"SigningError\";\n this.code = code;\n }\n}\n\n/**\n * Generate a fresh Ed25519 keypair. Calls into tweetnacl's CSPRNG.\n */\nexport function generateSigningKeyPair(): SigningKeyPair {\n const pair = nacl.sign.keyPair();\n return {\n publicKey: pair.publicKey,\n secretKey: pair.secretKey,\n };\n}\n\n/**\n * Reconstruct a keypair from an existing 64-byte secret key. Useful for\n * loading keys from persistent storage. Throws if the key is the wrong size.\n */\nexport function signingKeyPairFromSecret(secretKey: Uint8Array): SigningKeyPair {\n if (secretKey.length !== SECRET_KEY_BYTES) {\n throw new SigningError(\n `Ed25519 secret key must be ${SECRET_KEY_BYTES} bytes, got ${secretKey.length}.`,\n \"invalid-secret-key\"\n );\n }\n const pair = nacl.sign.keyPair.fromSecretKey(secretKey);\n return {\n publicKey: pair.publicKey,\n secretKey: pair.secretKey,\n };\n}\n\n/**\n * Produce a 64-byte detached signature over the given payload using the\n * supplied secret key.\n */\nexport function sign(payload: Uint8Array, secretKey: Uint8Array): Uint8Array {\n if (secretKey.length !== SECRET_KEY_BYTES) {\n throw new SigningError(\n `Ed25519 secret key must be ${SECRET_KEY_BYTES} bytes, got ${secretKey.length}.`,\n \"invalid-secret-key\"\n );\n }\n return nacl.sign.detached(payload, secretKey);\n}\n\n/**\n * Verify a detached signature against a payload and a public key. Returns\n * true if the signature is valid, false otherwise. Wrong-length keys or\n * signatures throw {@link SigningError} so callers can distinguish a bad\n * signature from a misshapen input.\n */\nexport function verify(payload: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {\n if (publicKey.length !== PUBLIC_KEY_BYTES) {\n throw new SigningError(\n `Ed25519 public key must be ${PUBLIC_KEY_BYTES} bytes, got ${publicKey.length}.`,\n \"invalid-public-key\"\n );\n }\n if (signature.length !== SIGNATURE_BYTES) {\n throw new SigningError(\n `Ed25519 signature must be ${SIGNATURE_BYTES} bytes, got ${signature.length}.`,\n \"invalid-signature-length\"\n );\n }\n return nacl.sign.detached.verify(payload, signature, publicKey);\n}\n\n/**\n * Sign a payload and pack it into a {@link SignedEnvelope} along with the\n * sender id. The mesh network adapter calls this on every outgoing message\n * before handing it to the transport.\n */\nexport function signEnvelope(\n payload: Uint8Array,\n senderId: string,\n secretKey: Uint8Array\n): SignedEnvelope {\n const signature = sign(payload, secretKey);\n return { senderId, payload, signature };\n}\n\n/**\n * Verify a {@link SignedEnvelope} against the sender's known public key.\n * Returns the inner payload on success, throws on failure. The mesh\n * network adapter calls this on every incoming message before forwarding\n * the payload to the underlying Automerge sync subsystem.\n */\nexport function openEnvelope(envelope: SignedEnvelope, publicKey: Uint8Array): Uint8Array {\n const ok = verify(envelope.payload, envelope.signature, publicKey);\n if (!ok) {\n throw new SigningError(\n `Signature verification failed for envelope from ${envelope.senderId}.`,\n \"envelope-malformed\"\n );\n }\n return envelope.payload;\n}\n\n/**\n * Serialise a {@link SignedEnvelope} to a single binary blob suitable for\n * transmission over a network adapter. Wire format:\n *\n * [4 bytes BE: senderId byte length]\n * [N bytes: senderId UTF-8]\n * [64 bytes: signature]\n * [remaining: payload]\n *\n * Callers should not depend on the exact bytes — they should round-trip\n * through {@link encodeSignedEnvelope} / {@link decodeSignedEnvelope}.\n */\nexport function encodeSignedEnvelope(envelope: SignedEnvelope): Uint8Array {\n const senderBytes = new TextEncoder().encode(envelope.senderId);\n const total = 4 + senderBytes.length + SIGNATURE_BYTES + envelope.payload.length;\n const out = new Uint8Array(total);\n const view = new DataView(out.buffer);\n view.setUint32(0, senderBytes.length, false);\n out.set(senderBytes, 4);\n out.set(envelope.signature, 4 + senderBytes.length);\n out.set(envelope.payload, 4 + senderBytes.length + SIGNATURE_BYTES);\n return out;\n}\n\n/**\n * Deserialise a binary envelope produced by {@link encodeSignedEnvelope}.\n * Throws on malformed input.\n */\nexport function decodeSignedEnvelope(bytes: Uint8Array): SignedEnvelope {\n if (bytes.length < 4 + SIGNATURE_BYTES) {\n throw new SigningError(\n `Envelope too short: ${bytes.length} bytes, need at least ${4 + SIGNATURE_BYTES}.`,\n \"envelope-malformed\"\n );\n }\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const senderLen = view.getUint32(0, false);\n if (bytes.length < 4 + senderLen + SIGNATURE_BYTES) {\n throw new SigningError(\n `Envelope truncated: declared sender length ${senderLen}, total ${bytes.length}.`,\n \"envelope-malformed\"\n );\n }\n const senderId = new TextDecoder().decode(bytes.subarray(4, 4 + senderLen));\n const signature = bytes.slice(4 + senderLen, 4 + senderLen + SIGNATURE_BYTES);\n const payload = bytes.slice(4 + senderLen + SIGNATURE_BYTES);\n return { senderId, payload, signature };\n}\n",
|
|
9
9
|
"/**\n * pairing — Phase 2 first-cut pairing flow for $meshState.\n *\n * Two devices that want to share a $meshState document must exchange three\n * things before sync can begin: the issuer's Ed25519 signing public key\n * (so the receiver can verify ops authored by the issuer), the symmetric\n * document encryption key (so both sides can encrypt and decrypt the\n * shared document), and the issuer's stable peer id (so the receiver\n * knows which entry in its keyring the public key belongs to). This\n * module packs all three into a {@link PairingToken}, serialises it to a\n * compact binary format suitable for QR codes or copy-paste, and provides\n * the matching parse-and-apply flow on the receiving side.\n *\n * Threat model: pairing tokens are transmitted over an out-of-band channel\n * that the user can authenticate visually — typically a QR code on the\n * issuer's device, scanned by the receiver. Because anyone with the token\n * can decrypt and impersonate, the OOB channel is the only authentication.\n * The token includes a TTL (default 10 minutes) so that a token displayed\n * briefly and then dismissed cannot be replayed by an attacker who later\n * gains access to a screenshot. A production deployment would layer a\n * Short Authentication String (SAS) on top — both devices display a code\n * derived from the shared state, and the user verifies they match — but\n * that is a follow-up.\n *\n * The pairing flow is one-way in the Phase 2 first cut. The issuer\n * generates a token and displays it; the receiver applies it and picks\n * up the issuer's keys. The receiver's own keys reach the issuer through\n * the access set: when the receiver sends its first signed op, the issuer\n * records the receiver's public key alongside its peer id and adds it to\n * the keyring. A bidirectional pairing flow that exchanges both sides'\n * keys in a single QR exchange is straightforward to add later but adds\n * UX surface area that is not needed for the mesh transport to work.\n */\n\nimport { KEY_BYTES as ENCRYPTION_KEY_BYTES, generateDocumentKey } from \"./encryption\";\nimport type { MeshKeyring } from \"./mesh-network-adapter\";\nimport {\n generateSigningKeyPair,\n PUBLIC_KEY_BYTES as SIGNING_PUBLIC_KEY_BYTES,\n type SigningKeyPair,\n} from \"./signing\";\n\n/** Current pairing-token format version. Bumped if the wire format changes. */\nexport const PAIRING_TOKEN_VERSION = 1;\n\n/** Magic header bytes for sanity-checking parsed tokens. ASCII \"PPT1\". */\nexport const PAIRING_TOKEN_MAGIC = new Uint8Array([0x50, 0x50, 0x54, 0x31]);\n\n/** Length of the random nonce embedded in every token. */\nexport const PAIRING_NONCE_BYTES = 16;\n\n/** Default TTL applied when {@link createPairingToken} is called without an\n * explicit `ttlMs` option. */\nexport const DEFAULT_PAIRING_TTL_MS = 10 * 60 * 1000; // 10 minutes\n\n/**\n * The contents of a pairing token. Both sides operate on this shape; the\n * binary serialisation is purely for transport.\n */\nexport interface PairingToken {\n /** Format version. {@link PAIRING_TOKEN_VERSION} at the time of writing. */\n version: number;\n /** Stable peer id of the issuing device. The receiver records this as\n * the lookup key for the issuer's public key in its keyring. */\n issuerPeerId: string;\n /** Issuer's Ed25519 signing public key (32 bytes). */\n issuerPublicKey: Uint8Array;\n /** Shared document encryption key (32 bytes). The receiver stores this\n * under {@link documentKeyId} in its keyring. */\n documentKey: Uint8Array;\n /** Identifier under which the receiver stores the document key. For the\n * Phase 2 first cut this is typically the well-known DEFAULT_MESH_KEY_ID\n * from mesh-network-adapter; per-document keys (one entry per Automerge\n * document) are a follow-up. */\n documentKeyId: string;\n /** Unix timestamp (milliseconds) after which the token is considered\n * expired and {@link applyPairingToken} refuses to use it. */\n expiresAt: number;\n /** 16-byte random nonce. Carried through serialisation so two tokens\n * with otherwise-identical contents are still distinguishable. */\n nonce: Uint8Array;\n}\n\n/** Errors thrown by the pairing subsystem. */\nexport class PairingError extends Error {\n readonly code:\n | \"expired\"\n | \"wrong-magic\"\n | \"unknown-version\"\n | \"truncated\"\n | \"invalid-public-key\"\n | \"invalid-document-key\"\n | \"invalid-nonce\";\n\n constructor(message: string, code: PairingError[\"code\"]) {\n super(message);\n this.name = \"PairingError\";\n this.code = code;\n }\n}\n\n/**\n * Options for {@link createPairingToken}. The signing identity and the\n * document key are required; everything else is optional with sensible\n * defaults.\n */\nexport interface CreatePairingTokenOptions {\n /** The issuing device's signing keypair. Only the public key ends up in\n * the token; the secret never leaves the issuer. */\n identity: SigningKeyPair;\n /** Stable peer id for the issuing device. */\n issuerPeerId: string;\n /** The symmetric document key the receiver should adopt. If omitted, a\n * fresh key is generated and the caller is responsible for using the\n * same key on the issuing side too. */\n documentKey?: Uint8Array;\n /** Identifier under which the receiver stores the document key. */\n documentKeyId: string;\n /** Time-to-live in milliseconds. Defaults to {@link DEFAULT_PAIRING_TTL_MS}. */\n ttlMs?: number;\n /** Override the current time. Intended for tests; production code should\n * not pass this. */\n now?: () => number;\n}\n\n/**\n * Generate a fresh {@link PairingToken}. The token is ready to be\n * serialised and displayed to the receiver via an OOB channel.\n */\nexport function createPairingToken(options: CreatePairingTokenOptions): PairingToken {\n const now = options.now ? options.now() : Date.now();\n const ttlMs = options.ttlMs ?? DEFAULT_PAIRING_TTL_MS;\n const documentKey = options.documentKey ?? generateDocumentKey();\n const nonce = randomBytes(PAIRING_NONCE_BYTES);\n\n return {\n version: PAIRING_TOKEN_VERSION,\n issuerPeerId: options.issuerPeerId,\n issuerPublicKey: options.identity.publicKey,\n documentKey,\n documentKeyId: options.documentKeyId,\n expiresAt: now + ttlMs,\n nonce,\n };\n}\n\n/**\n * Generate a fresh pairing token *and* a fresh signing keypair in one call.\n * Convenience for first-time setup where the device has no existing\n * identity yet. Returns both so the caller can persist the keypair and\n * then display the token.\n */\nexport function createPairingTokenWithFreshIdentity(args: {\n issuerPeerId: string;\n documentKeyId: string;\n ttlMs?: number;\n now?: () => number;\n}): { identity: SigningKeyPair; token: PairingToken } {\n const identity = generateSigningKeyPair();\n const token = createPairingToken({\n identity,\n issuerPeerId: args.issuerPeerId,\n documentKeyId: args.documentKeyId,\n ttlMs: args.ttlMs,\n now: args.now,\n });\n return { identity, token };\n}\n\n/**\n * Check whether a token has expired against the current wall-clock time\n * (or an injected `now`).\n */\nexport function isPairingTokenExpired(token: PairingToken, now?: () => number): boolean {\n const t = now ? now() : Date.now();\n return t >= token.expiresAt;\n}\n\n/**\n * Apply a parsed and validated token to a {@link MeshKeyring}. Mutates the\n * keyring in place: adds the issuer's public key to {@link MeshKeyring.knownPeers}\n * and the document key to {@link MeshKeyring.documentKeys}.\n *\n * Throws {@link PairingError} with code \"expired\" if the token's TTL has\n * elapsed. The receiver is expected to apply the token promptly after\n * scanning; rejecting expired tokens prevents replay of long-lived\n * captures.\n */\nexport function applyPairingToken(\n token: PairingToken,\n keyring: MeshKeyring,\n options: { now?: () => number } = {}\n): void {\n if (isPairingTokenExpired(token, options.now)) {\n throw new PairingError(\n `Pairing token from ${token.issuerPeerId} expired at ${new Date(token.expiresAt).toISOString()}.`,\n \"expired\"\n );\n }\n keyring.knownPeers.set(token.issuerPeerId, token.issuerPublicKey);\n keyring.documentKeys.set(token.documentKeyId, token.documentKey);\n}\n\n// ─── binary serialisation ──────────────────────────────────────────────────\n\n/**\n * Serialise a token to a binary blob. The wire format is:\n *\n * [4 bytes: magic \"PPT1\"]\n * [1 byte: version]\n * [4 bytes BE: issuer id byte length]\n * [N bytes: issuer id UTF-8]\n * [32 bytes: issuer public key]\n * [32 bytes: document key]\n * [4 bytes BE: document key id byte length]\n * [M bytes: document key id UTF-8]\n * [8 bytes BE: expiresAt (uint64 milliseconds)]\n * [16 bytes: nonce]\n *\n * Use {@link encodePairingToken} to round-trip through a base64 string.\n */\nexport function serialisePairingToken(token: PairingToken): Uint8Array {\n validateForSerialisation(token);\n const issuerBytes = new TextEncoder().encode(token.issuerPeerId);\n const keyIdBytes = new TextEncoder().encode(token.documentKeyId);\n\n const total =\n PAIRING_TOKEN_MAGIC.length +\n 1 + // version\n 4 + // issuer id length\n issuerBytes.length +\n SIGNING_PUBLIC_KEY_BYTES +\n ENCRYPTION_KEY_BYTES +\n 4 + // doc key id length\n keyIdBytes.length +\n 8 + // expiresAt\n PAIRING_NONCE_BYTES;\n\n const out = new Uint8Array(total);\n let offset = 0;\n\n out.set(PAIRING_TOKEN_MAGIC, offset);\n offset += PAIRING_TOKEN_MAGIC.length;\n\n out[offset] = token.version;\n offset += 1;\n\n const view = new DataView(out.buffer);\n view.setUint32(offset, issuerBytes.length, false);\n offset += 4;\n out.set(issuerBytes, offset);\n offset += issuerBytes.length;\n\n out.set(token.issuerPublicKey, offset);\n offset += SIGNING_PUBLIC_KEY_BYTES;\n\n out.set(token.documentKey, offset);\n offset += ENCRYPTION_KEY_BYTES;\n\n view.setUint32(offset, keyIdBytes.length, false);\n offset += 4;\n out.set(keyIdBytes, offset);\n offset += keyIdBytes.length;\n\n // Write expiresAt as uint64 BE. JavaScript numbers are float64 but the\n // value is an integer count of milliseconds, well within 53-bit safe\n // range for any practical timestamp.\n view.setBigUint64(offset, BigInt(token.expiresAt), false);\n offset += 8;\n\n out.set(token.nonce, offset);\n offset += PAIRING_NONCE_BYTES;\n\n return out;\n}\n\n/**\n * Inverse of {@link serialisePairingToken}. Throws {@link PairingError} on\n * malformed input.\n */\nexport function parsePairingToken(bytes: Uint8Array): PairingToken {\n let offset = 0;\n\n // Magic\n if (bytes.length < PAIRING_TOKEN_MAGIC.length) {\n throw new PairingError(`Pairing token too short: ${bytes.length} bytes.`, \"truncated\");\n }\n for (let i = 0; i < PAIRING_TOKEN_MAGIC.length; i++) {\n if (bytes[offset + i] !== PAIRING_TOKEN_MAGIC[i]) {\n throw new PairingError(\n `Pairing token magic mismatch: not a Polly pairing token.`,\n \"wrong-magic\"\n );\n }\n }\n offset += PAIRING_TOKEN_MAGIC.length;\n\n // Version\n if (bytes.length < offset + 1) {\n throw new PairingError(\"Pairing token truncated at version.\", \"truncated\");\n }\n const version = bytes[offset] as unknown as number;\n offset += 1;\n if (version !== PAIRING_TOKEN_VERSION) {\n throw new PairingError(\n `Unknown pairing token version: ${version}. This Polly build supports version ${PAIRING_TOKEN_VERSION}.`,\n \"unknown-version\"\n );\n }\n\n // Issuer id\n if (bytes.length < offset + 4) {\n throw new PairingError(\"Pairing token truncated at issuer id length.\", \"truncated\");\n }\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const issuerLen = view.getUint32(offset, false);\n offset += 4;\n if (bytes.length < offset + issuerLen) {\n throw new PairingError(\"Pairing token truncated at issuer id.\", \"truncated\");\n }\n const issuerPeerId = new TextDecoder().decode(bytes.subarray(offset, offset + issuerLen));\n offset += issuerLen;\n\n // Issuer public key\n if (bytes.length < offset + SIGNING_PUBLIC_KEY_BYTES) {\n throw new PairingError(\"Pairing token truncated at public key.\", \"truncated\");\n }\n const issuerPublicKey = bytes.slice(offset, offset + SIGNING_PUBLIC_KEY_BYTES);\n offset += SIGNING_PUBLIC_KEY_BYTES;\n\n // Document key\n if (bytes.length < offset + ENCRYPTION_KEY_BYTES) {\n throw new PairingError(\"Pairing token truncated at document key.\", \"truncated\");\n }\n const documentKey = bytes.slice(offset, offset + ENCRYPTION_KEY_BYTES);\n offset += ENCRYPTION_KEY_BYTES;\n\n // Document key id\n if (bytes.length < offset + 4) {\n throw new PairingError(\"Pairing token truncated at document key id length.\", \"truncated\");\n }\n const keyIdLen = view.getUint32(offset, false);\n offset += 4;\n if (bytes.length < offset + keyIdLen) {\n throw new PairingError(\"Pairing token truncated at document key id.\", \"truncated\");\n }\n const documentKeyId = new TextDecoder().decode(bytes.subarray(offset, offset + keyIdLen));\n offset += keyIdLen;\n\n // Expires at\n if (bytes.length < offset + 8) {\n throw new PairingError(\"Pairing token truncated at expiry.\", \"truncated\");\n }\n const expiresAtBig = view.getBigUint64(offset, false);\n offset += 8;\n const expiresAt = Number(expiresAtBig);\n\n // Nonce\n if (bytes.length < offset + PAIRING_NONCE_BYTES) {\n throw new PairingError(\"Pairing token truncated at nonce.\", \"truncated\");\n }\n const nonce = bytes.slice(offset, offset + PAIRING_NONCE_BYTES);\n offset += PAIRING_NONCE_BYTES;\n\n return {\n version,\n issuerPeerId,\n issuerPublicKey,\n documentKey,\n documentKeyId,\n expiresAt,\n nonce,\n };\n}\n\n/**\n * Serialise a token and base64-encode it for QR-code or copy-paste display.\n * The encoding uses the standard base64 alphabet (not URL-safe) because\n * QR codes encode bytes directly and do not care about URL safety.\n */\nexport function encodePairingToken(token: PairingToken): string {\n const bytes = serialisePairingToken(token);\n // btoa expects a binary string. Convert via String.fromCharCode per byte;\n // safe for the ~150-byte token size and avoids the spread-into-fromCharCode\n // pattern that runs into argument-count limits on large arrays.\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\n/**\n * Decode a base64-encoded pairing token produced by {@link encodePairingToken}.\n * Throws {@link PairingError} on malformed input.\n */\nexport function decodePairingToken(encoded: string): PairingToken {\n let binary: string;\n try {\n binary = atob(encoded);\n } catch {\n throw new PairingError(\"Pairing token is not valid base64.\", \"wrong-magic\");\n }\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return parsePairingToken(bytes);\n}\n\n// ─── helpers ───────────────────────────────────────────────────────────────\n\nfunction validateForSerialisation(token: PairingToken): void {\n if (token.issuerPublicKey.length !== SIGNING_PUBLIC_KEY_BYTES) {\n throw new PairingError(\n `Issuer public key must be ${SIGNING_PUBLIC_KEY_BYTES} bytes, got ${token.issuerPublicKey.length}.`,\n \"invalid-public-key\"\n );\n }\n if (token.documentKey.length !== ENCRYPTION_KEY_BYTES) {\n throw new PairingError(\n `Document key must be ${ENCRYPTION_KEY_BYTES} bytes, got ${token.documentKey.length}.`,\n \"invalid-document-key\"\n );\n }\n if (token.nonce.length !== PAIRING_NONCE_BYTES) {\n throw new PairingError(\n `Nonce must be ${PAIRING_NONCE_BYTES} bytes, got ${token.nonce.length}.`,\n \"invalid-nonce\"\n );\n }\n}\n\nfunction randomBytes(n: number): Uint8Array {\n const out = new Uint8Array(n);\n crypto.getRandomValues(out);\n return out;\n}\n"
|
|
10
10
|
],
|
|
11
|
-
"mappings": ";AAwCA;AACA;;;
|
|
12
|
-
"debugId": "
|
|
11
|
+
"mappings": "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",
|
|
12
|
+
"debugId": "D7A1C6B7D879C69A64756E2164756E21",
|
|
13
13
|
"names": []
|
|
14
14
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ban raw native interactive HTML elements in app source.
|
|
3
|
+
*
|
|
4
|
+
* Applications that consume `@fairfox/polly/ui` are expected to use
|
|
5
|
+
* the shared primitives (`<Button>`, `<ActionInput>`, `<Layout>`,
|
|
6
|
+
* `<Modal>`, `<ActionForm>`, `<Select>`) rather than writing raw
|
|
7
|
+
* `<button>`, `<input>`, `<select>`, `<textarea>`, `<form>`, or
|
|
8
|
+
* `<dialog>` elements. The primitives enforce data-action delegation,
|
|
9
|
+
* typed CSS-module classNames, accessibility attributes, and the
|
|
10
|
+
* layouting ban.
|
|
11
|
+
*
|
|
12
|
+
* This module exposes a programmatic check — `checkSharedComponents`
|
|
13
|
+
* — that walks a directory, scans every .tsx / .jsx file, and
|
|
14
|
+
* returns every violation it finds. Consumers typically wire it into
|
|
15
|
+
* a `bun check` script and set `exemptPackages` / `allowPaths` for
|
|
16
|
+
* legacy code that can't migrate yet.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { checkSharedComponents } from "@fairfox/polly/quality";
|
|
21
|
+
*
|
|
22
|
+
* const result = await checkSharedComponents({
|
|
23
|
+
* root: process.cwd(),
|
|
24
|
+
* scanRoot: "packages",
|
|
25
|
+
* exemptPackages: new Set(["struggle", "todo"]),
|
|
26
|
+
* });
|
|
27
|
+
* if (result.violations.length > 0) {
|
|
28
|
+
* result.print(console.error);
|
|
29
|
+
* process.exit(1);
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
/** One raw-element rule. Each rule flags a native element and
|
|
34
|
+
* suggests the polly primitive that replaces it. */
|
|
35
|
+
export interface SharedComponentRule {
|
|
36
|
+
/** Regular expression that matches the opening tag, e.g. /<button[\s>]/. */
|
|
37
|
+
pattern: RegExp;
|
|
38
|
+
/** Human-readable element marker, e.g. "<button>". */
|
|
39
|
+
element: string;
|
|
40
|
+
/** Suggested replacement, e.g. "<Button>". */
|
|
41
|
+
replacement: string;
|
|
42
|
+
/** Optional predicate; when it returns true the match is skipped.
|
|
43
|
+
* Used for legitimate raw usages (e.g. `<input type="hidden">`)
|
|
44
|
+
* that have no primitive analogue. */
|
|
45
|
+
skip?: (line: string) => boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Default rule set. Covers every native element that has a
|
|
48
|
+
* direct `@fairfox/polly/ui` replacement. Consumers may extend
|
|
49
|
+
* through the `additionalRules` option. */
|
|
50
|
+
export declare const DEFAULT_SHARED_COMPONENT_RULES: SharedComponentRule[];
|
|
51
|
+
/** One violation: a raw element found in an app source file. */
|
|
52
|
+
export interface SharedComponentViolation {
|
|
53
|
+
/** Path relative to `root`. */
|
|
54
|
+
file: string;
|
|
55
|
+
/** 1-based line number. */
|
|
56
|
+
line: number;
|
|
57
|
+
/** Element marker, e.g. "<button>". */
|
|
58
|
+
element: string;
|
|
59
|
+
/** Suggested replacement. */
|
|
60
|
+
replacement: string;
|
|
61
|
+
/** Trimmed offending line for context. */
|
|
62
|
+
content: string;
|
|
63
|
+
}
|
|
64
|
+
export interface CheckSharedComponentsOptions {
|
|
65
|
+
/** Repository root. Violation file paths are reported relative to
|
|
66
|
+
* this directory. */
|
|
67
|
+
root: string;
|
|
68
|
+
/** Directory under `root` to scan. Defaults to "packages". */
|
|
69
|
+
scanRoot?: string;
|
|
70
|
+
/** Directory names to skip entirely during traversal. Defaults to
|
|
71
|
+
* node_modules / .git / dist / build / tests. */
|
|
72
|
+
skipDirs?: Set<string>;
|
|
73
|
+
/** Workspace package names (the directory names immediately under
|
|
74
|
+
* `scanRoot`) to exempt. Useful for legacy packages that can't
|
|
75
|
+
* migrate to the primitives yet. */
|
|
76
|
+
exemptPackages?: Set<string>;
|
|
77
|
+
/** Additional rules appended to {@link DEFAULT_SHARED_COMPONENT_RULES}. */
|
|
78
|
+
additionalRules?: SharedComponentRule[];
|
|
79
|
+
/** Override the default rule set entirely. If set,
|
|
80
|
+
* `additionalRules` is ignored. */
|
|
81
|
+
rules?: SharedComponentRule[];
|
|
82
|
+
}
|
|
83
|
+
export interface SharedComponentsCheckResult {
|
|
84
|
+
violations: SharedComponentViolation[];
|
|
85
|
+
print(log: (msg: string) => void): void;
|
|
86
|
+
}
|
|
87
|
+
/** Walk the configured directory, returning every violation found. */
|
|
88
|
+
export declare function checkSharedComponents(options: CheckSharedComponentsOptions): Promise<SharedComponentsCheckResult>;
|
|
@@ -17,9 +17,126 @@ var __export = (target, all) => {
|
|
|
17
17
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
18
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
19
|
|
|
20
|
-
// tools/quality/src/
|
|
20
|
+
// tools/quality/src/check-shared-components.ts
|
|
21
21
|
import { readdir } from "node:fs/promises";
|
|
22
22
|
import { join, relative } from "node:path";
|
|
23
|
+
var DEFAULT_SHARED_COMPONENT_RULES = [
|
|
24
|
+
{ pattern: /<button[\s>]/, element: "<button>", replacement: "<Button>" },
|
|
25
|
+
{
|
|
26
|
+
pattern: /<input[\s>/]/,
|
|
27
|
+
element: "<input>",
|
|
28
|
+
replacement: "<ActionInput> or <TextInput>",
|
|
29
|
+
skip: (line) => /type=["']hidden["']/.test(line)
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: /<textarea[\s>]/,
|
|
33
|
+
element: "<textarea>",
|
|
34
|
+
replacement: '<ActionInput variant="multi">'
|
|
35
|
+
},
|
|
36
|
+
{ pattern: /<select[\s>]/, element: "<select>", replacement: "<Select>" },
|
|
37
|
+
{ pattern: /<form[\s>]/, element: "<form>", replacement: "<ActionForm>" },
|
|
38
|
+
{ pattern: /<dialog[\s>]/, element: "<dialog>", replacement: "<Modal>" }
|
|
39
|
+
];
|
|
40
|
+
var DEFAULT_SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", "tests"]);
|
|
41
|
+
async function checkSharedComponents(options) {
|
|
42
|
+
const rules = options.rules ?? [
|
|
43
|
+
...DEFAULT_SHARED_COMPONENT_RULES,
|
|
44
|
+
...options.additionalRules ?? []
|
|
45
|
+
];
|
|
46
|
+
const skipDirs = options.skipDirs ?? DEFAULT_SKIP_DIRS;
|
|
47
|
+
const scanRoot = options.scanRoot ?? "packages";
|
|
48
|
+
const exemptPackages = options.exemptPackages ?? new Set;
|
|
49
|
+
const packagesPath = join(options.root, scanRoot);
|
|
50
|
+
const violations = [];
|
|
51
|
+
await scanDirectory(packagesPath, {
|
|
52
|
+
root: options.root,
|
|
53
|
+
packagesPath,
|
|
54
|
+
skipDirs,
|
|
55
|
+
exemptPackages,
|
|
56
|
+
rules,
|
|
57
|
+
violations
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
violations,
|
|
61
|
+
print(log) {
|
|
62
|
+
if (violations.length === 0) {
|
|
63
|
+
log("[shared-components] ok");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
log(`[shared-components] ${violations.length} violation(s) found:
|
|
67
|
+
`);
|
|
68
|
+
for (const v of violations) {
|
|
69
|
+
log(` ${v.file}:${v.line} — ${v.element} → use ${v.replacement}`);
|
|
70
|
+
log(` ${v.content}
|
|
71
|
+
`);
|
|
72
|
+
}
|
|
73
|
+
log("[shared-components] Use @fairfox/polly/ui primitives instead of native HTML elements.");
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function scanDirectory(dir, state) {
|
|
78
|
+
let entries;
|
|
79
|
+
try {
|
|
80
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
81
|
+
} catch {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
const fullPath = join(dir, entry.name);
|
|
86
|
+
if (entry.isDirectory()) {
|
|
87
|
+
if (state.skipDirs.has(entry.name)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (dir === state.packagesPath && state.exemptPackages.has(entry.name)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
await scanDirectory(fullPath, state);
|
|
94
|
+
} else if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx"))) {
|
|
95
|
+
await scanFile(fullPath, state);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function scanFile(filePath, state) {
|
|
100
|
+
const text = await Bun.file(filePath).text();
|
|
101
|
+
const lines = text.split(`
|
|
102
|
+
`);
|
|
103
|
+
for (let i = 0;i < lines.length; i++) {
|
|
104
|
+
const line = lines[i];
|
|
105
|
+
if (!line)
|
|
106
|
+
continue;
|
|
107
|
+
const trimmed = line.trim();
|
|
108
|
+
if (isCommentLine(trimmed))
|
|
109
|
+
continue;
|
|
110
|
+
for (const rule of state.rules) {
|
|
111
|
+
if (!matchesRule(line, rule))
|
|
112
|
+
continue;
|
|
113
|
+
state.violations.push({
|
|
114
|
+
file: relative(state.root, filePath),
|
|
115
|
+
line: i + 1,
|
|
116
|
+
element: rule.element,
|
|
117
|
+
replacement: rule.replacement,
|
|
118
|
+
content: trimmed
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function isCommentLine(trimmed) {
|
|
124
|
+
return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
|
|
125
|
+
}
|
|
126
|
+
function matchesRule(line, rule) {
|
|
127
|
+
if (!rule.pattern.test(line))
|
|
128
|
+
return false;
|
|
129
|
+
const commentIndex = line.indexOf("//");
|
|
130
|
+
const elementIndex = line.search(rule.pattern);
|
|
131
|
+
if (commentIndex !== -1 && commentIndex < elementIndex)
|
|
132
|
+
return false;
|
|
133
|
+
if (rule.skip?.(line))
|
|
134
|
+
return false;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
// tools/quality/src/css/shared.ts
|
|
138
|
+
import { readdir as readdir2 } from "node:fs/promises";
|
|
139
|
+
import { join as join2, relative as relative2 } from "node:path";
|
|
23
140
|
|
|
24
141
|
// tools/quality/src/logger.ts
|
|
25
142
|
function defaultLog(message) {
|
|
@@ -48,20 +165,20 @@ function resetLogger() {
|
|
|
48
165
|
}
|
|
49
166
|
|
|
50
167
|
// tools/quality/src/css/shared.ts
|
|
51
|
-
var
|
|
168
|
+
var DEFAULT_SKIP_DIRS2 = ["node_modules", ".git", "dist", "dist-test", "build", "coverage"];
|
|
52
169
|
async function walkDirectory(dir, visit, opts) {
|
|
53
|
-
const skipDirs = new Set(opts.skipDirs ??
|
|
170
|
+
const skipDirs = new Set(opts.skipDirs ?? DEFAULT_SKIP_DIRS2);
|
|
54
171
|
const skipFiles = new Set(opts.skipFiles ?? []);
|
|
55
172
|
const rootDir = opts.rootDir;
|
|
56
173
|
async function walk(current) {
|
|
57
174
|
let entries;
|
|
58
175
|
try {
|
|
59
|
-
entries = await
|
|
176
|
+
entries = await readdir2(current, { withFileTypes: true });
|
|
60
177
|
} catch {
|
|
61
178
|
return;
|
|
62
179
|
}
|
|
63
180
|
for (const entry of entries) {
|
|
64
|
-
const full =
|
|
181
|
+
const full = join2(current, entry.name);
|
|
65
182
|
if (entry.isDirectory()) {
|
|
66
183
|
if (skipDirs.has(entry.name))
|
|
67
184
|
continue;
|
|
@@ -69,7 +186,7 @@ async function walkDirectory(dir, visit, opts) {
|
|
|
69
186
|
} else if (entry.isFile()) {
|
|
70
187
|
if (skipFiles.has(entry.name))
|
|
71
188
|
continue;
|
|
72
|
-
const rel =
|
|
189
|
+
const rel = relative2(rootDir, full);
|
|
73
190
|
await visit(full, rel);
|
|
74
191
|
}
|
|
75
192
|
}
|
|
@@ -90,7 +207,7 @@ function formatViolations(kind, violations, rootDir) {
|
|
|
90
207
|
byFile.set(v.file, bucket);
|
|
91
208
|
}
|
|
92
209
|
for (const [file, fileViolations] of byFile) {
|
|
93
|
-
lines.push(` ${
|
|
210
|
+
lines.push(` ${relative2(rootDir, file)}`);
|
|
94
211
|
for (const v of fileViolations) {
|
|
95
212
|
lines.push(` L${v.line}: ${v.content}`);
|
|
96
213
|
lines.push(` → ${v.suggestion} [${v.rule}]`);
|
|
@@ -654,16 +771,16 @@ function suggestFix(line) {
|
|
|
654
771
|
}
|
|
655
772
|
return;
|
|
656
773
|
}
|
|
657
|
-
function isFileExcluded(
|
|
658
|
-
const segments =
|
|
774
|
+
function isFileExcluded(relative3, excludeDirs, excludePackages, excludeFiles) {
|
|
775
|
+
const segments = relative3.split("/");
|
|
659
776
|
if (segments.some((s) => excludeDirs.has(s)))
|
|
660
777
|
return true;
|
|
661
778
|
if (excludePackages.size > 0 && segments.some((s) => excludePackages.has(s)))
|
|
662
779
|
return true;
|
|
663
780
|
const basename = segments[segments.length - 1] ?? "";
|
|
664
|
-
return excludeFiles.has(basename) || excludeFiles.has(
|
|
781
|
+
return excludeFiles.has(basename) || excludeFiles.has(relative3);
|
|
665
782
|
}
|
|
666
|
-
function findViolations(
|
|
783
|
+
function findViolations(relative3, content) {
|
|
667
784
|
const results = [];
|
|
668
785
|
const lines = content.split(`
|
|
669
786
|
`);
|
|
@@ -678,7 +795,7 @@ function findViolations(relative2, content) {
|
|
|
678
795
|
continue;
|
|
679
796
|
if (!isLineClean(line)) {
|
|
680
797
|
results.push({
|
|
681
|
-
file:
|
|
798
|
+
file: relative3,
|
|
682
799
|
line: i + 1,
|
|
683
800
|
content: line.trim(),
|
|
684
801
|
advice: suggestFix(line.trim())
|
|
@@ -713,11 +830,11 @@ async function checkNoAsCasting(options) {
|
|
|
713
830
|
const glob = new Glob(pattern);
|
|
714
831
|
const violations = [];
|
|
715
832
|
for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
|
|
716
|
-
const
|
|
717
|
-
if (isFileExcluded(
|
|
833
|
+
const relative3 = file.replace(`${rootDir}/`, "");
|
|
834
|
+
if (isFileExcluded(relative3, excludeDirs, excludePackages, excludeFiles))
|
|
718
835
|
continue;
|
|
719
836
|
const content = readFileSync(file, "utf-8");
|
|
720
|
-
violations.push(...findViolations(
|
|
837
|
+
violations.push(...findViolations(relative3, content));
|
|
721
838
|
}
|
|
722
839
|
return { violations, print: () => printViolations(violations) };
|
|
723
840
|
}
|
|
@@ -822,4 +939,4 @@ switch (subcommand) {
|
|
|
822
939
|
}
|
|
823
940
|
process.exit(exitCode);
|
|
824
941
|
|
|
825
|
-
//# debugId=
|
|
942
|
+
//# debugId=BF6E04239E5036A864756E2164756E21
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../tools/quality/src/css/shared.ts", "../tools/quality/src/logger.ts", "../tools/quality/src/css/check-layout.ts", "../tools/quality/src/css/check-quality.ts", "../tools/quality/src/css/check-unused.ts", "../tools/quality/src/css/check-vars.ts", "../tools/quality/src/no-as-casting.ts", "../tools/quality/src/cli.ts"],
|
|
3
|
+
"sources": ["../tools/quality/src/check-shared-components.ts", "../tools/quality/src/css/shared.ts", "../tools/quality/src/logger.ts", "../tools/quality/src/css/check-layout.ts", "../tools/quality/src/css/check-quality.ts", "../tools/quality/src/css/check-unused.ts", "../tools/quality/src/css/check-vars.ts", "../tools/quality/src/no-as-casting.ts", "../tools/quality/src/cli.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"/**\n * Ban raw native interactive HTML elements in app source.\n *\n * Applications that consume `@fairfox/polly/ui` are expected to use\n * the shared primitives (`<Button>`, `<ActionInput>`, `<Layout>`,\n * `<Modal>`, `<ActionForm>`, `<Select>`) rather than writing raw\n * `<button>`, `<input>`, `<select>`, `<textarea>`, `<form>`, or\n * `<dialog>` elements. The primitives enforce data-action delegation,\n * typed CSS-module classNames, accessibility attributes, and the\n * layouting ban.\n *\n * This module exposes a programmatic check — `checkSharedComponents`\n * — that walks a directory, scans every .tsx / .jsx file, and\n * returns every violation it finds. Consumers typically wire it into\n * a `bun check` script and set `exemptPackages` / `allowPaths` for\n * legacy code that can't migrate yet.\n *\n * @example\n * ```ts\n * import { checkSharedComponents } from \"@fairfox/polly/quality\";\n *\n * const result = await checkSharedComponents({\n * root: process.cwd(),\n * scanRoot: \"packages\",\n * exemptPackages: new Set([\"struggle\", \"todo\"]),\n * });\n * if (result.violations.length > 0) {\n * result.print(console.error);\n * process.exit(1);\n * }\n * ```\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\n\n/** One raw-element rule. Each rule flags a native element and\n * suggests the polly primitive that replaces it. */\nexport interface SharedComponentRule {\n /** Regular expression that matches the opening tag, e.g. /<button[\\s>]/. */\n pattern: RegExp;\n /** Human-readable element marker, e.g. \"<button>\". */\n element: string;\n /** Suggested replacement, e.g. \"<Button>\". */\n replacement: string;\n /** Optional predicate; when it returns true the match is skipped.\n * Used for legitimate raw usages (e.g. `<input type=\"hidden\">`)\n * that have no primitive analogue. */\n skip?: (line: string) => boolean;\n}\n\n/** Default rule set. Covers every native element that has a\n * direct `@fairfox/polly/ui` replacement. Consumers may extend\n * through the `additionalRules` option. */\nexport const DEFAULT_SHARED_COMPONENT_RULES: SharedComponentRule[] = [\n { pattern: /<button[\\s>]/, element: \"<button>\", replacement: \"<Button>\" },\n {\n pattern: /<input[\\s>/]/,\n element: \"<input>\",\n replacement: \"<ActionInput> or <TextInput>\",\n // `<input type=\"hidden\">` has no primitive analogue and is a\n // legitimate way to carry form data.\n skip: (line) => /type=[\"']hidden[\"']/.test(line),\n },\n {\n pattern: /<textarea[\\s>]/,\n element: \"<textarea>\",\n replacement: '<ActionInput variant=\"multi\">',\n },\n { pattern: /<select[\\s>]/, element: \"<select>\", replacement: \"<Select>\" },\n { pattern: /<form[\\s>]/, element: \"<form>\", replacement: \"<ActionForm>\" },\n { pattern: /<dialog[\\s>]/, element: \"<dialog>\", replacement: \"<Modal>\" },\n];\n\n/** One violation: a raw element found in an app source file. */\nexport interface SharedComponentViolation {\n /** Path relative to `root`. */\n file: string;\n /** 1-based line number. */\n line: number;\n /** Element marker, e.g. \"<button>\". */\n element: string;\n /** Suggested replacement. */\n replacement: string;\n /** Trimmed offending line for context. */\n content: string;\n}\n\nexport interface CheckSharedComponentsOptions {\n /** Repository root. Violation file paths are reported relative to\n * this directory. */\n root: string;\n /** Directory under `root` to scan. Defaults to \"packages\". */\n scanRoot?: string;\n /** Directory names to skip entirely during traversal. Defaults to\n * node_modules / .git / dist / build / tests. */\n skipDirs?: Set<string>;\n /** Workspace package names (the directory names immediately under\n * `scanRoot`) to exempt. Useful for legacy packages that can't\n * migrate to the primitives yet. */\n exemptPackages?: Set<string>;\n /** Additional rules appended to {@link DEFAULT_SHARED_COMPONENT_RULES}. */\n additionalRules?: SharedComponentRule[];\n /** Override the default rule set entirely. If set,\n * `additionalRules` is ignored. */\n rules?: SharedComponentRule[];\n}\n\nconst DEFAULT_SKIP_DIRS = new Set([\"node_modules\", \".git\", \"dist\", \"build\", \"tests\"]);\n\nexport interface SharedComponentsCheckResult {\n violations: SharedComponentViolation[];\n print(log: (msg: string) => void): void;\n}\n\n/** Walk the configured directory, returning every violation found. */\nexport async function checkSharedComponents(\n options: CheckSharedComponentsOptions\n): Promise<SharedComponentsCheckResult> {\n const rules = options.rules ?? [\n ...DEFAULT_SHARED_COMPONENT_RULES,\n ...(options.additionalRules ?? []),\n ];\n const skipDirs = options.skipDirs ?? DEFAULT_SKIP_DIRS;\n const scanRoot = options.scanRoot ?? \"packages\";\n const exemptPackages = options.exemptPackages ?? new Set<string>();\n const packagesPath = join(options.root, scanRoot);\n const violations: SharedComponentViolation[] = [];\n\n await scanDirectory(packagesPath, {\n root: options.root,\n packagesPath,\n skipDirs,\n exemptPackages,\n rules,\n violations,\n });\n\n return {\n violations,\n print(log) {\n if (violations.length === 0) {\n log(\"[shared-components] ok\");\n return;\n }\n log(`[shared-components] ${violations.length} violation(s) found:\\n`);\n for (const v of violations) {\n log(` ${v.file}:${v.line} — ${v.element} → use ${v.replacement}`);\n log(` ${v.content}\\n`);\n }\n log(\"[shared-components] Use @fairfox/polly/ui primitives instead of native HTML elements.\");\n },\n };\n}\n\ninterface ScanState {\n root: string;\n packagesPath: string;\n skipDirs: Set<string>;\n exemptPackages: Set<string>;\n rules: SharedComponentRule[];\n violations: SharedComponentViolation[];\n}\n\nasync function scanDirectory(dir: string, state: ScanState): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (state.skipDirs.has(entry.name)) {\n continue;\n }\n if (dir === state.packagesPath && state.exemptPackages.has(entry.name)) {\n continue;\n }\n await scanDirectory(fullPath, state);\n } else if (entry.isFile() && (entry.name.endsWith(\".tsx\") || entry.name.endsWith(\".jsx\"))) {\n await scanFile(fullPath, state);\n }\n }\n}\n\nasync function scanFile(filePath: string, state: ScanState): Promise<void> {\n const text = await Bun.file(filePath).text();\n const lines = text.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line) continue;\n const trimmed = line.trim();\n if (isCommentLine(trimmed)) continue;\n for (const rule of state.rules) {\n if (!matchesRule(line, rule)) continue;\n state.violations.push({\n file: relative(state.root, filePath),\n line: i + 1,\n element: rule.element,\n replacement: rule.replacement,\n content: trimmed,\n });\n }\n }\n}\n\nfunction isCommentLine(trimmed: string): boolean {\n return trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\");\n}\n\nfunction matchesRule(line: string, rule: SharedComponentRule): boolean {\n if (!rule.pattern.test(line)) return false;\n const commentIndex = line.indexOf(\"//\");\n const elementIndex = line.search(rule.pattern);\n if (commentIndex !== -1 && commentIndex < elementIndex) return false;\n if (rule.skip?.(line)) return false;\n return true;\n}\n",
|
|
5
6
|
"/**\n * Shared plumbing for CSS conformance checks.\n *\n * File discovery, violation printing, and common scanner options live\n * here so each check (`quality`, `layout`, `vars`, `unused`) can stay\n * focused on its own rule set.\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { logger } from \"../logger.ts\";\n\nexport type CssViolation = {\n file: string;\n line: number;\n rule: string;\n content: string;\n suggestion: string;\n};\n\nexport type CssCheckResult = {\n violations: CssViolation[];\n print: () => void;\n};\n\nexport type CssScanOptions = {\n rootDir: string;\n /** Directory names (not paths) to skip during recursion. */\n skipDirs?: string[];\n /** File names (not paths) to skip entirely. */\n skipFiles?: string[];\n};\n\nexport const DEFAULT_SKIP_DIRS = [\"node_modules\", \".git\", \"dist\", \"dist-test\", \"build\", \"coverage\"];\n\nexport async function walkDirectory(\n dir: string,\n visit: (filePath: string, relPath: string) => Promise<void>,\n opts: CssScanOptions\n): Promise<void> {\n const skipDirs = new Set(opts.skipDirs ?? DEFAULT_SKIP_DIRS);\n const skipFiles = new Set(opts.skipFiles ?? []);\n const rootDir = opts.rootDir;\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: recursive walk with skip sets is inherently branchy.\n async function walk(current: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(current, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const full = join(current, entry.name);\n if (entry.isDirectory()) {\n if (skipDirs.has(entry.name)) continue;\n await walk(full);\n } else if (entry.isFile()) {\n if (skipFiles.has(entry.name)) continue;\n const rel = relative(rootDir, full);\n await visit(full, rel);\n }\n }\n }\n\n await walk(dir);\n}\n\nexport function formatViolations(\n kind: string,\n violations: CssViolation[],\n rootDir: string\n): string[] {\n const lines: string[] = [];\n if (violations.length === 0) {\n lines.push(`✅ ${kind}: no violations`);\n return lines;\n }\n lines.push(`❌ ${kind}: ${violations.length} violation(s)`);\n const byFile = new Map<string, CssViolation[]>();\n for (const v of violations) {\n const bucket = byFile.get(v.file) ?? [];\n bucket.push(v);\n byFile.set(v.file, bucket);\n }\n for (const [file, fileViolations] of byFile) {\n lines.push(` ${relative(rootDir, file)}`);\n for (const v of fileViolations) {\n lines.push(` L${v.line}: ${v.content}`);\n lines.push(` → ${v.suggestion} [${v.rule}]`);\n }\n }\n return lines;\n}\n\nexport function makeResult(\n kind: string,\n rootDir: string,\n violations: CssViolation[]\n): CssCheckResult {\n return {\n violations,\n print() {\n for (const line of formatViolations(kind, violations, rootDir)) {\n if (line.startsWith(\"❌\")) {\n logger.error(line);\n } else {\n logger.log(line);\n }\n }\n },\n };\n}\n\n/** True when the line is a CSS comment (standalone or continuation). */\nexport function isInsideComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.startsWith(\"/*\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"//\");\n}\n\n/** Heuristic: true when the given line number falls inside an @keyframes block. */\nexport function isInsideKeyframes(lineNum: number, allLines: readonly string[]): boolean {\n for (let i = lineNum - 1; i >= 0; i -= 1) {\n const l = allLines[i]?.trim() ?? \"\";\n if (l.startsWith(\"@keyframes\")) return true;\n if (l === \"}\" && i < lineNum - 1) return false;\n }\n return false;\n}\n",
|
|
6
7
|
"/**\n * Logger for the quality tool.\n *\n * One mutable singleton so every check writes through the same sink.\n * Tests replace the methods to capture output, then call `resetLogger()`\n * to restore defaults. No dependency injection chain through every\n * check signature — the singleton pattern matches how Polly's own\n * CLI output is consumed (stdout/stderr at process edge).\n *\n * import { logger, resetLogger } from \"./logger\";\n * logger.error(\"…\");\n *\n * // in tests\n * const captured: string[] = [];\n * logger.error = (m) => captured.push(m);\n * // ... run check ...\n * resetLogger();\n */\n\nexport type QualityLogger = {\n log: (message: string) => void;\n error: (message: string) => void;\n info: (message: string) => void;\n warn: (message: string) => void;\n};\n\nfunction defaultLog(message: string): void {\n console.log(message);\n}\nfunction defaultError(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.error(message);\n}\nfunction defaultInfo(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.info(message);\n}\nfunction defaultWarn(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.warn(message);\n}\n\nexport const logger: QualityLogger = {\n log: defaultLog,\n error: defaultError,\n info: defaultInfo,\n warn: defaultWarn,\n};\n\nexport function resetLogger(): void {\n logger.log = defaultLog;\n logger.error = defaultError;\n logger.info = defaultInfo;\n logger.warn = defaultWarn;\n}\n",
|
|
7
8
|
"/**\n * CSS layout check.\n *\n * `display: flex` and `display: grid` are forbidden outside the Layout\n * primitive. Apps express layout through the `<Layout>` component so\n * layout decisions are declarative and greppable. Exempted paths default\n * to `Layout.module.css`; consumers can extend the list through\n * `layoutExemptPaths`. Suppress one-off cases with a layout-ignore CSS\n * comment on the violating line or the line above.\n */\n\nimport type { CssCheckResult, CssViolation } from \"./shared.ts\";\nimport { makeResult, walkDirectory } from \"./shared.ts\";\n\nexport type CssLayoutOptions = {\n rootDir: string;\n /** File basenames or path fragments where layout CSS is permitted. */\n layoutExemptPaths?: string[];\n /** Directory names skipped during recursion. */\n skipDirs?: string[];\n};\n\nconst CSS_PATTERNS: Array<{ pattern: RegExp; kind: string }> = [\n { pattern: /display\\s*:\\s*flex/, kind: \"display: flex in CSS\" },\n { pattern: /display\\s*:\\s*grid/, kind: \"display: grid in CSS\" },\n];\n\nconst TSX_PATTERNS: Array<{ pattern: RegExp; kind: string }> = [\n {\n pattern: /display\\s*:\\s*['\"]flex['\"]/,\n kind: \"display: flex in inline style\",\n },\n {\n pattern: /display\\s*:\\s*['\"]grid['\"]/,\n kind: \"display: grid in inline style\",\n },\n];\n\nconst SUPPRESS = \"layout-ignore\";\n\nexport async function checkCssLayout(options: CssLayoutOptions): Promise<CssCheckResult> {\n const rootDir = options.rootDir;\n const exempt = options.layoutExemptPaths ?? [\"Layout.module.css\", \"Layout.tsx\"];\n const violations: CssViolation[] = [];\n\n await walkDirectory(\n rootDir,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: per-file visitor covers filetype, suppression, and pattern loop.\n async (full) => {\n const isCss = full.endsWith(\".module.css\");\n const isTsx = full.endsWith(\".tsx\");\n if (!isCss && !isTsx) return;\n if (exempt.some((fragment) => full.includes(fragment))) return;\n\n const patterns = isCss ? CSS_PATTERNS : TSX_PATTERNS;\n const content = await Bun.file(full).text();\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (!line) continue;\n const trimmed = line.trim();\n if (trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\"))\n continue;\n if (trimmed.includes(SUPPRESS)) continue;\n const prev = i > 0 ? (lines[i - 1]?.trim() ?? \"\") : \"\";\n if (prev.includes(SUPPRESS)) continue;\n\n for (const rule of patterns) {\n if (rule.pattern.test(line)) {\n violations.push({\n file: full,\n line: i + 1,\n rule: rule.kind,\n content: trimmed,\n suggestion: \"Use the <Layout> component instead\",\n });\n break;\n }\n }\n }\n },\n {\n rootDir,\n skipDirs: options.skipDirs,\n }\n );\n\n return makeResult(\"css-layout\", rootDir, violations);\n}\n",
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
"/**\n * No-as-casting conformance check.\n *\n * Bans all TypeScript type assertions (`as Type`) except the allowed\n * patterns: `as const` (literal narrowing), `as unknown as` (explicit\n * escape hatch), import/export renames, and `as` inside strings or\n * comments. Violations include pattern-specific fix advice.\n *\n * This module exports the check logic as a library so consuming\n * applications can import it from `@fairfox/polly/quality` and run it\n * programmatically. Polly's own `scripts/check-no-as-casting.ts` is a\n * thin CLI wrapper around these exports.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { Glob } from \"bun\";\nimport { logger } from \"./logger\";\n\nexport interface Violation {\n file: string;\n line: number;\n content: string;\n advice?: string;\n}\n\nexport interface CheckResult {\n violations: Violation[];\n print: () => void;\n}\n\nexport interface CheckOptions {\n rootDir: string;\n exclude?: string[];\n excludePackages?: string[];\n excludeFiles?: string[];\n filePatterns?: string;\n}\n\n/**\n * Check whether a line contains a forbidden `as` type assertion.\n * Returns true if the line is clean (no violation), false if it violates.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Source-text scanning with many skip rules is inherently branchy.\nexport function isLineClean(line: string): boolean {\n if (!line.includes(\" as \")) return true;\n\n const trimmed = line.trim();\n\n // Full-line comments\n if (trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\")) {\n return true;\n }\n\n // as const (literal narrowing)\n if (line.match(/\\bas const\\b/)) {\n const withoutAsConst = line.replace(/\\bas const\\b/g, \"\");\n if (!withoutAsConst.includes(\" as \")) return true;\n }\n\n // as unknown as (explicit escape hatch)\n if (line.includes(\" as unknown as \") || line.trimEnd().endsWith(\"as unknown as\")) {\n const withoutEscapeHatch = line.replace(/\\bas unknown as\\b/g, \"\");\n if (!withoutEscapeHatch.includes(\" as \")) return true;\n }\n\n // Import/export renames\n if (\n line.match(/\\b(import|export)\\s+.*\\s+as\\s+\\w+/) ||\n line.match(/\\b(import|export)\\s+\\*\\s+as\\s+\\w+/) ||\n line.match(/\\b(import|export)\\s+type\\s+.*\\s+as\\s+\\w+/) ||\n line.match(/^\\s*\\w+\\s+as\\s+\\w+,?\\s*$/) ||\n line.match(/^\\s*type\\s+\\w+\\s+as\\s+\\w+,?\\s*$/)\n ) {\n return true;\n }\n\n // Property declarations: as= or as: or as,\n if (line.match(/\\bas\\s*[=:,]/)) return true;\n\n // String literal detection: count quotes before each ` as ` occurrence.\n // If any quote type has an odd count, the ` as ` is inside a string.\n if (everyAsInsideString(line)) return true;\n\n // JSX text: ` as ` between > and < with no code syntax around it\n if (isJsxText(trimmed)) return true;\n\n // Plain text heuristic: indented line with no code syntax characters\n // before ` as ` — catches multiline JSX text and template literal bodies.\n if (isPlainText(trimmed)) return true;\n\n // Inline comment: ` as ` appears only after //\n const commentIdx = line.indexOf(\"//\");\n if (commentIdx >= 0 && line.indexOf(\" as \", commentIdx) >= 0) {\n const beforeComment = line.substring(0, commentIdx);\n if (!beforeComment.includes(\" as \")) return true;\n }\n\n // SQL alias: `) as column_name`\n if (line.match(/\"\\)\\s+as\\s+\\w+\"/)) return true;\n\n if (line.includes(\" satisfies \")) return true;\n\n return false;\n}\n\n/**\n * Returns true when every ` as ` occurrence in the line falls inside a\n * string literal (single-quoted, double-quoted, or backtick).\n */\nfunction everyAsInsideString(line: string): boolean {\n let searchFrom = 0;\n while (true) {\n const idx = line.indexOf(\" as \", searchFrom);\n if (idx < 0) return true; // no more ` as ` to check\n const before = line.substring(0, idx);\n const singleQuotes = (before.match(/'/g) ?? []).length;\n const doubleQuotes = (before.match(/\"/g) ?? []).length;\n const backticks = (before.match(/`/g) ?? []).length;\n if (singleQuotes % 2 === 0 && doubleQuotes % 2 === 0 && backticks % 2 === 0) {\n return false; // this ` as ` is outside any string\n }\n searchFrom = idx + 4;\n }\n}\n\n/**\n * Detects JSX text content — ` as ` appearing between > and < with no\n * code-like syntax around it (no braces, semicolons, equals signs).\n */\nfunction isJsxText(trimmed: string): boolean {\n // Classic JSX text: starts after > or is plain text ending before <\n if (trimmed.match(/^[^{};=()]*\\bas\\b[^{};=()]*$/)) {\n // No code syntax at all — could be JSX text or template literal body.\n // Reject if it looks like a type assertion (word ` as ` TypeName pattern\n // where TypeName starts with uppercase, or is a known TS type).\n if (\n !trimmed.match(/\\bas\\s+[A-Z]\\w*/) &&\n !trimmed.match(/\\bas\\s+(string|number|boolean|any|unknown|never)\\b/)\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Heuristic for plain text in template literals or JSX: the line has no\n * code-like characters before ` as ` — no `=`, `{`, `}`, `:`, `;`, `(`.\n */\nfunction isPlainText(trimmed: string): boolean {\n const idx = trimmed.indexOf(\" as \");\n if (idx < 0) return false;\n const before = trimmed.substring(0, idx);\n // If nothing before ` as ` looks like code, it's probably prose.\n return (\n !before.match(/[={}:;(]/) &&\n !before.match(/\\b(const|let|var|type|interface|function|return|await)\\b/)\n );\n}\n\n/**\n * Suggest a concrete fix for a specific violation pattern.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Pattern-matching advice is a linear chain of if-returns.\nexport function suggestFix(line: string): string | undefined {\n if (line.includes(\"JSON.parse\")) {\n return \"Use a validation function or type guard to parse and validate the result.\";\n }\n if (\n line.includes(\"as HTMLInputElement\") ||\n line.includes(\"as HTMLTextAreaElement\") ||\n line.includes(\"as HTMLButtonElement\")\n ) {\n return \"Use instanceof: if (el instanceof HTMLInputElement) { el.value ... }\";\n }\n if (line.includes(\"as HTMLElement\") || line.includes(\"as Element\")) {\n return \"Use instanceof: if (el instanceof HTMLElement) { ... }\";\n }\n if (line.includes(\".doc()\") && line.includes(\"as \")) {\n return \"Type the DocHandle generic: repo.find<MyType>(id) returns DocHandle<MyType>.\";\n }\n if (\n line.includes(\"Record<string, unknown>\") &&\n (line.includes(\"window\") || line.includes(\"globalThis\"))\n ) {\n return \"Extract a type guard: function getGlobalProp(name: string): unknown { ... }\";\n }\n if (line.includes(\"Record<string, unknown>\")) {\n return \"Use a type guard function that narrows the unknown value to the target shape.\";\n }\n if (line.includes(\"as PeerId\") || line.includes(\"as DocumentId\")) {\n return \"Use the library's branded-type constructor if available, or centralise the cast in a factory.\";\n }\n if (line.includes(\"as string\") || line.includes(\"as number\") || line.includes(\"as boolean\")) {\n return \"Narrow with typeof: if (typeof x === 'string') { ... }\";\n }\n if (line.includes(\"as any\")) {\n return \"Replace 'any' with 'unknown' and add a type guard or validation at the boundary.\";\n }\n return undefined;\n}\n\nfunction isFileExcluded(\n relative: string,\n excludeDirs: Set<string>,\n excludePackages: Set<string>,\n excludeFiles: Set<string>\n): boolean {\n const segments = relative.split(\"/\");\n if (segments.some((s) => excludeDirs.has(s))) return true;\n if (excludePackages.size > 0 && segments.some((s) => excludePackages.has(s))) return true;\n const basename = segments[segments.length - 1] ?? \"\";\n return excludeFiles.has(basename) || excludeFiles.has(relative);\n}\n\nfunction findViolations(relative: string, content: string): Violation[] {\n const results: Violation[] = [];\n const lines = content.split(\"\\n\");\n let insideTemplate = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const backticks = (line.match(/`/g) ?? []).length;\n const startedInTemplate = insideTemplate;\n if (backticks % 2 === 1) insideTemplate = !insideTemplate;\n\n // Line is entirely inside a multi-line template literal and has no\n // interpolation — treat as string content (e.g. SQL column aliases).\n if (startedInTemplate && backticks === 0 && !line.includes(\"${\")) continue;\n\n if (!isLineClean(line)) {\n results.push({\n file: relative,\n line: i + 1,\n content: line.trim(),\n advice: suggestFix(line.trim()),\n });\n }\n }\n return results;\n}\n\nfunction printViolations(violations: Violation[]): void {\n if (violations.length === 0) {\n logger.log(\"[no-as-casting] ✅ No violations found.\");\n return;\n }\n logger.log(`[no-as-casting] ❌ ${violations.length} violation(s) found:\\n`);\n for (const v of violations) {\n logger.log(` ${v.file}:${v.line}`);\n logger.log(` ${v.content}`);\n if (v.advice) logger.log(` 💡 ${v.advice}`);\n logger.log(\"\");\n }\n logger.log(\"[no-as-casting] Use type guards, validation, or fix the types at the source.\");\n logger.log('[no-as-casting] Only \"as const\" and \"as unknown as\" are allowed.');\n}\n\n/**\n * Run the no-as-casting check against a directory. Returns a result\n * object with the violations and a print function for CLI output.\n */\nexport async function checkNoAsCasting(options: CheckOptions): Promise<CheckResult> {\n const rootDir = options.rootDir;\n const excludeDirs = new Set(options.exclude ?? [\"node_modules\", \"dist\", \".git\", \".bun\"]);\n const excludePackages = new Set(options.excludePackages ?? []);\n const excludeFiles = new Set(options.excludeFiles ?? []);\n const pattern = options.filePatterns ?? \"**/*.{ts,tsx}\";\n const glob = new Glob(pattern);\n const violations: Violation[] = [];\n\n for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {\n const relative = file.replace(`${rootDir}/`, \"\");\n if (isFileExcluded(relative, excludeDirs, excludePackages, excludeFiles)) continue;\n const content = readFileSync(file, \"utf-8\");\n violations.push(...findViolations(relative, content));\n }\n\n return { violations, print: () => printViolations(violations) };\n}\n",
|
|
12
13
|
"#!/usr/bin/env bun\n\n/**\n * CLI entry point for Polly quality checks.\n *\n * polly quality # run every check\n * polly quality no-as-casting # only the TS casting check\n * polly quality css # all CSS checks\n * polly quality css-quality # only hardcoded-values check\n * polly quality css-layout # only Layout-usage check\n * polly quality css-vars # only undefined-variable check\n * polly quality css-unused # only unused-selector check (advisory)\n *\n * Shared flags:\n * --root <dir> # defaults to process.cwd()\n * --exclude <a,b,c> # comma-separated dir names\n * --exclude-packages <a,b> # no-as-casting only\n * --exclude-files <a,b> # no-as-casting only\n * --pattern <glob> # no-as-casting only\n */\n\nimport {\n checkCssLayout,\n checkCssQuality,\n checkCssUnused,\n checkCssVars,\n checkNoAsCasting,\n} from \"./index\";\nimport { logger } from \"./logger\";\n\nconst args = process.argv.slice(2);\n\nfunction getFlag(name: string): string | undefined {\n const idx = args.indexOf(`--${name}`);\n return idx >= 0 ? args[idx + 1] : undefined;\n}\n\nfunction getSubcommand(): string {\n for (const arg of args) {\n if (!arg.startsWith(\"--\")) return arg;\n }\n return \"all\";\n}\n\nconst subcommand = getSubcommand();\nconst rootDir = getFlag(\"root\") ?? process.cwd();\nconst exclude = getFlag(\"exclude\")?.split(\",\") ?? [\n \"node_modules\",\n \"dist\",\n \".git\",\n \".bun\",\n \"dist-test\",\n \"build\",\n \"coverage\",\n];\nconst excludePackages = getFlag(\"exclude-packages\")?.split(\",\");\nconst excludeFiles = getFlag(\"exclude-files\")?.split(\",\");\nconst filePatterns = getFlag(\"pattern\");\n\nasync function runNoAsCasting(): Promise<number> {\n const result = await checkNoAsCasting({\n rootDir,\n exclude,\n ...(excludePackages ? { excludePackages } : {}),\n ...(excludeFiles ? { excludeFiles } : {}),\n ...(filePatterns ? { filePatterns } : {}),\n });\n result.print();\n return result.violations.length > 0 ? 1 : 0;\n}\n\nasync function runCssQuality(): Promise<number> {\n const r = await checkCssQuality({ rootDir, skipDirs: exclude });\n r.print();\n return r.violations.length > 0 ? 1 : 0;\n}\n\nasync function runCssLayout(): Promise<number> {\n const r = await checkCssLayout({ rootDir, skipDirs: exclude });\n r.print();\n return r.violations.length > 0 ? 1 : 0;\n}\n\nasync function runCssVars(): Promise<number> {\n const r = await checkCssVars({ rootDir, skipDirs: exclude });\n r.print();\n return r.violations.length > 0 ? 1 : 0;\n}\n\nasync function runCssUnused(): Promise<number> {\n const r = await checkCssUnused({ rootDir, skipDirs: exclude });\n r.print();\n return 0;\n}\n\nasync function runCssAll(): Promise<number> {\n const results = [\n await runCssQuality(),\n await runCssLayout(),\n await runCssVars(),\n await runCssUnused(),\n ];\n return results.some((code) => code !== 0) ? 1 : 0;\n}\n\nasync function runAll(): Promise<number> {\n const results = [await runNoAsCasting(), await runCssAll()];\n return results.some((code) => code !== 0) ? 1 : 0;\n}\n\nlet exitCode = 0;\nswitch (subcommand) {\n case \"no-as-casting\":\n exitCode = await runNoAsCasting();\n break;\n case \"css\":\n exitCode = await runCssAll();\n break;\n case \"css-quality\":\n exitCode = await runCssQuality();\n break;\n case \"css-layout\":\n exitCode = await runCssLayout();\n break;\n case \"css-vars\":\n exitCode = await runCssVars();\n break;\n case \"css-unused\":\n exitCode = await runCssUnused();\n break;\n case \"all\":\n exitCode = await runAll();\n break;\n default:\n logger.error(`Unknown quality subcommand: ${subcommand}`);\n logger.error(\n \"Expected one of: no-as-casting, css, css-quality, css-layout, css-vars, css-unused\"\n );\n exitCode = 2;\n}\n\nprocess.exit(exitCode);\n"
|
|
13
14
|
],
|
|
14
|
-
"mappings": "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",
|
|
15
|
-
"debugId": "
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "BF6E04239E5036A864756E2164756E21",
|
|
16
17
|
"names": []
|
|
17
18
|
}
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* }
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
+
export { type CheckSharedComponentsOptions, checkSharedComponents, DEFAULT_SHARED_COMPONENT_RULES, type SharedComponentRule, type SharedComponentsCheckResult, type SharedComponentViolation, } from "./check-shared-components.ts";
|
|
31
32
|
export { type CssLayoutOptions, checkCssLayout, } from "./css/check-layout.ts";
|
|
32
33
|
export { type CssQualityOptions, checkCssQuality, } from "./css/check-quality.ts";
|
|
33
34
|
export { type CssUnusedOptions, checkCssUnused } from "./css/check-unused.ts";
|
|
@@ -16,9 +16,126 @@ var __export = (target, all) => {
|
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
17
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
18
18
|
|
|
19
|
-
// tools/quality/src/
|
|
19
|
+
// tools/quality/src/check-shared-components.ts
|
|
20
20
|
import { readdir } from "node:fs/promises";
|
|
21
21
|
import { join, relative } from "node:path";
|
|
22
|
+
var DEFAULT_SHARED_COMPONENT_RULES = [
|
|
23
|
+
{ pattern: /<button[\s>]/, element: "<button>", replacement: "<Button>" },
|
|
24
|
+
{
|
|
25
|
+
pattern: /<input[\s>/]/,
|
|
26
|
+
element: "<input>",
|
|
27
|
+
replacement: "<ActionInput> or <TextInput>",
|
|
28
|
+
skip: (line) => /type=["']hidden["']/.test(line)
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
pattern: /<textarea[\s>]/,
|
|
32
|
+
element: "<textarea>",
|
|
33
|
+
replacement: '<ActionInput variant="multi">'
|
|
34
|
+
},
|
|
35
|
+
{ pattern: /<select[\s>]/, element: "<select>", replacement: "<Select>" },
|
|
36
|
+
{ pattern: /<form[\s>]/, element: "<form>", replacement: "<ActionForm>" },
|
|
37
|
+
{ pattern: /<dialog[\s>]/, element: "<dialog>", replacement: "<Modal>" }
|
|
38
|
+
];
|
|
39
|
+
var DEFAULT_SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", "tests"]);
|
|
40
|
+
async function checkSharedComponents(options) {
|
|
41
|
+
const rules = options.rules ?? [
|
|
42
|
+
...DEFAULT_SHARED_COMPONENT_RULES,
|
|
43
|
+
...options.additionalRules ?? []
|
|
44
|
+
];
|
|
45
|
+
const skipDirs = options.skipDirs ?? DEFAULT_SKIP_DIRS;
|
|
46
|
+
const scanRoot = options.scanRoot ?? "packages";
|
|
47
|
+
const exemptPackages = options.exemptPackages ?? new Set;
|
|
48
|
+
const packagesPath = join(options.root, scanRoot);
|
|
49
|
+
const violations = [];
|
|
50
|
+
await scanDirectory(packagesPath, {
|
|
51
|
+
root: options.root,
|
|
52
|
+
packagesPath,
|
|
53
|
+
skipDirs,
|
|
54
|
+
exemptPackages,
|
|
55
|
+
rules,
|
|
56
|
+
violations
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
violations,
|
|
60
|
+
print(log) {
|
|
61
|
+
if (violations.length === 0) {
|
|
62
|
+
log("[shared-components] ok");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
log(`[shared-components] ${violations.length} violation(s) found:
|
|
66
|
+
`);
|
|
67
|
+
for (const v of violations) {
|
|
68
|
+
log(` ${v.file}:${v.line} — ${v.element} → use ${v.replacement}`);
|
|
69
|
+
log(` ${v.content}
|
|
70
|
+
`);
|
|
71
|
+
}
|
|
72
|
+
log("[shared-components] Use @fairfox/polly/ui primitives instead of native HTML elements.");
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function scanDirectory(dir, state) {
|
|
77
|
+
let entries;
|
|
78
|
+
try {
|
|
79
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
80
|
+
} catch {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const fullPath = join(dir, entry.name);
|
|
85
|
+
if (entry.isDirectory()) {
|
|
86
|
+
if (state.skipDirs.has(entry.name)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (dir === state.packagesPath && state.exemptPackages.has(entry.name)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
await scanDirectory(fullPath, state);
|
|
93
|
+
} else if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx"))) {
|
|
94
|
+
await scanFile(fullPath, state);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function scanFile(filePath, state) {
|
|
99
|
+
const text = await Bun.file(filePath).text();
|
|
100
|
+
const lines = text.split(`
|
|
101
|
+
`);
|
|
102
|
+
for (let i = 0;i < lines.length; i++) {
|
|
103
|
+
const line = lines[i];
|
|
104
|
+
if (!line)
|
|
105
|
+
continue;
|
|
106
|
+
const trimmed = line.trim();
|
|
107
|
+
if (isCommentLine(trimmed))
|
|
108
|
+
continue;
|
|
109
|
+
for (const rule of state.rules) {
|
|
110
|
+
if (!matchesRule(line, rule))
|
|
111
|
+
continue;
|
|
112
|
+
state.violations.push({
|
|
113
|
+
file: relative(state.root, filePath),
|
|
114
|
+
line: i + 1,
|
|
115
|
+
element: rule.element,
|
|
116
|
+
replacement: rule.replacement,
|
|
117
|
+
content: trimmed
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function isCommentLine(trimmed) {
|
|
123
|
+
return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
|
|
124
|
+
}
|
|
125
|
+
function matchesRule(line, rule) {
|
|
126
|
+
if (!rule.pattern.test(line))
|
|
127
|
+
return false;
|
|
128
|
+
const commentIndex = line.indexOf("//");
|
|
129
|
+
const elementIndex = line.search(rule.pattern);
|
|
130
|
+
if (commentIndex !== -1 && commentIndex < elementIndex)
|
|
131
|
+
return false;
|
|
132
|
+
if (rule.skip?.(line))
|
|
133
|
+
return false;
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
// tools/quality/src/css/shared.ts
|
|
137
|
+
import { readdir as readdir2 } from "node:fs/promises";
|
|
138
|
+
import { join as join2, relative as relative2 } from "node:path";
|
|
22
139
|
|
|
23
140
|
// tools/quality/src/logger.ts
|
|
24
141
|
function defaultLog(message) {
|
|
@@ -47,20 +164,20 @@ function resetLogger() {
|
|
|
47
164
|
}
|
|
48
165
|
|
|
49
166
|
// tools/quality/src/css/shared.ts
|
|
50
|
-
var
|
|
167
|
+
var DEFAULT_SKIP_DIRS2 = ["node_modules", ".git", "dist", "dist-test", "build", "coverage"];
|
|
51
168
|
async function walkDirectory(dir, visit, opts) {
|
|
52
|
-
const skipDirs = new Set(opts.skipDirs ??
|
|
169
|
+
const skipDirs = new Set(opts.skipDirs ?? DEFAULT_SKIP_DIRS2);
|
|
53
170
|
const skipFiles = new Set(opts.skipFiles ?? []);
|
|
54
171
|
const rootDir = opts.rootDir;
|
|
55
172
|
async function walk(current) {
|
|
56
173
|
let entries;
|
|
57
174
|
try {
|
|
58
|
-
entries = await
|
|
175
|
+
entries = await readdir2(current, { withFileTypes: true });
|
|
59
176
|
} catch {
|
|
60
177
|
return;
|
|
61
178
|
}
|
|
62
179
|
for (const entry of entries) {
|
|
63
|
-
const full =
|
|
180
|
+
const full = join2(current, entry.name);
|
|
64
181
|
if (entry.isDirectory()) {
|
|
65
182
|
if (skipDirs.has(entry.name))
|
|
66
183
|
continue;
|
|
@@ -68,7 +185,7 @@ async function walkDirectory(dir, visit, opts) {
|
|
|
68
185
|
} else if (entry.isFile()) {
|
|
69
186
|
if (skipFiles.has(entry.name))
|
|
70
187
|
continue;
|
|
71
|
-
const rel =
|
|
188
|
+
const rel = relative2(rootDir, full);
|
|
72
189
|
await visit(full, rel);
|
|
73
190
|
}
|
|
74
191
|
}
|
|
@@ -89,7 +206,7 @@ function formatViolations(kind, violations, rootDir) {
|
|
|
89
206
|
byFile.set(v.file, bucket);
|
|
90
207
|
}
|
|
91
208
|
for (const [file, fileViolations] of byFile) {
|
|
92
|
-
lines.push(` ${
|
|
209
|
+
lines.push(` ${relative2(rootDir, file)}`);
|
|
93
210
|
for (const v of fileViolations) {
|
|
94
211
|
lines.push(` L${v.line}: ${v.content}`);
|
|
95
212
|
lines.push(` → ${v.suggestion} [${v.rule}]`);
|
|
@@ -653,16 +770,16 @@ function suggestFix(line) {
|
|
|
653
770
|
}
|
|
654
771
|
return;
|
|
655
772
|
}
|
|
656
|
-
function isFileExcluded(
|
|
657
|
-
const segments =
|
|
773
|
+
function isFileExcluded(relative3, excludeDirs, excludePackages, excludeFiles) {
|
|
774
|
+
const segments = relative3.split("/");
|
|
658
775
|
if (segments.some((s) => excludeDirs.has(s)))
|
|
659
776
|
return true;
|
|
660
777
|
if (excludePackages.size > 0 && segments.some((s) => excludePackages.has(s)))
|
|
661
778
|
return true;
|
|
662
779
|
const basename = segments[segments.length - 1] ?? "";
|
|
663
|
-
return excludeFiles.has(basename) || excludeFiles.has(
|
|
780
|
+
return excludeFiles.has(basename) || excludeFiles.has(relative3);
|
|
664
781
|
}
|
|
665
|
-
function findViolations(
|
|
782
|
+
function findViolations(relative3, content) {
|
|
666
783
|
const results = [];
|
|
667
784
|
const lines = content.split(`
|
|
668
785
|
`);
|
|
@@ -677,7 +794,7 @@ function findViolations(relative2, content) {
|
|
|
677
794
|
continue;
|
|
678
795
|
if (!isLineClean(line)) {
|
|
679
796
|
results.push({
|
|
680
|
-
file:
|
|
797
|
+
file: relative3,
|
|
681
798
|
line: i + 1,
|
|
682
799
|
content: line.trim(),
|
|
683
800
|
advice: suggestFix(line.trim())
|
|
@@ -712,11 +829,11 @@ async function checkNoAsCasting(options) {
|
|
|
712
829
|
const glob = new Glob(pattern);
|
|
713
830
|
const violations = [];
|
|
714
831
|
for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
|
|
715
|
-
const
|
|
716
|
-
if (isFileExcluded(
|
|
832
|
+
const relative3 = file.replace(`${rootDir}/`, "");
|
|
833
|
+
if (isFileExcluded(relative3, excludeDirs, excludePackages, excludeFiles))
|
|
717
834
|
continue;
|
|
718
835
|
const content = readFileSync(file, "utf-8");
|
|
719
|
-
violations.push(...findViolations(
|
|
836
|
+
violations.push(...findViolations(relative3, content));
|
|
720
837
|
}
|
|
721
838
|
return { violations, print: () => printViolations(violations) };
|
|
722
839
|
}
|
|
@@ -725,11 +842,13 @@ export {
|
|
|
725
842
|
resetLogger,
|
|
726
843
|
logger,
|
|
727
844
|
isLineClean,
|
|
845
|
+
checkSharedComponents,
|
|
728
846
|
checkNoAsCasting,
|
|
729
847
|
checkCssVars,
|
|
730
848
|
checkCssUnused,
|
|
731
849
|
checkCssQuality,
|
|
732
|
-
checkCssLayout
|
|
850
|
+
checkCssLayout,
|
|
851
|
+
DEFAULT_SHARED_COMPONENT_RULES
|
|
733
852
|
};
|
|
734
853
|
|
|
735
|
-
//# debugId=
|
|
854
|
+
//# debugId=A8CB88D5CE00AC5664756E2164756E21
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../tools/quality/src/css/shared.ts", "../tools/quality/src/logger.ts", "../tools/quality/src/css/check-layout.ts", "../tools/quality/src/css/check-quality.ts", "../tools/quality/src/css/check-unused.ts", "../tools/quality/src/css/check-vars.ts", "../tools/quality/src/no-as-casting.ts"],
|
|
3
|
+
"sources": ["../tools/quality/src/check-shared-components.ts", "../tools/quality/src/css/shared.ts", "../tools/quality/src/logger.ts", "../tools/quality/src/css/check-layout.ts", "../tools/quality/src/css/check-quality.ts", "../tools/quality/src/css/check-unused.ts", "../tools/quality/src/css/check-vars.ts", "../tools/quality/src/no-as-casting.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"/**\n * Ban raw native interactive HTML elements in app source.\n *\n * Applications that consume `@fairfox/polly/ui` are expected to use\n * the shared primitives (`<Button>`, `<ActionInput>`, `<Layout>`,\n * `<Modal>`, `<ActionForm>`, `<Select>`) rather than writing raw\n * `<button>`, `<input>`, `<select>`, `<textarea>`, `<form>`, or\n * `<dialog>` elements. The primitives enforce data-action delegation,\n * typed CSS-module classNames, accessibility attributes, and the\n * layouting ban.\n *\n * This module exposes a programmatic check — `checkSharedComponents`\n * — that walks a directory, scans every .tsx / .jsx file, and\n * returns every violation it finds. Consumers typically wire it into\n * a `bun check` script and set `exemptPackages` / `allowPaths` for\n * legacy code that can't migrate yet.\n *\n * @example\n * ```ts\n * import { checkSharedComponents } from \"@fairfox/polly/quality\";\n *\n * const result = await checkSharedComponents({\n * root: process.cwd(),\n * scanRoot: \"packages\",\n * exemptPackages: new Set([\"struggle\", \"todo\"]),\n * });\n * if (result.violations.length > 0) {\n * result.print(console.error);\n * process.exit(1);\n * }\n * ```\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\n\n/** One raw-element rule. Each rule flags a native element and\n * suggests the polly primitive that replaces it. */\nexport interface SharedComponentRule {\n /** Regular expression that matches the opening tag, e.g. /<button[\\s>]/. */\n pattern: RegExp;\n /** Human-readable element marker, e.g. \"<button>\". */\n element: string;\n /** Suggested replacement, e.g. \"<Button>\". */\n replacement: string;\n /** Optional predicate; when it returns true the match is skipped.\n * Used for legitimate raw usages (e.g. `<input type=\"hidden\">`)\n * that have no primitive analogue. */\n skip?: (line: string) => boolean;\n}\n\n/** Default rule set. Covers every native element that has a\n * direct `@fairfox/polly/ui` replacement. Consumers may extend\n * through the `additionalRules` option. */\nexport const DEFAULT_SHARED_COMPONENT_RULES: SharedComponentRule[] = [\n { pattern: /<button[\\s>]/, element: \"<button>\", replacement: \"<Button>\" },\n {\n pattern: /<input[\\s>/]/,\n element: \"<input>\",\n replacement: \"<ActionInput> or <TextInput>\",\n // `<input type=\"hidden\">` has no primitive analogue and is a\n // legitimate way to carry form data.\n skip: (line) => /type=[\"']hidden[\"']/.test(line),\n },\n {\n pattern: /<textarea[\\s>]/,\n element: \"<textarea>\",\n replacement: '<ActionInput variant=\"multi\">',\n },\n { pattern: /<select[\\s>]/, element: \"<select>\", replacement: \"<Select>\" },\n { pattern: /<form[\\s>]/, element: \"<form>\", replacement: \"<ActionForm>\" },\n { pattern: /<dialog[\\s>]/, element: \"<dialog>\", replacement: \"<Modal>\" },\n];\n\n/** One violation: a raw element found in an app source file. */\nexport interface SharedComponentViolation {\n /** Path relative to `root`. */\n file: string;\n /** 1-based line number. */\n line: number;\n /** Element marker, e.g. \"<button>\". */\n element: string;\n /** Suggested replacement. */\n replacement: string;\n /** Trimmed offending line for context. */\n content: string;\n}\n\nexport interface CheckSharedComponentsOptions {\n /** Repository root. Violation file paths are reported relative to\n * this directory. */\n root: string;\n /** Directory under `root` to scan. Defaults to \"packages\". */\n scanRoot?: string;\n /** Directory names to skip entirely during traversal. Defaults to\n * node_modules / .git / dist / build / tests. */\n skipDirs?: Set<string>;\n /** Workspace package names (the directory names immediately under\n * `scanRoot`) to exempt. Useful for legacy packages that can't\n * migrate to the primitives yet. */\n exemptPackages?: Set<string>;\n /** Additional rules appended to {@link DEFAULT_SHARED_COMPONENT_RULES}. */\n additionalRules?: SharedComponentRule[];\n /** Override the default rule set entirely. If set,\n * `additionalRules` is ignored. */\n rules?: SharedComponentRule[];\n}\n\nconst DEFAULT_SKIP_DIRS = new Set([\"node_modules\", \".git\", \"dist\", \"build\", \"tests\"]);\n\nexport interface SharedComponentsCheckResult {\n violations: SharedComponentViolation[];\n print(log: (msg: string) => void): void;\n}\n\n/** Walk the configured directory, returning every violation found. */\nexport async function checkSharedComponents(\n options: CheckSharedComponentsOptions\n): Promise<SharedComponentsCheckResult> {\n const rules = options.rules ?? [\n ...DEFAULT_SHARED_COMPONENT_RULES,\n ...(options.additionalRules ?? []),\n ];\n const skipDirs = options.skipDirs ?? DEFAULT_SKIP_DIRS;\n const scanRoot = options.scanRoot ?? \"packages\";\n const exemptPackages = options.exemptPackages ?? new Set<string>();\n const packagesPath = join(options.root, scanRoot);\n const violations: SharedComponentViolation[] = [];\n\n await scanDirectory(packagesPath, {\n root: options.root,\n packagesPath,\n skipDirs,\n exemptPackages,\n rules,\n violations,\n });\n\n return {\n violations,\n print(log) {\n if (violations.length === 0) {\n log(\"[shared-components] ok\");\n return;\n }\n log(`[shared-components] ${violations.length} violation(s) found:\\n`);\n for (const v of violations) {\n log(` ${v.file}:${v.line} — ${v.element} → use ${v.replacement}`);\n log(` ${v.content}\\n`);\n }\n log(\"[shared-components] Use @fairfox/polly/ui primitives instead of native HTML elements.\");\n },\n };\n}\n\ninterface ScanState {\n root: string;\n packagesPath: string;\n skipDirs: Set<string>;\n exemptPackages: Set<string>;\n rules: SharedComponentRule[];\n violations: SharedComponentViolation[];\n}\n\nasync function scanDirectory(dir: string, state: ScanState): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (state.skipDirs.has(entry.name)) {\n continue;\n }\n if (dir === state.packagesPath && state.exemptPackages.has(entry.name)) {\n continue;\n }\n await scanDirectory(fullPath, state);\n } else if (entry.isFile() && (entry.name.endsWith(\".tsx\") || entry.name.endsWith(\".jsx\"))) {\n await scanFile(fullPath, state);\n }\n }\n}\n\nasync function scanFile(filePath: string, state: ScanState): Promise<void> {\n const text = await Bun.file(filePath).text();\n const lines = text.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line) continue;\n const trimmed = line.trim();\n if (isCommentLine(trimmed)) continue;\n for (const rule of state.rules) {\n if (!matchesRule(line, rule)) continue;\n state.violations.push({\n file: relative(state.root, filePath),\n line: i + 1,\n element: rule.element,\n replacement: rule.replacement,\n content: trimmed,\n });\n }\n }\n}\n\nfunction isCommentLine(trimmed: string): boolean {\n return trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\");\n}\n\nfunction matchesRule(line: string, rule: SharedComponentRule): boolean {\n if (!rule.pattern.test(line)) return false;\n const commentIndex = line.indexOf(\"//\");\n const elementIndex = line.search(rule.pattern);\n if (commentIndex !== -1 && commentIndex < elementIndex) return false;\n if (rule.skip?.(line)) return false;\n return true;\n}\n",
|
|
5
6
|
"/**\n * Shared plumbing for CSS conformance checks.\n *\n * File discovery, violation printing, and common scanner options live\n * here so each check (`quality`, `layout`, `vars`, `unused`) can stay\n * focused on its own rule set.\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { logger } from \"../logger.ts\";\n\nexport type CssViolation = {\n file: string;\n line: number;\n rule: string;\n content: string;\n suggestion: string;\n};\n\nexport type CssCheckResult = {\n violations: CssViolation[];\n print: () => void;\n};\n\nexport type CssScanOptions = {\n rootDir: string;\n /** Directory names (not paths) to skip during recursion. */\n skipDirs?: string[];\n /** File names (not paths) to skip entirely. */\n skipFiles?: string[];\n};\n\nexport const DEFAULT_SKIP_DIRS = [\"node_modules\", \".git\", \"dist\", \"dist-test\", \"build\", \"coverage\"];\n\nexport async function walkDirectory(\n dir: string,\n visit: (filePath: string, relPath: string) => Promise<void>,\n opts: CssScanOptions\n): Promise<void> {\n const skipDirs = new Set(opts.skipDirs ?? DEFAULT_SKIP_DIRS);\n const skipFiles = new Set(opts.skipFiles ?? []);\n const rootDir = opts.rootDir;\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: recursive walk with skip sets is inherently branchy.\n async function walk(current: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(current, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const full = join(current, entry.name);\n if (entry.isDirectory()) {\n if (skipDirs.has(entry.name)) continue;\n await walk(full);\n } else if (entry.isFile()) {\n if (skipFiles.has(entry.name)) continue;\n const rel = relative(rootDir, full);\n await visit(full, rel);\n }\n }\n }\n\n await walk(dir);\n}\n\nexport function formatViolations(\n kind: string,\n violations: CssViolation[],\n rootDir: string\n): string[] {\n const lines: string[] = [];\n if (violations.length === 0) {\n lines.push(`✅ ${kind}: no violations`);\n return lines;\n }\n lines.push(`❌ ${kind}: ${violations.length} violation(s)`);\n const byFile = new Map<string, CssViolation[]>();\n for (const v of violations) {\n const bucket = byFile.get(v.file) ?? [];\n bucket.push(v);\n byFile.set(v.file, bucket);\n }\n for (const [file, fileViolations] of byFile) {\n lines.push(` ${relative(rootDir, file)}`);\n for (const v of fileViolations) {\n lines.push(` L${v.line}: ${v.content}`);\n lines.push(` → ${v.suggestion} [${v.rule}]`);\n }\n }\n return lines;\n}\n\nexport function makeResult(\n kind: string,\n rootDir: string,\n violations: CssViolation[]\n): CssCheckResult {\n return {\n violations,\n print() {\n for (const line of formatViolations(kind, violations, rootDir)) {\n if (line.startsWith(\"❌\")) {\n logger.error(line);\n } else {\n logger.log(line);\n }\n }\n },\n };\n}\n\n/** True when the line is a CSS comment (standalone or continuation). */\nexport function isInsideComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.startsWith(\"/*\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"//\");\n}\n\n/** Heuristic: true when the given line number falls inside an @keyframes block. */\nexport function isInsideKeyframes(lineNum: number, allLines: readonly string[]): boolean {\n for (let i = lineNum - 1; i >= 0; i -= 1) {\n const l = allLines[i]?.trim() ?? \"\";\n if (l.startsWith(\"@keyframes\")) return true;\n if (l === \"}\" && i < lineNum - 1) return false;\n }\n return false;\n}\n",
|
|
6
7
|
"/**\n * Logger for the quality tool.\n *\n * One mutable singleton so every check writes through the same sink.\n * Tests replace the methods to capture output, then call `resetLogger()`\n * to restore defaults. No dependency injection chain through every\n * check signature — the singleton pattern matches how Polly's own\n * CLI output is consumed (stdout/stderr at process edge).\n *\n * import { logger, resetLogger } from \"./logger\";\n * logger.error(\"…\");\n *\n * // in tests\n * const captured: string[] = [];\n * logger.error = (m) => captured.push(m);\n * // ... run check ...\n * resetLogger();\n */\n\nexport type QualityLogger = {\n log: (message: string) => void;\n error: (message: string) => void;\n info: (message: string) => void;\n warn: (message: string) => void;\n};\n\nfunction defaultLog(message: string): void {\n console.log(message);\n}\nfunction defaultError(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.error(message);\n}\nfunction defaultInfo(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.info(message);\n}\nfunction defaultWarn(message: string): void {\n // biome-ignore lint/suspicious/noConsole: CLI output is the whole point of the default sink.\n console.warn(message);\n}\n\nexport const logger: QualityLogger = {\n log: defaultLog,\n error: defaultError,\n info: defaultInfo,\n warn: defaultWarn,\n};\n\nexport function resetLogger(): void {\n logger.log = defaultLog;\n logger.error = defaultError;\n logger.info = defaultInfo;\n logger.warn = defaultWarn;\n}\n",
|
|
7
8
|
"/**\n * CSS layout check.\n *\n * `display: flex` and `display: grid` are forbidden outside the Layout\n * primitive. Apps express layout through the `<Layout>` component so\n * layout decisions are declarative and greppable. Exempted paths default\n * to `Layout.module.css`; consumers can extend the list through\n * `layoutExemptPaths`. Suppress one-off cases with a layout-ignore CSS\n * comment on the violating line or the line above.\n */\n\nimport type { CssCheckResult, CssViolation } from \"./shared.ts\";\nimport { makeResult, walkDirectory } from \"./shared.ts\";\n\nexport type CssLayoutOptions = {\n rootDir: string;\n /** File basenames or path fragments where layout CSS is permitted. */\n layoutExemptPaths?: string[];\n /** Directory names skipped during recursion. */\n skipDirs?: string[];\n};\n\nconst CSS_PATTERNS: Array<{ pattern: RegExp; kind: string }> = [\n { pattern: /display\\s*:\\s*flex/, kind: \"display: flex in CSS\" },\n { pattern: /display\\s*:\\s*grid/, kind: \"display: grid in CSS\" },\n];\n\nconst TSX_PATTERNS: Array<{ pattern: RegExp; kind: string }> = [\n {\n pattern: /display\\s*:\\s*['\"]flex['\"]/,\n kind: \"display: flex in inline style\",\n },\n {\n pattern: /display\\s*:\\s*['\"]grid['\"]/,\n kind: \"display: grid in inline style\",\n },\n];\n\nconst SUPPRESS = \"layout-ignore\";\n\nexport async function checkCssLayout(options: CssLayoutOptions): Promise<CssCheckResult> {\n const rootDir = options.rootDir;\n const exempt = options.layoutExemptPaths ?? [\"Layout.module.css\", \"Layout.tsx\"];\n const violations: CssViolation[] = [];\n\n await walkDirectory(\n rootDir,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: per-file visitor covers filetype, suppression, and pattern loop.\n async (full) => {\n const isCss = full.endsWith(\".module.css\");\n const isTsx = full.endsWith(\".tsx\");\n if (!isCss && !isTsx) return;\n if (exempt.some((fragment) => full.includes(fragment))) return;\n\n const patterns = isCss ? CSS_PATTERNS : TSX_PATTERNS;\n const content = await Bun.file(full).text();\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (!line) continue;\n const trimmed = line.trim();\n if (trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\"))\n continue;\n if (trimmed.includes(SUPPRESS)) continue;\n const prev = i > 0 ? (lines[i - 1]?.trim() ?? \"\") : \"\";\n if (prev.includes(SUPPRESS)) continue;\n\n for (const rule of patterns) {\n if (rule.pattern.test(line)) {\n violations.push({\n file: full,\n line: i + 1,\n rule: rule.kind,\n content: trimmed,\n suggestion: \"Use the <Layout> component instead\",\n });\n break;\n }\n }\n }\n },\n {\n rootDir,\n skipDirs: options.skipDirs,\n }\n );\n\n return makeResult(\"css-layout\", rootDir, violations);\n}\n",
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
"/**\n * CSS variable reference validator.\n *\n * Two-pass scanner. First pass collects every `--name:` definition in\n * every `.css` file under the root. Second pass walks `.css`, `.ts`, and\n * `.tsx` files and reports any `var(--name)` that does not resolve. Catches\n * typos, stale references, and references to removed tokens.\n *\n * Variables that are set via JS (inline style) can be declared via\n * `dynamicVars` so they are treated as defined without appearing in CSS.\n */\n\nimport type { CssCheckResult, CssViolation } from \"./shared.ts\";\nimport { makeResult, walkDirectory } from \"./shared.ts\";\n\nexport type CssVarsOptions = {\n rootDir: string;\n /** Extensions scanned for var(--x) references. Default: css, ts, tsx. */\n scanExtensions?: string[];\n /** Variables defined dynamically (set via JS). Treated as defined. */\n dynamicVars?: string[];\n /** Directory names skipped during recursion. */\n skipDirs?: string[];\n};\n\nexport async function checkCssVars(options: CssVarsOptions): Promise<CssCheckResult> {\n const rootDir = options.rootDir;\n const scanExts = options.scanExtensions ?? [\".ts\", \".tsx\", \".css\"];\n const dynamic = new Set(options.dynamicVars ?? []);\n const definitions = new Set<string>(dynamic);\n const violations: CssViolation[] = [];\n\n // Pass 1 — collect all CSS custom property definitions\n await walkDirectory(\n rootDir,\n async (full) => {\n if (!full.endsWith(\".css\")) return;\n const content = await Bun.file(full).text();\n for (const m of content.matchAll(/--([\\w-]+)\\s*:/g)) {\n if (m[1]) definitions.add(`--${m[1]}`);\n }\n },\n { rootDir, skipDirs: options.skipDirs }\n );\n\n // Pass 2 — scan var(--name) references\n await walkDirectory(\n rootDir,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: nested for + matchAll per file is linear and readable as written.\n async (full) => {\n if (full.endsWith(\".css.d.ts\")) return;\n if (!scanExts.some((ext) => full.endsWith(ext))) return;\n const content = await Bun.file(full).text();\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (!line) continue;\n for (const m of line.matchAll(/var\\(--([\\w-]+)\\)/g)) {\n const name = `--${m[1]}`;\n if (!definitions.has(name)) {\n violations.push({\n file: full,\n line: i + 1,\n rule: \"undefined-var\",\n content: line.trim(),\n suggestion: `Define ${name} in a CSS file or add to dynamicVars`,\n });\n }\n }\n }\n },\n { rootDir, skipDirs: options.skipDirs }\n );\n\n return makeResult(\"css-vars\", rootDir, violations);\n}\n",
|
|
11
12
|
"/**\n * No-as-casting conformance check.\n *\n * Bans all TypeScript type assertions (`as Type`) except the allowed\n * patterns: `as const` (literal narrowing), `as unknown as` (explicit\n * escape hatch), import/export renames, and `as` inside strings or\n * comments. Violations include pattern-specific fix advice.\n *\n * This module exports the check logic as a library so consuming\n * applications can import it from `@fairfox/polly/quality` and run it\n * programmatically. Polly's own `scripts/check-no-as-casting.ts` is a\n * thin CLI wrapper around these exports.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { Glob } from \"bun\";\nimport { logger } from \"./logger\";\n\nexport interface Violation {\n file: string;\n line: number;\n content: string;\n advice?: string;\n}\n\nexport interface CheckResult {\n violations: Violation[];\n print: () => void;\n}\n\nexport interface CheckOptions {\n rootDir: string;\n exclude?: string[];\n excludePackages?: string[];\n excludeFiles?: string[];\n filePatterns?: string;\n}\n\n/**\n * Check whether a line contains a forbidden `as` type assertion.\n * Returns true if the line is clean (no violation), false if it violates.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Source-text scanning with many skip rules is inherently branchy.\nexport function isLineClean(line: string): boolean {\n if (!line.includes(\" as \")) return true;\n\n const trimmed = line.trim();\n\n // Full-line comments\n if (trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\") || trimmed.startsWith(\"/*\")) {\n return true;\n }\n\n // as const (literal narrowing)\n if (line.match(/\\bas const\\b/)) {\n const withoutAsConst = line.replace(/\\bas const\\b/g, \"\");\n if (!withoutAsConst.includes(\" as \")) return true;\n }\n\n // as unknown as (explicit escape hatch)\n if (line.includes(\" as unknown as \") || line.trimEnd().endsWith(\"as unknown as\")) {\n const withoutEscapeHatch = line.replace(/\\bas unknown as\\b/g, \"\");\n if (!withoutEscapeHatch.includes(\" as \")) return true;\n }\n\n // Import/export renames\n if (\n line.match(/\\b(import|export)\\s+.*\\s+as\\s+\\w+/) ||\n line.match(/\\b(import|export)\\s+\\*\\s+as\\s+\\w+/) ||\n line.match(/\\b(import|export)\\s+type\\s+.*\\s+as\\s+\\w+/) ||\n line.match(/^\\s*\\w+\\s+as\\s+\\w+,?\\s*$/) ||\n line.match(/^\\s*type\\s+\\w+\\s+as\\s+\\w+,?\\s*$/)\n ) {\n return true;\n }\n\n // Property declarations: as= or as: or as,\n if (line.match(/\\bas\\s*[=:,]/)) return true;\n\n // String literal detection: count quotes before each ` as ` occurrence.\n // If any quote type has an odd count, the ` as ` is inside a string.\n if (everyAsInsideString(line)) return true;\n\n // JSX text: ` as ` between > and < with no code syntax around it\n if (isJsxText(trimmed)) return true;\n\n // Plain text heuristic: indented line with no code syntax characters\n // before ` as ` — catches multiline JSX text and template literal bodies.\n if (isPlainText(trimmed)) return true;\n\n // Inline comment: ` as ` appears only after //\n const commentIdx = line.indexOf(\"//\");\n if (commentIdx >= 0 && line.indexOf(\" as \", commentIdx) >= 0) {\n const beforeComment = line.substring(0, commentIdx);\n if (!beforeComment.includes(\" as \")) return true;\n }\n\n // SQL alias: `) as column_name`\n if (line.match(/\"\\)\\s+as\\s+\\w+\"/)) return true;\n\n if (line.includes(\" satisfies \")) return true;\n\n return false;\n}\n\n/**\n * Returns true when every ` as ` occurrence in the line falls inside a\n * string literal (single-quoted, double-quoted, or backtick).\n */\nfunction everyAsInsideString(line: string): boolean {\n let searchFrom = 0;\n while (true) {\n const idx = line.indexOf(\" as \", searchFrom);\n if (idx < 0) return true; // no more ` as ` to check\n const before = line.substring(0, idx);\n const singleQuotes = (before.match(/'/g) ?? []).length;\n const doubleQuotes = (before.match(/\"/g) ?? []).length;\n const backticks = (before.match(/`/g) ?? []).length;\n if (singleQuotes % 2 === 0 && doubleQuotes % 2 === 0 && backticks % 2 === 0) {\n return false; // this ` as ` is outside any string\n }\n searchFrom = idx + 4;\n }\n}\n\n/**\n * Detects JSX text content — ` as ` appearing between > and < with no\n * code-like syntax around it (no braces, semicolons, equals signs).\n */\nfunction isJsxText(trimmed: string): boolean {\n // Classic JSX text: starts after > or is plain text ending before <\n if (trimmed.match(/^[^{};=()]*\\bas\\b[^{};=()]*$/)) {\n // No code syntax at all — could be JSX text or template literal body.\n // Reject if it looks like a type assertion (word ` as ` TypeName pattern\n // where TypeName starts with uppercase, or is a known TS type).\n if (\n !trimmed.match(/\\bas\\s+[A-Z]\\w*/) &&\n !trimmed.match(/\\bas\\s+(string|number|boolean|any|unknown|never)\\b/)\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Heuristic for plain text in template literals or JSX: the line has no\n * code-like characters before ` as ` — no `=`, `{`, `}`, `:`, `;`, `(`.\n */\nfunction isPlainText(trimmed: string): boolean {\n const idx = trimmed.indexOf(\" as \");\n if (idx < 0) return false;\n const before = trimmed.substring(0, idx);\n // If nothing before ` as ` looks like code, it's probably prose.\n return (\n !before.match(/[={}:;(]/) &&\n !before.match(/\\b(const|let|var|type|interface|function|return|await)\\b/)\n );\n}\n\n/**\n * Suggest a concrete fix for a specific violation pattern.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Pattern-matching advice is a linear chain of if-returns.\nexport function suggestFix(line: string): string | undefined {\n if (line.includes(\"JSON.parse\")) {\n return \"Use a validation function or type guard to parse and validate the result.\";\n }\n if (\n line.includes(\"as HTMLInputElement\") ||\n line.includes(\"as HTMLTextAreaElement\") ||\n line.includes(\"as HTMLButtonElement\")\n ) {\n return \"Use instanceof: if (el instanceof HTMLInputElement) { el.value ... }\";\n }\n if (line.includes(\"as HTMLElement\") || line.includes(\"as Element\")) {\n return \"Use instanceof: if (el instanceof HTMLElement) { ... }\";\n }\n if (line.includes(\".doc()\") && line.includes(\"as \")) {\n return \"Type the DocHandle generic: repo.find<MyType>(id) returns DocHandle<MyType>.\";\n }\n if (\n line.includes(\"Record<string, unknown>\") &&\n (line.includes(\"window\") || line.includes(\"globalThis\"))\n ) {\n return \"Extract a type guard: function getGlobalProp(name: string): unknown { ... }\";\n }\n if (line.includes(\"Record<string, unknown>\")) {\n return \"Use a type guard function that narrows the unknown value to the target shape.\";\n }\n if (line.includes(\"as PeerId\") || line.includes(\"as DocumentId\")) {\n return \"Use the library's branded-type constructor if available, or centralise the cast in a factory.\";\n }\n if (line.includes(\"as string\") || line.includes(\"as number\") || line.includes(\"as boolean\")) {\n return \"Narrow with typeof: if (typeof x === 'string') { ... }\";\n }\n if (line.includes(\"as any\")) {\n return \"Replace 'any' with 'unknown' and add a type guard or validation at the boundary.\";\n }\n return undefined;\n}\n\nfunction isFileExcluded(\n relative: string,\n excludeDirs: Set<string>,\n excludePackages: Set<string>,\n excludeFiles: Set<string>\n): boolean {\n const segments = relative.split(\"/\");\n if (segments.some((s) => excludeDirs.has(s))) return true;\n if (excludePackages.size > 0 && segments.some((s) => excludePackages.has(s))) return true;\n const basename = segments[segments.length - 1] ?? \"\";\n return excludeFiles.has(basename) || excludeFiles.has(relative);\n}\n\nfunction findViolations(relative: string, content: string): Violation[] {\n const results: Violation[] = [];\n const lines = content.split(\"\\n\");\n let insideTemplate = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const backticks = (line.match(/`/g) ?? []).length;\n const startedInTemplate = insideTemplate;\n if (backticks % 2 === 1) insideTemplate = !insideTemplate;\n\n // Line is entirely inside a multi-line template literal and has no\n // interpolation — treat as string content (e.g. SQL column aliases).\n if (startedInTemplate && backticks === 0 && !line.includes(\"${\")) continue;\n\n if (!isLineClean(line)) {\n results.push({\n file: relative,\n line: i + 1,\n content: line.trim(),\n advice: suggestFix(line.trim()),\n });\n }\n }\n return results;\n}\n\nfunction printViolations(violations: Violation[]): void {\n if (violations.length === 0) {\n logger.log(\"[no-as-casting] ✅ No violations found.\");\n return;\n }\n logger.log(`[no-as-casting] ❌ ${violations.length} violation(s) found:\\n`);\n for (const v of violations) {\n logger.log(` ${v.file}:${v.line}`);\n logger.log(` ${v.content}`);\n if (v.advice) logger.log(` 💡 ${v.advice}`);\n logger.log(\"\");\n }\n logger.log(\"[no-as-casting] Use type guards, validation, or fix the types at the source.\");\n logger.log('[no-as-casting] Only \"as const\" and \"as unknown as\" are allowed.');\n}\n\n/**\n * Run the no-as-casting check against a directory. Returns a result\n * object with the violations and a print function for CLI output.\n */\nexport async function checkNoAsCasting(options: CheckOptions): Promise<CheckResult> {\n const rootDir = options.rootDir;\n const excludeDirs = new Set(options.exclude ?? [\"node_modules\", \"dist\", \".git\", \".bun\"]);\n const excludePackages = new Set(options.excludePackages ?? []);\n const excludeFiles = new Set(options.excludeFiles ?? []);\n const pattern = options.filePatterns ?? \"**/*.{ts,tsx}\";\n const glob = new Glob(pattern);\n const violations: Violation[] = [];\n\n for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {\n const relative = file.replace(`${rootDir}/`, \"\");\n if (isFileExcluded(relative, excludeDirs, excludePackages, excludeFiles)) continue;\n const content = readFileSync(file, \"utf-8\");\n violations.push(...findViolations(relative, content));\n }\n\n return { violations, print: () => printViolations(violations) };\n}\n"
|
|
12
13
|
],
|
|
13
|
-
"mappings": "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",
|
|
14
|
-
"debugId": "
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "A8CB88D5CE00AC5664756E2164756E21",
|
|
15
16
|
"names": []
|
|
16
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fairfox/polly",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Multi-execution-context framework with reactive state and cross-context messaging for Chrome extensions, PWAs, and worker-based applications",
|