@ideare/kit 0.0.0-stage → 0.1.0-next.0
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/LICENSE +21 -0
- package/README.md +148 -2
- package/THIRD_PARTY.md +52 -0
- package/dist/brand/schema.d.ts +265 -0
- package/dist/brand/schema.js +271 -0
- package/dist/check/copy.d.ts +27 -0
- package/dist/check/copy.js +139 -0
- package/dist/check/index.d.ts +54 -0
- package/dist/check/index.js +492 -0
- package/dist/color/contrast.d.ts +41 -0
- package/dist/color/contrast.js +84 -0
- package/dist/color/palette.d.ts +27 -0
- package/dist/color/palette.js +114 -0
- package/dist/color/wcag.d.ts +22 -0
- package/dist/color/wcag.js +50 -0
- package/dist/draft/draft.d.ts +61 -0
- package/dist/draft/draft.js +383 -0
- package/dist/editor/history.d.ts +78 -0
- package/dist/editor/history.js +221 -0
- package/dist/editor/operations.d.ts +112 -0
- package/dist/editor/operations.js +621 -0
- package/dist/files/docs.d.ts +49 -0
- package/dist/files/docs.js +392 -0
- package/dist/files/generate.d.ts +47 -0
- package/dist/files/generate.js +254 -0
- package/dist/files/png.d.ts +40 -0
- package/dist/files/png.js +168 -0
- package/dist/files/raster.d.ts +14 -0
- package/dist/files/raster.js +0 -0
- package/dist/files/templates.d.ts +162 -0
- package/dist/files/templates.js +390 -0
- package/dist/files/tokens.d.ts +22 -0
- package/dist/files/tokens.js +204 -0
- package/dist/fonts/catalog.d.ts +3 -0
- package/dist/fonts/catalog.js +345 -0
- package/dist/fonts/ofl.d.ts +5 -0
- package/dist/fonts/ofl.js +5 -0
- package/dist/fonts/pick.d.ts +33 -0
- package/dist/fonts/pick.js +73 -0
- package/dist/imports/folder.d.ts +80 -0
- package/dist/imports/folder.js +124 -0
- package/dist/imports/unzip.d.ts +32 -0
- package/dist/imports/unzip.js +128 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +34 -0
- package/dist/marks/draw.d.ts +48 -0
- package/dist/marks/draw.js +149 -0
- package/dist/marks/icons.data.d.ts +5 -0
- package/dist/marks/icons.data.js +600 -0
- package/dist/marks/svg.d.ts +46 -0
- package/dist/marks/svg.js +341 -0
- package/dist/node/index.d.ts +13 -0
- package/dist/node/index.js +41 -0
- package/dist/posts/pix.d.ts +19 -0
- package/dist/posts/pix.js +49 -0
- package/dist/posts/templates.d.ts +45 -0
- package/dist/posts/templates.js +868 -0
- package/dist/resvg/index.d.ts +2 -0
- package/dist/resvg/index.js +22 -0
- package/dist/scene/brand-art.d.ts +49 -0
- package/dist/scene/brand-art.js +154 -0
- package/dist/scene/frame.d.ts +89 -0
- package/dist/scene/frame.js +213 -0
- package/dist/scene/grain.d.ts +7 -0
- package/dist/scene/grain.js +7 -0
- package/dist/scene/qr.d.ts +10 -0
- package/dist/scene/qr.js +359 -0
- package/dist/scene/render.d.ts +76 -0
- package/dist/scene/render.js +557 -0
- package/dist/scene/schema.d.ts +271 -0
- package/dist/scene/schema.js +257 -0
- package/dist/sign.d.ts +47 -0
- package/dist/sign.js +88 -0
- package/dist/text/engine.d.ts +128 -0
- package/dist/text/engine.js +245 -0
- package/dist/text/fonts.d.ts +56 -0
- package/dist/text/fonts.js +65 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/dist/wasm/index.d.ts +15 -0
- package/dist/wasm/index.js +46 -0
- package/package.json +78 -5
- package/schema/brand.v1.json +442 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gustavo Salomé
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,149 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ideare/kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The engine behind ideare: it reads a brand (`brand.json`) and makes every file the brand needs.
|
|
4
|
+
Icons, logos, share cards, social sizes, tokens, a business card and plain-words guidelines all
|
|
5
|
+
come from one scene engine, so the studio, the CLI and the server draw the same pixels.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { parseBrand } from "@ideare/kit";
|
|
9
|
+
|
|
10
|
+
const result = parseBrand(JSON.parse(text));
|
|
11
|
+
if (!result.ok) console.log(result.issues); // [{ path: "colors.light.ink", message: "Use a 6-digit hex color, like #1A2B3C." }]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Make the files
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { generate } from "@ideare/kit";
|
|
18
|
+
import { diskFontResolver } from "@ideare/kit/node";
|
|
19
|
+
import { resvgRasterizer } from "@ideare/kit/resvg";
|
|
20
|
+
|
|
21
|
+
const files = await generate(brand, { fonts: diskFontResolver(), rasterize: resvgRasterizer() });
|
|
22
|
+
// Map { "web/favicon.ico" => { bytes, mime, sha256, width, height }, "og/og.png" => ..., ... }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`generate()` writes nothing to disk; you decide where the bytes go. Pick groups with
|
|
26
|
+
`targets: ["web", "tokens"]`. The groups are `web`, `logo`, `og`, `social`, `tokens`,
|
|
27
|
+
`registry`, `docs`, `email` and `print`. When text would not fit or a letter is missing from a
|
|
28
|
+
font, it refuses with a `GenerateRefusal` instead of making a cut file.
|
|
29
|
+
|
|
30
|
+
## Check a brand
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { check } from "@ideare/kit";
|
|
34
|
+
|
|
35
|
+
const results = await check(brand, { fonts: diskFontResolver() });
|
|
36
|
+
// [{ id: "contrast.light.muted.surface", level: "error", title: "Quiet text on cards: hard to read. Fix it",
|
|
37
|
+
// fix: { kind: "set", label: "Use #6b5e55", changes: [...] }, details: { ratio: "3.12:1", needed: "4.5:1" } }, ...]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Contrast (WCAG 2), the logo on its icon, 16 px legibility, glyph coverage, text fit in every
|
|
41
|
+
language, safe zones, the copy check (no em dash, no machine-sounding words, sentence case, no
|
|
42
|
+
exclamation marks, lengths) and upload limits.
|
|
43
|
+
|
|
44
|
+
## Draw a scene
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { renderScene } from "@ideare/kit";
|
|
48
|
+
|
|
49
|
+
const { svg, boxes, checks, revision } = await renderScene(scene, brand, { fonts });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Text is shaped with HarfBuzz into glyph paths, so the browser and resvg show the same lines.
|
|
53
|
+
Each layer sits in its own `<g transform="translate(x y) rotate(r w/2 h/2)">`, and a group's
|
|
54
|
+
layers are placed in the group's own space. An editor passes one cache per stage, so a drag frame
|
|
55
|
+
redraws only what changed:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { createRenderCache } from "@ideare/kit";
|
|
59
|
+
|
|
60
|
+
const cache = createRenderCache();
|
|
61
|
+
const { svg } = await renderScene(scene, brand, { fonts, cache }); // the moved layer's transform, the rest from the cache
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Make a post from a template
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { postTemplate } from "@ideare/kit";
|
|
68
|
+
|
|
69
|
+
const scene = postTemplate("promotion", brand); // an Instagram post, in the brand's language
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
There are 7 templates (`POST_TEMPLATES`): `promotion`, `hours`, `menu`, `pix`, `new-product`,
|
|
73
|
+
`status-offer` and `carousel` (5 pages). Each comes in 5 sizes (`POST_FORMATS`): `ig-post`
|
|
74
|
+
1080x1350, `ig-square` 1080x1080, `ig-story` and `wa-status` 1080x1920, and `share-card`
|
|
75
|
+
1200x630. Pass `{ format: "ig-story", locale: "es" }` for another size or language. They use only
|
|
76
|
+
the brand's colors and its two fonts. The words the owner changes are slots (`scene.slots`), and
|
|
77
|
+
the photo spot is an art layer called `photo`.
|
|
78
|
+
|
|
79
|
+
The Pix card needs the owner's Pix key, or its QR code shows a sample key that pays no one:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
postTemplate("pix", brand, { pix: { key: "+5541999990000", city: "Curitiba" } });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`pixCode({ key, name, city, amount })` gives the "copia e cola" code itself.
|
|
86
|
+
|
|
87
|
+
## Edit a scene
|
|
88
|
+
|
|
89
|
+
Every edit is a plain function from a scene to a new scene, with no DOM, so an editor, an agent
|
|
90
|
+
and a test edit the same way. Layers are found by id on a page (page 0 here), and positions are in
|
|
91
|
+
the page's own pixels, even for a layer inside a turned group.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { moveLayers } from "@ideare/kit";
|
|
95
|
+
|
|
96
|
+
const moved = moveLayers(scene, 0, ["title"], 40, 0); // 40 px to the right
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The others: `addLayer`, `removeLayers`, `duplicateLayers`, `resizeLayers` (any corner or side,
|
|
100
|
+
the opposite one held still), `rotateLayers`, `groupLayers`, `ungroupLayers`, `reorderLayers`,
|
|
101
|
+
`alignLayers`, `distributeLayers`, `lockLayers`, `setTextHeight`, and `addPage`, `duplicatePage`,
|
|
102
|
+
`removePage` and `movePage` for carousels. For a drag, compute each frame from the scene at the
|
|
103
|
+
press, never from the last frame. `snapTargets` and `snapBox` snap within 12 screen pixels at the
|
|
104
|
+
stage's scale, and `turnAngle` lands a turn on 45 degrees, or in 15 degree steps.
|
|
105
|
+
|
|
106
|
+
Undo keeps 50 steps, and a typing session is one step when its edits share a group:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { emptyHistory, recordEdit, undoEdit } from "@ideare/kit";
|
|
110
|
+
|
|
111
|
+
let history = recordEdit(emptyHistory(), before, after, "typing:title");
|
|
112
|
+
const back = undoEdit(history, after); // { history, scene }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
When a save comes back with someone else's change, `mergeScenes(mine, base, theirs)` brings it in
|
|
116
|
+
and lists the fields you both changed, and `rebaseHistory` keeps Undo for everything they didn't.
|
|
117
|
+
|
|
118
|
+
## Start from a name
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { draftBrand, newDraftSeed } from "@ideare/kit";
|
|
122
|
+
|
|
123
|
+
const brand = await draftBrand(
|
|
124
|
+
{ name: "Padaria Fermento", idea: "Pão de fermentação natural", locale: "pt-BR",
|
|
125
|
+
seed: newDraftSeed(), picks: { colors: 0, fonts: 0, logo: 0 } },
|
|
126
|
+
{ fonts },
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
A whole draft brand from a name and one line, drawn by code: colors, a font pair, a logo (an icon
|
|
131
|
+
or a monogram) and the copy. The same input always draws the same brand, so `draftParams(input)`
|
|
132
|
+
puts it in a link and `readDraftParams(params)` reads it back anywhere. Each `picks` count is one
|
|
133
|
+
"Try another" press. The font pairs are a short list (`draftFontFiles()` names every file), so a
|
|
134
|
+
page can serve them itself.
|
|
135
|
+
|
|
136
|
+
## Where it runs
|
|
137
|
+
|
|
138
|
+
- The core (`@ideare/kit`) runs in browsers, Node 20.3+, Bun and Workers. It loads the HarfBuzz
|
|
139
|
+
wasm only when it first draws text. A bundler must keep `harfbuzz.wasm` next to `harfbuzz.js`,
|
|
140
|
+
and a page's CSP needs `'wasm-unsafe-eval'`.
|
|
141
|
+
- `@ideare/kit/node`: a font cache on disk (`~/.cache/ideare/fonts`).
|
|
142
|
+
- `@ideare/kit/resvg`: the rasterizer, on `@resvg/resvg-js` 2.6.2 (an optional peer).
|
|
143
|
+
- `@ideare/kit/wasm`: the same rasterizer built to wasm, on `@resvg/resvg-wasm` 2.6.2 (an
|
|
144
|
+
optional peer), for browsers and for tools that must install nothing native. Pass it the
|
|
145
|
+
wasm: `wasmRasterizer({ wasm: readFile(require.resolve("@resvg/resvg-wasm/index_bg.wasm")) })`
|
|
146
|
+
in Node, or a URL in the browser. It draws the same pixels as `@ideare/kit/resvg`.
|
|
147
|
+
- Under Bun, the `bun` export condition loads the TypeScript source, with no build step.
|
|
148
|
+
|
|
149
|
+
MIT. Lucide icons (ISC) and a QR encoder port (MIT) are inside; see `THIRD_PARTY.md`.
|
package/THIRD_PARTY.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Third-party code and data in @ideare/kit
|
|
2
|
+
|
|
3
|
+
## Lucide icons (`src/marks/icons.data.ts`)
|
|
4
|
+
|
|
5
|
+
The kit carries the markup of a curated set of Lucide icons (lucide-static 1.68.0), drawn as
|
|
6
|
+
icon marks and on highlight covers.
|
|
7
|
+
|
|
8
|
+
ISC License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Lucide Icons and Contributors
|
|
11
|
+
|
|
12
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without
|
|
13
|
+
fee is hereby granted, provided that the above copyright notice and this permission notice appear
|
|
14
|
+
in all copies.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
17
|
+
SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
19
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
20
|
+
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
21
|
+
OF THIS SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Some Lucide icons are derived from Feather (MIT License, Copyright (c) 2013-present Cole Bemis).
|
|
24
|
+
|
|
25
|
+
## QR Code generator (`src/scene/qr.ts`)
|
|
26
|
+
|
|
27
|
+
Ported from Project Nayuki's QR Code generator library.
|
|
28
|
+
|
|
29
|
+
MIT License
|
|
30
|
+
|
|
31
|
+
Copyright (c) Project Nayuki. (MIT License) https://www.nayuki.io/page/qr-code-generator-library
|
|
32
|
+
|
|
33
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
34
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
35
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
36
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
37
|
+
furnished to do so, subject to the following conditions:
|
|
38
|
+
|
|
39
|
+
- The above copyright notice and this permission notice shall be included in all copies or
|
|
40
|
+
substantial portions of the Software.
|
|
41
|
+
- The Software is provided "as is", without warranty of any kind, express or implied, including
|
|
42
|
+
but not limited to the warranties of merchantability, fitness for a particular purpose and
|
|
43
|
+
noninfringement. In no event shall the authors or copyright holders be liable for any claim,
|
|
44
|
+
damages or other liability, whether in an action of contract, tort or otherwise, arising from,
|
|
45
|
+
out of or in connection with the Software or the use or other dealings in the Software.
|
|
46
|
+
|
|
47
|
+
## Fonts
|
|
48
|
+
|
|
49
|
+
The kit ships no font. It downloads static files from Fontsource at run time, and every font in
|
|
50
|
+
its catalog is under the SIL Open Font License 1.1, whose text the kit writes next to the font
|
|
51
|
+
files it hands out (`OFL.txt`). The two fonts in `test/fonts` are used by the tests only; their
|
|
52
|
+
notices are in `test/fonts/OFL.txt`.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* brand.json v1, the masters. Everything else (icons, cards, tokens, brand.md) is derived from
|
|
4
|
+
* this file by `generate()`, so a field belongs here only when a person chooses it. The kit
|
|
5
|
+
* outlines the wordmark and draws every file; neither is stored.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BRAND_SCHEMA_VERSION = 1;
|
|
8
|
+
export declare const BRAND_SCHEMA_URL = "https://ideare.app/schema/brand.v1.json";
|
|
9
|
+
/** The languages a brand can write its copy in. Widening this list is not a breaking change. */
|
|
10
|
+
export declare const LOCALES: readonly ["pt-BR", "en", "es"];
|
|
11
|
+
export type Locale = (typeof LOCALES)[number];
|
|
12
|
+
/** Every color role, in the order tokens and brand.md list them. */
|
|
13
|
+
export declare const COLOR_ROLES: readonly ["ground", "surface", "ink", "muted", "line", "primary", "onPrimary", "accent", "onAccent", "focus", "danger", "success", "warning"];
|
|
14
|
+
export type ColorRole = (typeof COLOR_ROLES)[number];
|
|
15
|
+
export declare const FONT_ROLES: readonly ["display", "text"];
|
|
16
|
+
export type FontRole = (typeof FONT_ROLES)[number];
|
|
17
|
+
/** The links a brand can list. `site` is a URL, the socials are handles, whatsapp is E.164. */
|
|
18
|
+
export declare const LINK_KINDS: readonly ["site", "instagram", "facebook", "x", "linkedin", "youtube", "tiktok", "whatsapp", "email", "phone"];
|
|
19
|
+
export type LinkKind = (typeof LINK_KINDS)[number];
|
|
20
|
+
/** The links that reach a person. ideare publishes them only when the owner shares contacts. */
|
|
21
|
+
export declare const CONTACT_LINK_KINDS: ["whatsapp", "email", "phone"];
|
|
22
|
+
declare const copySchema: z.ZodObject<{
|
|
23
|
+
tagline: z.ZodString;
|
|
24
|
+
description: z.ZodString;
|
|
25
|
+
card: z.ZodObject<{
|
|
26
|
+
title: z.ZodString;
|
|
27
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export declare const brandSchema: z.ZodObject<{
|
|
31
|
+
$schema: z.ZodDefault<z.ZodLiteral<"https://ideare.app/schema/brand.v1.json">>;
|
|
32
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
33
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
34
|
+
version: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
name: z.ZodString;
|
|
36
|
+
shortName: z.ZodString;
|
|
37
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
38
|
+
locales: z.ZodArray<z.ZodEnum<{
|
|
39
|
+
"pt-BR": "pt-BR";
|
|
40
|
+
en: "en";
|
|
41
|
+
es: "es";
|
|
42
|
+
}>>;
|
|
43
|
+
defaultLocale: z.ZodEnum<{
|
|
44
|
+
"pt-BR": "pt-BR";
|
|
45
|
+
en: "en";
|
|
46
|
+
es: "es";
|
|
47
|
+
}>;
|
|
48
|
+
copy: z.ZodRecord<z.ZodEnum<{
|
|
49
|
+
"pt-BR": "pt-BR";
|
|
50
|
+
en: "en";
|
|
51
|
+
es: "es";
|
|
52
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
53
|
+
tagline: z.ZodString;
|
|
54
|
+
description: z.ZodString;
|
|
55
|
+
card: z.ZodObject<{
|
|
56
|
+
title: z.ZodString;
|
|
57
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
}, z.core.$strip>>;
|
|
60
|
+
voice: z.ZodPrefault<z.ZodObject<{
|
|
61
|
+
tone: z.ZodArray<z.ZodString>;
|
|
62
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
63
|
+
notesPublic: z.ZodDefault<z.ZodBoolean>;
|
|
64
|
+
neverSay: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
65
|
+
examples: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
66
|
+
context: z.ZodString;
|
|
67
|
+
text: z.ZodString;
|
|
68
|
+
}, z.core.$strip>>>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
mark: z.ZodObject<{
|
|
71
|
+
svg: z.ZodString;
|
|
72
|
+
small: z.ZodOptional<z.ZodString>;
|
|
73
|
+
dark: z.ZodOptional<z.ZodString>;
|
|
74
|
+
lockups: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
horizontal: z.ZodOptional<z.ZodString>;
|
|
76
|
+
stacked: z.ZodOptional<z.ZodString>;
|
|
77
|
+
wordmark: z.ZodOptional<z.ZodString>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
tile: z.ZodPrefault<z.ZodObject<{
|
|
80
|
+
fill: z.ZodDefault<z.ZodEnum<{
|
|
81
|
+
ground: "ground";
|
|
82
|
+
surface: "surface";
|
|
83
|
+
ink: "ink";
|
|
84
|
+
muted: "muted";
|
|
85
|
+
line: "line";
|
|
86
|
+
primary: "primary";
|
|
87
|
+
onPrimary: "onPrimary";
|
|
88
|
+
accent: "accent";
|
|
89
|
+
onAccent: "onAccent";
|
|
90
|
+
focus: "focus";
|
|
91
|
+
danger: "danger";
|
|
92
|
+
success: "success";
|
|
93
|
+
warning: "warning";
|
|
94
|
+
}>>;
|
|
95
|
+
shape: z.ZodDefault<z.ZodEnum<{
|
|
96
|
+
square: "square";
|
|
97
|
+
rounded: "rounded";
|
|
98
|
+
circle: "circle";
|
|
99
|
+
}>>;
|
|
100
|
+
radius: z.ZodDefault<z.ZodNumber>;
|
|
101
|
+
padding: z.ZodDefault<z.ZodNumber>;
|
|
102
|
+
}, z.core.$strip>>;
|
|
103
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
104
|
+
kind: z.ZodEnum<{
|
|
105
|
+
monogram: "monogram";
|
|
106
|
+
icon: "icon";
|
|
107
|
+
ai: "ai";
|
|
108
|
+
upload: "upload";
|
|
109
|
+
}>;
|
|
110
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
111
|
+
}, z.core.$strip>>;
|
|
112
|
+
}, z.core.$strip>;
|
|
113
|
+
wordmark: z.ZodObject<{
|
|
114
|
+
text: z.ZodString;
|
|
115
|
+
font: z.ZodDefault<z.ZodEnum<{
|
|
116
|
+
display: "display";
|
|
117
|
+
text: "text";
|
|
118
|
+
}>>;
|
|
119
|
+
weight: z.ZodDefault<z.ZodNumber>;
|
|
120
|
+
tracking: z.ZodDefault<z.ZodNumber>;
|
|
121
|
+
}, z.core.$strip>;
|
|
122
|
+
colors: z.ZodObject<{
|
|
123
|
+
light: z.ZodObject<{
|
|
124
|
+
ground: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
125
|
+
surface: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
126
|
+
ink: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
127
|
+
muted: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
128
|
+
line: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
129
|
+
primary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
130
|
+
onPrimary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
131
|
+
accent: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
132
|
+
onAccent: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
133
|
+
focus: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
134
|
+
danger: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
135
|
+
success: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
136
|
+
warning: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
dark: z.ZodObject<{
|
|
139
|
+
ground: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
140
|
+
surface: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
141
|
+
ink: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
142
|
+
muted: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
143
|
+
line: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
144
|
+
primary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
145
|
+
onPrimary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
146
|
+
accent: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
147
|
+
onAccent: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
148
|
+
focus: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
149
|
+
danger: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
150
|
+
success: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
151
|
+
warning: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
152
|
+
}, z.core.$strip>;
|
|
153
|
+
}, z.core.$strip>;
|
|
154
|
+
paints: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
155
|
+
fonts: z.ZodObject<{
|
|
156
|
+
display: z.ZodObject<{
|
|
157
|
+
family: z.ZodString;
|
|
158
|
+
id: z.ZodString;
|
|
159
|
+
weights: z.ZodArray<z.ZodNumber>;
|
|
160
|
+
license: z.ZodEnum<{
|
|
161
|
+
"OFL-1.1": "OFL-1.1";
|
|
162
|
+
"Apache-2.0": "Apache-2.0";
|
|
163
|
+
}>;
|
|
164
|
+
files: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
text: z.ZodObject<{
|
|
167
|
+
family: z.ZodString;
|
|
168
|
+
id: z.ZodString;
|
|
169
|
+
weights: z.ZodArray<z.ZodNumber>;
|
|
170
|
+
license: z.ZodEnum<{
|
|
171
|
+
"OFL-1.1": "OFL-1.1";
|
|
172
|
+
"Apache-2.0": "Apache-2.0";
|
|
173
|
+
}>;
|
|
174
|
+
files: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
175
|
+
}, z.core.$strip>;
|
|
176
|
+
}, z.core.$strip>;
|
|
177
|
+
radii: z.ZodPrefault<z.ZodObject<{
|
|
178
|
+
control: z.ZodDefault<z.ZodNumber>;
|
|
179
|
+
card: z.ZodDefault<z.ZodNumber>;
|
|
180
|
+
}, z.core.$strip>>;
|
|
181
|
+
art: z.ZodPrefault<z.ZodObject<{
|
|
182
|
+
prompt: z.ZodDefault<z.ZodString>;
|
|
183
|
+
references: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
184
|
+
sha256: z.ZodString;
|
|
185
|
+
mime: z.ZodEnum<{
|
|
186
|
+
"image/png": "image/png";
|
|
187
|
+
"image/jpeg": "image/jpeg";
|
|
188
|
+
"image/webp": "image/webp";
|
|
189
|
+
}>;
|
|
190
|
+
width: z.ZodNumber;
|
|
191
|
+
height: z.ZodNumber;
|
|
192
|
+
}, z.core.$strip>>>;
|
|
193
|
+
referencesPublic: z.ZodDefault<z.ZodBoolean>;
|
|
194
|
+
avoid: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
195
|
+
}, z.core.$strip>>;
|
|
196
|
+
links: z.ZodDefault<z.ZodObject<{
|
|
197
|
+
site: z.ZodOptional<z.ZodObject<{
|
|
198
|
+
value: z.ZodString;
|
|
199
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
200
|
+
}, z.core.$strip>>;
|
|
201
|
+
instagram: z.ZodOptional<z.ZodObject<{
|
|
202
|
+
value: z.ZodString;
|
|
203
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
204
|
+
}, z.core.$strip>>;
|
|
205
|
+
facebook: z.ZodOptional<z.ZodObject<{
|
|
206
|
+
value: z.ZodString;
|
|
207
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
208
|
+
}, z.core.$strip>>;
|
|
209
|
+
x: z.ZodOptional<z.ZodObject<{
|
|
210
|
+
value: z.ZodString;
|
|
211
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
212
|
+
}, z.core.$strip>>;
|
|
213
|
+
linkedin: z.ZodOptional<z.ZodObject<{
|
|
214
|
+
value: z.ZodString;
|
|
215
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
216
|
+
}, z.core.$strip>>;
|
|
217
|
+
youtube: z.ZodOptional<z.ZodObject<{
|
|
218
|
+
value: z.ZodString;
|
|
219
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
220
|
+
}, z.core.$strip>>;
|
|
221
|
+
tiktok: z.ZodOptional<z.ZodObject<{
|
|
222
|
+
value: z.ZodString;
|
|
223
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
224
|
+
}, z.core.$strip>>;
|
|
225
|
+
whatsapp: z.ZodOptional<z.ZodObject<{
|
|
226
|
+
value: z.ZodString;
|
|
227
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
228
|
+
}, z.core.$strip>>;
|
|
229
|
+
email: z.ZodOptional<z.ZodObject<{
|
|
230
|
+
value: z.ZodString;
|
|
231
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
232
|
+
}, z.core.$strip>>;
|
|
233
|
+
phone: z.ZodOptional<z.ZodObject<{
|
|
234
|
+
value: z.ZodString;
|
|
235
|
+
public: z.ZodDefault<z.ZodBoolean>;
|
|
236
|
+
}, z.core.$strip>>;
|
|
237
|
+
}, z.core.$strip>>;
|
|
238
|
+
}, z.core.$strip>;
|
|
239
|
+
/** A parsed brand, with every default filled in. */
|
|
240
|
+
export type Brand = z.output<typeof brandSchema>;
|
|
241
|
+
/** What a person may write in brand.json: defaults may be left out. */
|
|
242
|
+
export type BrandInput = z.input<typeof brandSchema>;
|
|
243
|
+
export type Palette = Brand["colors"]["light"];
|
|
244
|
+
export type BrandFont = Brand["fonts"]["display"];
|
|
245
|
+
export type BrandCopy = z.output<typeof copySchema>;
|
|
246
|
+
export type BrandIssue = {
|
|
247
|
+
path: string;
|
|
248
|
+
message: string;
|
|
249
|
+
};
|
|
250
|
+
export type ParseBrandResult = {
|
|
251
|
+
ok: true;
|
|
252
|
+
brand: Brand;
|
|
253
|
+
} | {
|
|
254
|
+
ok: false;
|
|
255
|
+
reason: "newer" | "invalid";
|
|
256
|
+
issues: BrandIssue[];
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Read a brand.json. A file from a newer kit is refused with "Update ideare" instead of being
|
|
260
|
+
* half-read, so a CLI never writes files from a format it does not know.
|
|
261
|
+
*/
|
|
262
|
+
export declare function parseBrand(input: unknown): ParseBrandResult;
|
|
263
|
+
/** The JSON Schema for editors and outside tools, generated from the zod schema. */
|
|
264
|
+
export declare function brandJsonSchema(): Record<string, unknown>;
|
|
265
|
+
export {};
|