From 6277a40b563ee083551af9c500bfb2846b39eea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Sz=C5=91gy=C3=A9nyi?= Date: Fri, 3 Apr 2026 16:32:31 +0300 Subject: [PATCH] update: remove redundant commands and component families --- DESIGN-SYSTEM-SKILL-BLUEPRINT.md => DESIGN.md | 11 --- README.md | 28 +++++- README.registry-api.md => REGISTRY.md | 0 skills/typeui-cli/SKILL.md | 6 -- src/cli.ts | 28 ------ src/config.ts | 13 --- src/domain/designSystemSchema.ts | 2 - src/generation/existingDesignSystem.ts | 3 - src/licensing/licenseCache.ts | 48 --------- src/licensing/licenseService.ts | 97 ------------------- src/licensing/polarClient.ts | 73 -------------- src/prompts/designSystem.ts | 63 ------------ src/prompts/license.ts | 35 ------- src/renderers/shared.ts | 3 - src/types.ts | 10 -- test/existingDesignSystem.test.ts | 1 - test/licenseCache.test.ts | 25 ----- test/renderers.test.ts | 1 - 18 files changed, 25 insertions(+), 422 deletions(-) rename DESIGN-SYSTEM-SKILL-BLUEPRINT.md => DESIGN.md (96%) rename README.registry-api.md => REGISTRY.md (100%) delete mode 100644 src/licensing/licenseCache.ts delete mode 100644 src/licensing/licenseService.ts delete mode 100644 src/licensing/polarClient.ts delete mode 100644 src/prompts/license.ts delete mode 100644 test/licenseCache.test.ts diff --git a/DESIGN-SYSTEM-SKILL-BLUEPRINT.md b/DESIGN.md similarity index 96% rename from DESIGN-SYSTEM-SKILL-BLUEPRINT.md rename to DESIGN.md index 5271e3e..17fc8f2 100644 --- a/DESIGN-SYSTEM-SKILL-BLUEPRINT.md +++ b/DESIGN.md @@ -42,16 +42,6 @@ One paragraph describing the system objective and target product experience. - Spacing scale: [token list] - Radius/shadow/motion tokens: [if applicable] -## Component Families -- buttons -- inputs -- forms -- navigation -- overlays -- feedback -- data display -- etc. - ## Accessibility - Target: WCAG 2.2 AA - Keyboard-first interactions required @@ -107,7 +97,6 @@ concise, confident, implementation-focused - `[brand-or-scope]` in `name` - System name and mission - Token values (typography, colors, spacing, motion) -- Component family list based on product scope - Any framework-specific implementation notes ## Optional Extensions diff --git a/README.md b/README.md index 826ee36..96280d4 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,6 @@ Check out all [design systems](https://typeui.sh/design-skills) that can be pull | `update` | Update existing managed skill content in generated files. | | `pull ` | Pull a registry skill from `bergside/awesome-design-skills` and write it to selected provider paths. | | `list` | Show available registry specs from `bergside/awesome-design-skills` (with typeui.sh preview links), then pull one automatically. | -| `verify` | Verify your license key (pro version) and cache local license status. | -| `license` | Show local cached license status. | -| `clear-cache` | Remove local cache state (`~/.typeui-sh`). | Shared options for `generate` and `update`: @@ -50,6 +47,31 @@ Shared options for `list`: - `-p, --providers ` (comma-separated providers passed through to auto-pull) - `--dry-run` (preview pull file changes without writing) +## Design Skill File Structure + +Generated files include YAML frontmatter plus a managed content block between: + +- `` +- `` + +Within the managed block, sections are structured like this: + +| Section | What it does | +| --- | --- | +| `Mission` | Defines the design-system objective and expected output quality for the agent. | +| `Brand` | Captures product context and brand direction to anchor decisions. | +| `Style Foundations` | Defines core visual tokens and constraints (visual style, typography, color palette, spacing). | +| `Accessibility` | States accessibility standards and non-negotiable requirements. | +| `Writing Tone` | Sets tone/style for generated guidance language. | +| `Rules: Do` | Lists required implementation practices to follow. | +| `Rules: Don't` | Lists anti-patterns and prohibited behaviors. | +| `Expected Behavior` | Sets expectations for decision-making and trade-off handling. | +| `Guideline Authoring Workflow` | Gives the ordered process the agent should follow when producing guidelines. | +| `Required Output Structure` | Enforces the final response format for consistency and completeness. | +| `Component Rule Expectations` | Defines required interaction/state details in component guidance. | +| `Quality Gates` | Adds validation criteria for clarity, testability, and consistency. | +| `Example Constraint Language` | Standardizes wording strength (`must` vs `should`) and constraint style. | + For local development: ```bash diff --git a/README.registry-api.md b/REGISTRY.md similarity index 100% rename from README.registry-api.md rename to REGISTRY.md diff --git a/skills/typeui-cli/SKILL.md b/skills/typeui-cli/SKILL.md index 1eb082b..75f19d3 100644 --- a/skills/typeui-cli/SKILL.md +++ b/skills/typeui-cli/SKILL.md @@ -37,12 +37,6 @@ Use `typeui.sh` to generate, update, list, and pull design-system skill files fo - Pull a specific registry skill and write it to selected provider paths. - `npx typeui.sh list` - List available registry slugs, show preview links, and pull one selection. -- `npx typeui.sh verify` - - Verify and cache license state for license-aware workflows. -- `npx typeui.sh license` - - Show local cached license summary. -- `npx typeui.sh clear-cache` - - Clear local `~/.typeui-sh` cache state. ## Local Dev Invocation (This Repo) diff --git a/src/cli.ts b/src/cli.ts index cdcad6b..bc0c829 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,11 +1,6 @@ #!/usr/bin/env node import path from "node:path"; import { Command } from "commander"; -import { - clearCachedLicenseState, - getCachedLicenseSummary, - verifyAndCacheLicenseFromPrompt -} from "./licensing/licenseService"; import { promptDesignSystem, promptDesignSystemFields, @@ -184,29 +179,6 @@ program await listLike(options); }); -program - .command("verify") - .description("Verify your license key and cache local license status.") - .action(async () => { - const record = await verifyAndCacheLicenseFromPrompt(); - console.log(`License cached (${record.licenseKeyFingerprint}) until ${record.expiresAt}`); - }); - -program - .command("license") - .description("Show local cached license status.") - .action(async () => { - console.log(await getCachedLicenseSummary()); - }); - -program - .command("clear-cache") - .description("Clear all local typeui.sh cache state.") - .action(async () => { - await clearCachedLicenseState(); - console.log("Cleared local cache state."); - }); - program.parseAsync().catch((error: unknown) => { const message = error instanceof Error ? error.message : String(error); console.error(`typeui.sh error: ${message}`); diff --git a/src/config.ts b/src/config.ts index a263a60..c762bc5 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,24 +1,11 @@ -import path from "node:path"; -import os from "node:os"; - -export const PRODUCT_ID = "typeui.sh"; export const MANAGED_BLOCK_START = ""; export const MANAGED_BLOCK_END = ""; export const API_DOMAIN = "https://www.typeui.sh"; export const GITHUB_REGISTRY_REPO_URL = "https://github.com/bergside/awesome-design-skills"; export const GITHUB_REGISTRY_RAW_BASE_URL = "https://raw.githubusercontent.com/bergside/awesome-design-skills/main"; -export const PRICING_URL = "https://www.typeui.sh/#pricing"; -export const POLAR_VERIFY_URL = `${API_DOMAIN}/api/license/verify`; export const REGISTRY_SPECS_URL = `${GITHUB_REGISTRY_RAW_BASE_URL}/skills/index.json`; -export const LICENSE_CACHE_DIR = path.join(os.homedir(), ".typeui-sh"); -export const LICENSE_CACHE_PATH = path.join(LICENSE_CACHE_DIR, "license.json"); - -export function getPolarVerifyUrl(): string { - return POLAR_VERIFY_URL; -} - export function getRegistryPullUrl(skillPath: string): string { const encodedPath = skillPath .split("/") diff --git a/src/domain/designSystemSchema.ts b/src/domain/designSystemSchema.ts index d4ea585..396fa38 100644 --- a/src/domain/designSystemSchema.ts +++ b/src/domain/designSystemSchema.ts @@ -28,7 +28,6 @@ export const DesignSystemSchema = z.object({ typographyScale: z.string().min(3), colorPalette: z.string().min(3), spacingScale: z.string().min(3), - componentFamilies: z.array(z.string().min(1)).min(1), accessibilityRequirements: z.string().min(3), writingTone: z.string().min(3), doRules: z.array(z.string().min(1)).min(1), @@ -60,7 +59,6 @@ export const FlatDesignSystemPromptSchema = z.object({ typographyScale: z.string().min(3), colorPalette: z.string().min(3), spacingScale: z.string().min(3), - componentFamilies: nonEmptyList, accessibilityRequirements: z.string().min(3), writingTone: z.string().min(3), doRules: nonEmptyList, diff --git a/src/generation/existingDesignSystem.ts b/src/generation/existingDesignSystem.ts index eb6e3da..b180106 100644 --- a/src/generation/existingDesignSystem.ts +++ b/src/generation/existingDesignSystem.ts @@ -78,7 +78,6 @@ export function parseManagedDesignSystem(content: string): DesignSystemInput | n const typographyScale = extractStyleValue(managed, "Typography scale"); const colorPalette = extractStyleValue(managed, "Color palette"); const spacingScale = extractStyleValue(managed, "Spacing scale"); - const componentFamilies = extractListSection(managed, "## Component Families", "## Accessibility"); const accessibilityRequirements = extractSection(managed, "## Accessibility", "## Writing Tone"); const writingTone = extractSection(managed, "## Writing Tone", "## Rules: Do"); const doRules = extractListSection(managed, "## Rules: Do", "## Rules: Don't"); @@ -91,7 +90,6 @@ export function parseManagedDesignSystem(content: string): DesignSystemInput | n !typographyScale || !colorPalette || !spacingScale || - !componentFamilies || !accessibilityRequirements || !writingTone || !doRules || @@ -107,7 +105,6 @@ export function parseManagedDesignSystem(content: string): DesignSystemInput | n typographyScale, colorPalette, spacingScale, - componentFamilies, accessibilityRequirements, writingTone, doRules, diff --git a/src/licensing/licenseCache.ts b/src/licensing/licenseCache.ts deleted file mode 100644 index 6fe50e9..0000000 --- a/src/licensing/licenseCache.ts +++ /dev/null @@ -1,48 +0,0 @@ -import crypto from "node:crypto"; -import fs from "node:fs/promises"; -import { LICENSE_CACHE_DIR, LICENSE_CACHE_PATH, PRODUCT_ID } from "../config"; -import { LicenseCacheRecord } from "../types"; - -export async function readLicenseCache(): Promise { - try { - const raw = await fs.readFile(LICENSE_CACHE_PATH, "utf8"); - const parsed = JSON.parse(raw) as Partial; - if (!parsed.productId || !parsed.expiresAt || !parsed.licenseKeyFingerprint) { - return null; - } - if (parsed.productId !== PRODUCT_ID) { - return null; - } - return { - productId: parsed.productId, - verifiedAt: parsed.verifiedAt ?? new Date().toISOString(), - expiresAt: parsed.expiresAt, - licenseKeyFingerprint: parsed.licenseKeyFingerprint, - licenseKey: typeof parsed.licenseKey === "string" ? parsed.licenseKey : undefined - }; - } catch (error) { - const e = error as NodeJS.ErrnoException; - if (e.code === "ENOENT") { - return null; - } - throw error; - } -} - -export async function writeLicenseCache(record: LicenseCacheRecord): Promise { - await fs.mkdir(LICENSE_CACHE_DIR, { recursive: true }); - await fs.writeFile(LICENSE_CACHE_PATH, JSON.stringify(record, null, 2), "utf8"); -} - -export function isCacheRecordValid(record: LicenseCacheRecord): boolean { - const expires = new Date(record.expiresAt).getTime(); - return Number.isFinite(expires) && expires > Date.now(); -} - -export function fingerprintToken(token: string): string { - return crypto.createHash("sha256").update(token).digest("hex").slice(0, 16); -} - -export async function clearLocalLicenseState(): Promise { - await fs.rm(LICENSE_CACHE_DIR, { recursive: true, force: true }); -} diff --git a/src/licensing/licenseService.ts b/src/licensing/licenseService.ts deleted file mode 100644 index 83892f5..0000000 --- a/src/licensing/licenseService.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { PRICING_URL, PRODUCT_ID } from "../config"; -import { promptLicenseCredentials } from "../prompts/license"; -import { LicenseCacheRecord } from "../types"; -import { - clearLocalLicenseState, - fingerprintToken, - isCacheRecordValid, - readLicenseCache, - writeLicenseCache -} from "./licenseCache"; -import { verifyPurchaseWithPolar } from "./polarClient"; - -function buildCacheRecord(licenseKey: string, expiresAt: string): LicenseCacheRecord { - return { - productId: PRODUCT_ID, - verifiedAt: new Date().toISOString(), - expiresAt, - licenseKeyFingerprint: fingerprintToken(licenseKey), - licenseKey - }; -} - -function isInvalidLicenseReason(reason: string): boolean { - const normalized = reason.toLowerCase(); - return ( - normalized === "not_found" || - normalized.includes("license_invalid") || - normalized.includes("license key is not valid") || - normalized.includes("invalid license") - ); -} - -function withLicensePurchaseHelp(reason: string): string { - if (!isInvalidLicenseReason(reason)) { - return reason; - } - return `${reason} You can get a license key at ${PRICING_URL}.`; -} - -export async function ensureVerifiedAccess(): Promise { - const cached = await readLicenseCache(); - if (cached && isCacheRecordValid(cached)) { - return; - } - - const { licenseKey } = await promptLicenseCredentials(); - const verifyResult = await verifyPurchaseWithPolar(licenseKey); - - if (!verifyResult.ok) { - throw new Error(`License verification failed: ${withLicensePurchaseHelp(verifyResult.reason)}`); - } - - await writeLicenseCache(buildCacheRecord(licenseKey, verifyResult.expiresAt)); -} - -export async function getVerifiedLicenseKey(): Promise { - const cached = await readLicenseCache(); - if (cached && isCacheRecordValid(cached) && cached.licenseKey) { - return cached.licenseKey; - } - - const { licenseKey } = await promptLicenseCredentials(); - const verifyResult = await verifyPurchaseWithPolar(licenseKey); - - if (!verifyResult.ok) { - throw new Error(`License verification failed: ${withLicensePurchaseHelp(verifyResult.reason)}`); - } - - await writeLicenseCache(buildCacheRecord(licenseKey, verifyResult.expiresAt)); - return licenseKey; -} - -export async function verifyAndCacheLicenseFromPrompt(): Promise { - const { licenseKey } = await promptLicenseCredentials(); - const verifyResult = await verifyPurchaseWithPolar(licenseKey); - - if (!verifyResult.ok) { - throw new Error(`License verification failed: ${withLicensePurchaseHelp(verifyResult.reason)}`); - } - - const cacheRecord = buildCacheRecord(licenseKey, verifyResult.expiresAt); - await writeLicenseCache(cacheRecord); - return cacheRecord; -} - -export async function getCachedLicenseSummary(): Promise { - const cached = await readLicenseCache(); - if (!cached) { - return "No cached license."; - } - const status = isCacheRecordValid(cached) ? "valid" : "expired"; - return `Cached license (${cached.licenseKeyFingerprint}) is ${status} until ${cached.expiresAt}.`; -} - -export async function clearCachedLicenseState(): Promise { - await clearLocalLicenseState(); -} diff --git a/src/licensing/polarClient.ts b/src/licensing/polarClient.ts deleted file mode 100644 index 826e786..0000000 --- a/src/licensing/polarClient.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { getPolarVerifyUrl } from "../config"; - -export interface PolarVerifySuccess { - ok: true; - expiresAt: string; -} - -export interface PolarVerifyFailure { - ok: false; - reason: string; -} - -export type PolarVerifyResult = PolarVerifySuccess | PolarVerifyFailure; - -interface PolarResponseShape { - valid?: boolean; - reason?: string; - status?: string; - expires_at?: string; - expiresAt?: string; - error?: string; -} - -const VERIFY_CACHE_TTL_DAYS = 31; - -export async function verifyPurchaseWithPolar(licenseKey: string): Promise { - const verifyUrl = getPolarVerifyUrl(); - let response: Response; - try { - response = await fetch(verifyUrl, { - method: "POST", - headers: { - "content-type": "application/json" - }, - body: JSON.stringify({ - licenseKey - }) - }); - } catch (error) { - const message = error instanceof Error ? error.message : String(error); - return { - ok: false, - reason: `Could not reach license server at ${verifyUrl}: ${message}. Please ensure your network connection is available and try again.` - }; - } - - if (!response.ok) { - let serverReason: string | undefined; - try { - const errorData = (await response.json()) as PolarResponseShape; - serverReason = errorData.reason || errorData.error; - } catch { - // Ignore JSON parse failures and fall back to status-only message. - } - return { - ok: false, - reason: serverReason - ? `License verification failed (${response.status}): ${serverReason}.` - : `License verification failed (${response.status}).` - }; - } - - const data = (await response.json()) as PolarResponseShape; - if (!data.valid || data.reason !== "active" || data.status !== "granted") { - return { ok: false, reason: data.reason || data.error || "License key is not valid." }; - } - - return { - ok: true, - // Local cache is fixed to 31 days from verification. - expiresAt: new Date(Date.now() + VERIFY_CACHE_TTL_DAYS * 24 * 60 * 60 * 1000).toISOString() - }; -} diff --git a/src/prompts/designSystem.ts b/src/prompts/designSystem.ts index 016e1c0..2c12eca 100644 --- a/src/prompts/designSystem.ts +++ b/src/prompts/designSystem.ts @@ -52,7 +52,6 @@ const designFieldChoices: { name: string; value: DesignSystemField }[] = [ { name: "Typography scale", value: "typographyScale" }, { name: "Color palette", value: "colorPalette" }, { name: "Spacing scale", value: "spacingScale" }, - { name: "Component families", value: "componentFamilies" }, { name: "Accessibility requirements", value: "accessibilityRequirements" }, { name: "Writing tone", value: "writingTone" }, { name: "DO rules", value: "doRules" }, @@ -344,52 +343,6 @@ const SPACING_SCALE_OPTIONS = [ "comfortable density mode" ]; -const COMPONENT_FAMILY_OPTIONS = [ - "buttons", - "inputs", - "forms", - "selects/comboboxes", - "checkboxes/radios/switches", - "textareas", - "date/time pickers", - "file uploaders", - "cards", - "tables", - "data lists", - "data grids", - "charts", - "stats/metrics", - "badges/chips", - "avatars", - "breadcrumbs", - "pagination", - "steppers", - "modals", - "drawers/sheets", - "tooltips", - "popovers/menus", - "navigation", - "sidebars", - "top bars/headers", - "command palette", - "tabs", - "accordions", - "carousels", - "progress indicators", - "skeletons", - "alerts/toasts", - "notifications center", - "search", - "empty states", - "onboarding", - "authentication screens", - "settings pages", - "documentation layouts", - "feedback components", - "pricing blocks", - "data visualization wrappers" -]; - const ACCESSIBILITY_OPTIONS = [ "WCAG 2.2 AA", "keyboard-first interactions", @@ -597,11 +550,6 @@ export async function promptDesignSystem(defaultProductName = "typeui.sh"): Prom presets: SPACING_SCALE_OPTIONS, defaultChoice: "4/8/12/16/24/32" }); - const componentFamilies = await promptPresetSelection({ - message: "Select component families to prioritize:", - presets: COMPONENT_FAMILY_OPTIONS, - defaultSelected: COMPONENT_FAMILY_OPTIONS - }); const accessibilityRequirements = await promptPresetSelection({ message: "Select accessibility requirements:", presets: ACCESSIBILITY_OPTIONS, @@ -638,7 +586,6 @@ export async function promptDesignSystem(defaultProductName = "typeui.sh"): Prom typographyScale, colorPalette, spacingScale, - componentFamilies, accessibilityRequirements: accessibilityRequirements.join(", "), writingTone: writingTone.join(", "), doRules, @@ -720,16 +667,6 @@ export async function promptDesignSystemUpdates( updates.spacingScale = value; break; } - case "componentFamilies": { - const defaults = matchPresetDefaults(current.componentFamilies.join(", "), COMPONENT_FAMILY_OPTIONS); - updates.componentFamilies = await promptPresetSelection({ - message: "Select component families to prioritize:", - presets: COMPONENT_FAMILY_OPTIONS, - defaultSelected: defaults.selected.length > 0 ? defaults.selected : COMPONENT_FAMILY_OPTIONS, - defaultCustom: defaults.custom - }); - break; - } case "accessibilityRequirements": { const defaults = matchPresetDefaults(current.accessibilityRequirements, ACCESSIBILITY_OPTIONS); const values = await promptPresetSelection({ diff --git a/src/prompts/license.ts b/src/prompts/license.ts deleted file mode 100644 index f1f847c..0000000 --- a/src/prompts/license.ts +++ /dev/null @@ -1,35 +0,0 @@ -type InquirerModule = typeof import("inquirer"); - -async function loadInquirer(): Promise { - const dynamicImport = new Function( - "specifier", - "return import(specifier)" - ) as (specifier: string) => Promise; - const inquirerModule = await dynamicImport("inquirer"); - return inquirerModule.default; -} - -async function prompt(questions: unknown): Promise { - const inquirer = await loadInquirer(); - return (await inquirer.prompt(questions as never)) as T; -} - -export interface LicensePromptAnswers { - licenseKey: string; -} - -export async function promptLicenseCredentials(): Promise { - const answers = await prompt([ - { - type: "password", - name: "licenseKey", - message: "License key:", - mask: "*", - validate: (value: string) => value.trim().length > 5 || "License key is required." - } - ]); - - return { - licenseKey: answers.licenseKey.trim() - }; -} diff --git a/src/renderers/shared.ts b/src/renderers/shared.ts index 1a3613a..43875e4 100644 --- a/src/renderers/shared.ts +++ b/src/renderers/shared.ts @@ -24,9 +24,6 @@ export function createManagedSkillBody(providerTitle: string, design: DesignSyst `- Color palette: ${design.colorPalette}`, `- Spacing scale: ${design.spacingScale}`, "", - "## Component Families", - list(design.componentFamilies), - "", "## Accessibility", design.accessibilityRequirements, "", diff --git a/src/types.ts b/src/types.ts index 9aba551..db08f75 100644 --- a/src/types.ts +++ b/src/types.ts @@ -158,7 +158,6 @@ export interface DesignSystemInput { typographyScale: string; colorPalette: string; spacingScale: string; - componentFamilies: string[]; accessibilityRequirements: string; writingTone: string; doRules: string[]; @@ -177,7 +176,6 @@ export const DESIGN_SYSTEM_FIELDS = [ "typographyScale", "colorPalette", "spacingScale", - "componentFamilies", "accessibilityRequirements", "writingTone", "doRules", @@ -191,11 +189,3 @@ export interface ProviderFile { relativePath: string; content: string; } - -export interface LicenseCacheRecord { - productId: string; - verifiedAt: string; - expiresAt: string; - licenseKeyFingerprint: string; - licenseKey?: string; -} diff --git a/test/existingDesignSystem.test.ts b/test/existingDesignSystem.test.ts index 962f90e..3e4bc17 100644 --- a/test/existingDesignSystem.test.ts +++ b/test/existingDesignSystem.test.ts @@ -10,7 +10,6 @@ const sampleDesign: DesignSystemInput = { typographyScale: "12/14/16/20/24/32", colorPalette: "primary, neutral, semantic", spacingScale: "4/8/12/16/24/32", - componentFamilies: ["buttons", "inputs", "cards"], accessibilityRequirements: "WCAG 2.2 AA", writingTone: "clear and direct", doRules: ["use semantic tokens", "preserve hierarchy"], diff --git a/test/licenseCache.test.ts b/test/licenseCache.test.ts deleted file mode 100644 index 9b6fbca..0000000 --- a/test/licenseCache.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { isCacheRecordValid } from "../src/licensing/licenseCache"; - -describe("isCacheRecordValid", () => { - it("returns true for future expiry", () => { - const valid = isCacheRecordValid({ - productId: "typeui.sh", - verifiedAt: new Date().toISOString(), - expiresAt: new Date(Date.now() + 60_000).toISOString(), - licenseKeyFingerprint: "abcd", - licenseKey: "license_valid_123" - }); - expect(valid).toBe(true); - }); - - it("returns false for expired cache", () => { - const valid = isCacheRecordValid({ - productId: "typeui.sh", - verifiedAt: new Date().toISOString(), - expiresAt: new Date(Date.now() - 60_000).toISOString(), - licenseKeyFingerprint: "abcd" - }); - expect(valid).toBe(false); - }); -}); diff --git a/test/renderers.test.ts b/test/renderers.test.ts index adbaa48..b503b50 100644 --- a/test/renderers.test.ts +++ b/test/renderers.test.ts @@ -9,7 +9,6 @@ const sampleDesign: DesignSystemInput = { typographyScale: "12/14/16/20/24/32", colorPalette: "primary, neutral, semantic", spacingScale: "4/8/12/16/24/32", - componentFamilies: ["buttons", "inputs", "cards"], accessibilityRequirements: "WCAG 2.2 AA", writingTone: "clear and direct", doRules: ["use semantic tokens", "preserve hierarchy"],