@clay-design-system/email 0.2.4 → 0.3.1
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/MIGRATION.md +31 -0
- package/README.md +7 -0
- package/dist/build/catalog.d.ts +0 -1
- package/dist/generated/email-tokens.d.ts +0 -1
- package/dist/generated/email-tokens.js +0 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/package.json +14 -5
- package/dist/build/asset-scoring.d.ts +0 -48
- package/dist/build/asset-scoring.d.ts.map +0 -1
- package/dist/build/asset-scoring.js +0 -58
- package/dist/build/asset-scoring.js.map +0 -1
- package/dist/build/braze-transform.d.ts +0 -20
- package/dist/build/braze-transform.d.ts.map +0 -1
- package/dist/build/braze-transform.js +0 -26
- package/dist/build/braze-transform.js.map +0 -1
- package/dist/build/catalog.d.ts.map +0 -1
- package/dist/build/catalog.js +0 -3
- package/dist/build/catalog.js.map +0 -1
- package/dist/build/cloudinary-env.d.ts +0 -15
- package/dist/build/cloudinary-env.d.ts.map +0 -1
- package/dist/build/cloudinary-env.js +0 -36
- package/dist/build/cloudinary-env.js.map +0 -1
- package/dist/build/cloudinary-manifest.d.ts +0 -33
- package/dist/build/cloudinary-manifest.d.ts.map +0 -1
- package/dist/build/cloudinary-manifest.js +0 -36
- package/dist/build/cloudinary-manifest.js.map +0 -1
- package/dist/build/compile.d.ts +0 -11
- package/dist/build/compile.d.ts.map +0 -1
- package/dist/build/compile.js +0 -234
- package/dist/build/compile.js.map +0 -1
- package/dist/build/email-config.d.ts +0 -26
- package/dist/build/email-config.d.ts.map +0 -1
- package/dist/build/email-config.js +0 -17
- package/dist/build/email-config.js.map +0 -1
- package/dist/build/email-list.d.ts +0 -6
- package/dist/build/email-list.d.ts.map +0 -1
- package/dist/build/email-list.js +0 -17
- package/dist/build/email-list.js.map +0 -1
- package/dist/build/email-tree.d.ts +0 -23
- package/dist/build/email-tree.d.ts.map +0 -1
- package/dist/build/email-tree.js +0 -46
- package/dist/build/email-tree.js.map +0 -1
- package/dist/build/export-braze.d.ts +0 -22
- package/dist/build/export-braze.d.ts.map +0 -1
- package/dist/build/export-braze.js +0 -92
- package/dist/build/export-braze.js.map +0 -1
- package/dist/build/generate-stock-library-map.d.ts +0 -13
- package/dist/build/generate-stock-library-map.d.ts.map +0 -1
- package/dist/build/generate-stock-library-map.js +0 -202
- package/dist/build/generate-stock-library-map.js.map +0 -1
- package/dist/build/icon-registry-map.d.ts +0 -34
- package/dist/build/icon-registry-map.d.ts.map +0 -1
- package/dist/build/icon-registry-map.js +0 -44
- package/dist/build/icon-registry-map.js.map +0 -1
- package/dist/build/import-examples.d.ts +0 -14
- package/dist/build/import-examples.d.ts.map +0 -1
- package/dist/build/import-examples.js +0 -65
- package/dist/build/import-examples.js.map +0 -1
- package/dist/build/persona-character-map.d.ts +0 -32
- package/dist/build/persona-character-map.d.ts.map +0 -1
- package/dist/build/persona-character-map.js +0 -90
- package/dist/build/persona-character-map.js.map +0 -1
- package/dist/build/placeholder.d.ts +0 -79
- package/dist/build/placeholder.d.ts.map +0 -1
- package/dist/build/placeholder.js +0 -148
- package/dist/build/placeholder.js.map +0 -1
- package/dist/build/stock-library-map.d.ts +0 -57
- package/dist/build/stock-library-map.d.ts.map +0 -1
- package/dist/build/stock-library-map.js +0 -1261
- package/dist/build/stock-library-map.js.map +0 -1
- package/dist/build/upload-assets.d.ts +0 -20
- package/dist/build/upload-assets.d.ts.map +0 -1
- package/dist/build/upload-assets.js +0 -153
- package/dist/build/upload-assets.js.map +0 -1
- package/dist/build/upload-library-assets.d.ts +0 -21
- package/dist/build/upload-library-assets.d.ts.map +0 -1
- package/dist/build/upload-library-assets.js +0 -182
- package/dist/build/upload-library-assets.js.map +0 -1
- package/dist/build/visual-resolver.d.ts +0 -87
- package/dist/build/visual-resolver.d.ts.map +0 -1
- package/dist/build/visual-resolver.js +0 -439
- package/dist/build/visual-resolver.js.map +0 -1
- package/dist/examples/manifest.d.ts +0 -21
- package/dist/examples/manifest.d.ts.map +0 -1
- package/dist/examples/manifest.js +0 -84
- package/dist/examples/manifest.js.map +0 -1
- package/dist/exports/contact-sales/Images/Contact_sales_Image_16f4175c-d08c-43f6-9d4c-a0606383271d.png +0 -0
- package/dist/exports/contact-sales/Images/Contact_sales_Image_659b3091-1da9-40c2-86b0-04250982e529.png +0 -0
- package/dist/exports/contact-sales/Images/Contact_sales_Image_79c651f4-5f0f-4a7f-8354-1f6f95ae86d9.png +0 -0
- package/dist/exports/contact-sales/index.braze.html +0 -837
- package/dist/exports/contact-sales/index.html +0 -837
- package/dist/exports/event-confirmation/Images/Confirmation_Image_11938de2-4161-4ae8-8969-90ea0d8b45cb.png +0 -0
- package/dist/exports/event-confirmation/Images/Confirmation_Image_3c52e81f-5d4f-452c-bad1-0471a27598f1.png +0 -0
- package/dist/exports/event-confirmation/Images/Confirmation_Image_3ec1fec8-bf46-4068-8835-633567a715f9.png +0 -0
- package/dist/exports/event-confirmation/Images/Confirmation_Image_c4980c01-c270-4384-a56c-0bae74814cf9.png +0 -0
- package/dist/exports/event-confirmation/Images/Confirmation_Image_cde93e8c-0f96-434d-acaf-1b86503c66f0.png +0 -0
- package/dist/exports/event-confirmation/index.braze.html +0 -1055
- package/dist/exports/event-confirmation/index.html +0 -1055
- package/dist/exports/legal-update/Images/v2_Image_07bbcc13-0ab8-46e4-ab94-98f215f85f69.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_34394d50-acdf-4375-b254-eef1f84aaacb.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_4a25f2bd-6270-439b-86c5-4a968a1b104f.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_7e8e814f-3112-4d8c-af5b-4f4616d84d9c.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_b24a04c8-4af0-42a1-be0f-cd3f66595e47.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_b709b9fb-836e-4c20-82e5-a9cb9d702392.png +0 -0
- package/dist/exports/legal-update/Images/v2_Image_ed7b924b-35e6-4536-be0c-92ddc8a34fc2.png +0 -0
- package/dist/exports/legal-update/index.braze.html +0 -1731
- package/dist/exports/legal-update/index.html +0 -1731
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_09be22f6-1f30-4c58-bf33-1df0494b8fc2.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_2dfb595e-6fe2-4e6e-a73a-942a085b38ab.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_544c971b-b4b5-4c89-a25a-8f0d92644009.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_5b6a9576-1c33-40c5-81e3-637514fb6c78.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_680c6193-793a-4a24-8288-4bb4046f4f5e.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_75818ba9-026a-45d7-91e4-f992d4ee7690.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_785f18e6-816d-44d1-8efb-ecc82510b540.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_8bf9141d-9d63-4601-9e81-5c9d726e17f8.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_9097d6e0-65d0-4237-9661-963751812786.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_a4ef2f53-2eaf-438a-bfef-61455ac0915e.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_b7748f87-a7b7-4a91-981a-16567683e4b4.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_bc9830a4-2911-4768-808a-32cbbc39215e.png +0 -0
- package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_ef0e8e92-9075-43a9-991f-09a77ef6d6d4.png +0 -0
- package/dist/exports/newsletter/index.braze.html +0 -125
- package/dist/exports/newsletter/index.html +0 -125
- package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-blocks.png +0 -0
- package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-hero-mcp.png +0 -0
- package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-magic.png +0 -0
- package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-mcp.png +0 -0
- package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-portfolio.png +0 -0
- package/dist/exports/newsletter-ai-june-july/index.braze.html +0 -1640
- package/dist/exports/newsletter-ai-june-july/index.html +0 -1640
- package/dist/exports/survey/Images/EmailLove_Image_3b6f4a6f-7f5f-418b-be71-9371b25c20ce.png +0 -0
- package/dist/exports/survey/Images/EmailLove_Image_f659c728-2401-485d-8d90-98c962d28c0c.png +0 -0
- package/dist/exports/survey/index.braze.html +0 -515
- package/dist/exports/survey/index.html +0 -515
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_115ccc58-a47f-4eca-a1f2-c0d86e1e1cf4.png +0 -0
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_aec4d0d3-6057-4b8a-8d8f-46fbd024f182.png +0 -0
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_d139966a-6051-4383-bf8f-1e5138e1b030.png +0 -0
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_080fa361-a3f2-4593-9ac0-03cf3a7972ff.png +0 -0
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_5ebade34-8f1d-4c2c-9d27-5f9e843ce502.png +0 -0
- package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_aa5e4144-9ec8-4525-b01e-077d72f0bab6.png +0 -0
- package/dist/exports/trial-01-welcome/index.braze.html +0 -941
- package/dist/exports/trial-01-welcome/index.html +0 -941
- package/dist/exports/trial-02/Images/tp2_Image_5b0d9bc4-2e38-4252-8f20-d9f27d471c21.png +0 -0
- package/dist/exports/trial-02/Images/tp2_Image_b3f77c7c-cc8e-4db8-a5d9-072f4f621e72.png +0 -0
- package/dist/exports/trial-02/Images/tp2_Image_cafd1a17-1915-47cd-80f2-1c2d0b133cfe.png +0 -0
- package/dist/exports/trial-02/index.braze.html +0 -923
- package/dist/exports/trial-02/index.html +0 -923
- package/dist/exports/trial-03/Images/tp3_Image_1b96630c-fc4d-4aec-91fb-3c1d4d8544b3.png +0 -0
- package/dist/exports/trial-03/Images/tp3_Image_58f3a342-2193-4b5c-b30a-96f7f3338dd8.png +0 -0
- package/dist/exports/trial-03/Images/tp3_Image_6c4f307a-bac2-40e7-b4f1-9aa623c9eb8e.png +0 -0
- package/dist/exports/trial-03/Images/tp3_Image_848917ce-3f89-4538-a826-558b21f5fea7.png +0 -0
- package/dist/exports/trial-03/Images/tp3_Image_aae8410f-556f-4fb9-88f9-f276d75bafd2.png +0 -0
- package/dist/exports/trial-03/Images/tp3_Image_b4d5be39-509e-4f22-9601-dd070e4c6561.png +0 -0
- package/dist/exports/trial-03/index.braze.html +0 -1129
- package/dist/exports/trial-03/index.html +0 -1129
- package/dist/exports/trial-04/Images/tp4_Image_03bd5a56-25e3-4dcc-bef5-143bf12312d5.png +0 -0
- package/dist/exports/trial-04/Images/tp4_Image_0facbfca-b735-4199-a0d9-05a59341a1e3.gif +0 -0
- package/dist/exports/trial-04/Images/tp4_Image_171cee5f-cd3d-42f0-a180-995893d3742a.png +0 -0
- package/dist/exports/trial-04/Images/tp4_Image_3509d89d-1825-4817-8c1e-130fa294d0e1.png +0 -0
- package/dist/exports/trial-04/Images/tp4_Image_763a0f40-2985-4140-859b-ddd34f20a520.png +0 -0
- package/dist/exports/trial-04/Images/tp4_Image_cc2db4f5-b41d-45d7-a798-7a79e7b8d4d8.png +0 -0
- package/dist/exports/trial-04/index.braze.html +0 -885
- package/dist/exports/trial-04/index.html +0 -885
- package/dist/exports/trial-05/Images/tp5_Image_0248a517-5c60-4e84-ad1c-449dcf4f6a64.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_4c1a2d5a-47d3-4801-bb3a-01c22decc108.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_63ae77e7-cec7-4b4a-91e0-603b5a80929f.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_7aa43530-6707-4308-ab0e-e4c38fc1b77d.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_7efe5b6d-b360-4179-bee1-72908ba569bc.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_b142bd84-c40a-4a29-b9d5-715b52fdd937.png +0 -0
- package/dist/exports/trial-05/Images/tp5_Image_c0c896ea-5b68-4f58-9e27-cdb4a1f1b438.png +0 -0
- package/dist/exports/trial-05/index.braze.html +0 -1023
- package/dist/exports/trial-05/index.html +0 -1023
- package/dist/exports/trial-06/Images/tp6_Image_2267a268-8a80-4e0d-8813-d4c75dbab6f2.png +0 -0
- package/dist/exports/trial-06/Images/tp6_Image_637a97b7-837e-478d-8ed1-6e8c2739fdc7.png +0 -0
- package/dist/exports/trial-06/Images/tp6_Image_a78df270-ad6f-41e6-8822-ba8ec38313a3.png +0 -0
- package/dist/exports/trial-06/index.braze.html +0 -773
- package/dist/exports/trial-06/index.html +0 -773
- package/dist/exports/winback/Images/_managers_Image_4587ac22-460c-487a-bc37-9dbc487e95a4.png +0 -0
- package/dist/exports/winback/Images/_managers_Image_8a77ec2c-ed49-480d-a1a1-7a38abad232a.png +0 -0
- package/dist/exports/winback/Images/_managers_Image_bb643775-8a2f-4e28-9dfb-6d1838c3561f.png +0 -0
- package/dist/exports/winback/Images/_managers_Image_f7d1bca5-0fcb-4d4c-abcd-40ce2d453b07.png +0 -0
- package/dist/exports/winback/index.braze.html +0 -605
- package/dist/exports/winback/index.html +0 -605
- package/dist/generated/email-tokens.d.ts.map +0 -1
- package/dist/generated/email-tokens.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tokens/build-email-assets.d.ts +0 -19
- package/dist/tokens/build-email-assets.d.ts.map +0 -1
- package/dist/tokens/build-email-assets.js +0 -186
- package/dist/tokens/build-email-assets.js.map +0 -1
- package/dist/tokens/build-email-tokens.d.ts +0 -17
- package/dist/tokens/build-email-tokens.d.ts.map +0 -1
- package/dist/tokens/build-email-tokens.js +0 -229
- package/dist/tokens/build-email-tokens.js.map +0 -1
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates stock-library-map.ts from stock-library-source.csv (D5.5, board item Clay Lifecycle D5).
|
|
3
|
-
*
|
|
4
|
-
* stock-library-source.csv is the authored source — same "CSV is authored, other artifacts are
|
|
5
|
-
* generated from it, never hand-edit the generated file" convention as the Asset Catalog's own
|
|
6
|
-
* CatalogTest.csv → chips_seed.sql (see .../Assets/Asset Catalog/Table/SCHEMA.md). This script is
|
|
7
|
-
* the equivalent of that repo's `build_seed.py`.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* pnpm --filter @clay-design-system/email library:generate-map
|
|
11
|
-
*/
|
|
12
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
13
|
-
import { dirname, resolve } from 'node:path';
|
|
14
|
-
import { fileURLToPath } from 'node:url';
|
|
15
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
-
const SOURCE_CSV = resolve(__dirname, 'stock-library-source.csv');
|
|
17
|
-
const OUT_TS = resolve(__dirname, 'stock-library-map.ts');
|
|
18
|
-
/** Minimal RFC 4180 parser — handles quoted fields with embedded commas/newlines. Mirrors upload-library-assets.ts. */
|
|
19
|
-
function parseCsv(text) {
|
|
20
|
-
const rows = [];
|
|
21
|
-
let field = '';
|
|
22
|
-
let row = [];
|
|
23
|
-
let inQuotes = false;
|
|
24
|
-
for (let i = 0; i < text.length; i++) {
|
|
25
|
-
const c = text[i];
|
|
26
|
-
if (inQuotes) {
|
|
27
|
-
if (c === '"') {
|
|
28
|
-
if (text[i + 1] === '"') {
|
|
29
|
-
field += '"';
|
|
30
|
-
i++;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
inQuotes = false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
else
|
|
37
|
-
field += c;
|
|
38
|
-
}
|
|
39
|
-
else if (c === '"')
|
|
40
|
-
inQuotes = true;
|
|
41
|
-
else if (c === ',') {
|
|
42
|
-
row.push(field);
|
|
43
|
-
field = '';
|
|
44
|
-
}
|
|
45
|
-
else if (c === '\n') {
|
|
46
|
-
row.push(field);
|
|
47
|
-
rows.push(row);
|
|
48
|
-
row = [];
|
|
49
|
-
field = '';
|
|
50
|
-
}
|
|
51
|
-
else if (c === '\r') { /* skip */ }
|
|
52
|
-
else
|
|
53
|
-
field += c;
|
|
54
|
-
}
|
|
55
|
-
if (field.length || row.length) {
|
|
56
|
-
row.push(field);
|
|
57
|
-
rows.push(row);
|
|
58
|
-
}
|
|
59
|
-
const [header, ...body] = rows.filter((r) => r.length > 1 || r[0] !== '');
|
|
60
|
-
return body.map((r) => Object.fromEntries(header.map((h, idx) => [h, r[idx] ?? ''])));
|
|
61
|
-
}
|
|
62
|
-
const STOPWORDS = new Set(['a', 'an', 'the', 'and', 'or', 'of', 'in', 'on', 'for', 'with', 'to', 'its', 'this']);
|
|
63
|
-
/** Slug words + tag_form/tag_context/use_case_domain — the vocabulary findStockLibraryEntry matches against. */
|
|
64
|
-
function buildTags(row) {
|
|
65
|
-
const slug = row.id.split('/', 2)[1];
|
|
66
|
-
const slugWords = slug.split('-').filter((w) => w.length > 2 && !STOPWORDS.has(w));
|
|
67
|
-
const facets = [row.tag_form, row.tag_context, row.use_case_domain]
|
|
68
|
-
.filter(Boolean)
|
|
69
|
-
.map((t) => t.toLowerCase());
|
|
70
|
-
return [...new Set([...slugWords, ...facets])];
|
|
71
|
-
}
|
|
72
|
-
function tsStringLiteral(s) {
|
|
73
|
-
return `'${s.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, ' ')}'`;
|
|
74
|
-
}
|
|
75
|
-
function main() {
|
|
76
|
-
const rows = parseCsv(readFileSync(SOURCE_CSV, 'utf-8')).filter((r) => r.cloudinary_url);
|
|
77
|
-
const entries = rows.map((r) => {
|
|
78
|
-
const slug = r.id.split('/', 2)[1];
|
|
79
|
-
const tags = buildTags(r);
|
|
80
|
-
return ` {
|
|
81
|
-
id: ${tsStringLiteral(r.id)},
|
|
82
|
-
slug: ${tsStringLiteral(slug)},
|
|
83
|
-
name: ${tsStringLiteral(r.name)},
|
|
84
|
-
description: ${tsStringLiteral(r.description)},
|
|
85
|
-
tags: [${tags.map(tsStringLiteral).join(', ')}],
|
|
86
|
-
tagForm: ${tsStringLiteral(r.tag_form.toLowerCase())},
|
|
87
|
-
tagContext: ${tsStringLiteral(r.tag_context.toLowerCase())},
|
|
88
|
-
useCaseDomain: ${tsStringLiteral(r.use_case_domain)},
|
|
89
|
-
width: ${Number(r.width) || 0},
|
|
90
|
-
height: ${Number(r.height) || 0},
|
|
91
|
-
aspectRatioLabel: ${tsStringLiteral(r.ratio.toLowerCase())},
|
|
92
|
-
localFile: ${tsStringLiteral(r.local_file)},
|
|
93
|
-
cloudinaryUrl: ${tsStringLiteral(r.cloudinary_url)},
|
|
94
|
-
figmaSource: ${tsStringLiteral(r.figma_source)},
|
|
95
|
-
}`;
|
|
96
|
-
});
|
|
97
|
-
const out = `/**
|
|
98
|
-
* GENERATED FILE — do not hand-edit. Regenerate via:
|
|
99
|
-
* pnpm --filter @clay-design-system/email library:generate-map
|
|
100
|
-
* Source: stock-library-source.csv (${rows.length} rows with a live cloudinary_url).
|
|
101
|
-
*
|
|
102
|
-
* The Cloudinary-hosted stock-image library (D5, board item Clay Lifecycle D5.5) — a tier
|
|
103
|
-
* visual-resolver.ts can search when a visual-brief slot's intent names a specific scene this
|
|
104
|
-
* bank already has (e.g. "Agile Dashboard with Kanban view"), before falling to a generic
|
|
105
|
-
* placeholder. Committed as generated TS (not read live from Cloudinary) so
|
|
106
|
-
* visual-resolver.test.ts stays CI-safe without live credentials — same reasoning as
|
|
107
|
-
* persona-character-map.ts.
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
import { containsWord, pickRankedMatch, type RankedMatch, SHAPE_ACCEPTABLE_RATIOS, type SlotShape } from './asset-scoring'
|
|
111
|
-
|
|
112
|
-
export interface StockLibraryEntry {
|
|
113
|
-
/** Catalog id, e.g. "asset/agile-dashboard-overview-hero" — traces back to stock-library-source.csv. */
|
|
114
|
-
id: string
|
|
115
|
-
slug: string
|
|
116
|
-
name: string
|
|
117
|
-
description: string
|
|
118
|
-
/** Slug words + tag_form/tag_context/use_case_domain — the stage-1 content-overlap vocabulary. */
|
|
119
|
-
tags: string[]
|
|
120
|
-
/** Raw tag_form column (e.g. 'card' | 'dashboard' | 'board-view' | 'exchange' | ...) — a stage-2 tie-breaker, independent of tags. */
|
|
121
|
-
tagForm: string
|
|
122
|
-
/** Raw tag_context column (e.g. 'project' | 'campaign' | 'customer' | ...) — a stage-2 tie-breaker, independent of tags. */
|
|
123
|
-
tagContext: string
|
|
124
|
-
useCaseDomain: string
|
|
125
|
-
/** Raw CSV width (px). Traceability + a stage-2 aspect signal via aspectRatioLabel, not scored directly. */
|
|
126
|
-
width: number
|
|
127
|
-
/** Raw CSV height (px). */
|
|
128
|
-
height: number
|
|
129
|
-
/** Raw CSV ratio column, verbatim: 'square' | 'wide' | 'super wide' — the stage-2 aspect-fit signal (see SHAPE_ACCEPTABLE_RATIOS). */
|
|
130
|
-
aspectRatioLabel: string
|
|
131
|
-
/** Raw CSV local_file column. Traceability only, same status as description — never matched against. */
|
|
132
|
-
localFile: string
|
|
133
|
-
/** Live Cloudinary secure_url, lifecycle/library/email-assets/<slug>. */
|
|
134
|
-
cloudinaryUrl: string
|
|
135
|
-
/** Traceability back to the original Figma occurrence. */
|
|
136
|
-
figmaSource: string
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export const STOCK_LIBRARY: StockLibraryEntry[] = [
|
|
140
|
-
${entries.join(',\n')},
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
const KNOWN_DOMAINS = ['marketing', 'sales', 'it', 'pmo', 'hr', 'general', 'operations']
|
|
144
|
-
|
|
145
|
-
/** Unambiguous-or-nothing, same rule as every other fuzzy matcher here — no scoring, no guessing. */
|
|
146
|
-
function extractDomainHint(text: string): string | null {
|
|
147
|
-
const lower = text.toLowerCase()
|
|
148
|
-
const hits = KNOWN_DOMAINS.filter((d) => containsWord(lower, d))
|
|
149
|
-
return hits.length === 1 ? hits[0] : null
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Placeholder weights — aspect is treated as the most structurally reliable secondary signal;
|
|
153
|
-
// tune once real disambiguation behavior has been observed against production briefs.
|
|
154
|
-
const W_ASPECT = 2
|
|
155
|
-
const W_DOMAIN = 1
|
|
156
|
-
const W_FORM = 1
|
|
157
|
-
const W_CONTEXT = 1
|
|
158
|
-
|
|
159
|
-
export interface StockLibraryMatchContext {
|
|
160
|
-
intent: string
|
|
161
|
-
/** Derived automatically by visual-resolver.ts's deriveSlotShape — never hand-authored. */
|
|
162
|
-
shape: SlotShape
|
|
163
|
-
/** Campaign slug, e.g. "sales-agent-activation" — scanned for a domain word alongside intent. */
|
|
164
|
-
campaign?: string
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Stage 1: score each entry by how many of its \`tags\` appear as whole words in \`intent\` — same
|
|
169
|
-
* content-overlap rule as before. Stage 2 (only among entries tied for the max content score):
|
|
170
|
-
* break the tie using aspect-ratio fit for the slot's shape, useCaseDomain, and literal
|
|
171
|
-
* tag_form/tag_context matches — but only if that produces a single, strictly-positive winner.
|
|
172
|
-
* A content tie that's still tied (or all-zero) on every secondary signal stays null, exactly as
|
|
173
|
-
* before this module existed. See asset-scoring.ts's pickRankedMatch for the exact two-stage rule.
|
|
174
|
-
*/
|
|
175
|
-
export function findStockLibraryEntry(ctx: StockLibraryMatchContext): RankedMatch<StockLibraryEntry> | null {
|
|
176
|
-
const lower = ctx.intent.toLowerCase()
|
|
177
|
-
const domainHint = extractDomainHint(ctx.intent) ?? (ctx.campaign ? extractDomainHint(ctx.campaign) : null)
|
|
178
|
-
const acceptableRatios = SHAPE_ACCEPTABLE_RATIOS[ctx.shape]
|
|
179
|
-
|
|
180
|
-
return pickRankedMatch(STOCK_LIBRARY, {
|
|
181
|
-
contentScore: (entry) => entry.tags.filter((tag) => containsWord(lower, tag)).length,
|
|
182
|
-
secondaryScore: (entry) =>
|
|
183
|
-
W_ASPECT * (acceptableRatios.has(entry.aspectRatioLabel) ? 1 : 0) +
|
|
184
|
-
W_DOMAIN * (domainHint !== null && entry.useCaseDomain.toLowerCase() === domainHint ? 1 : 0) +
|
|
185
|
-
W_FORM * (containsWord(lower, entry.tagForm) ? 1 : 0) +
|
|
186
|
-
W_CONTEXT * (containsWord(lower, entry.tagContext) ? 1 : 0),
|
|
187
|
-
explainSecondary: (entry) => {
|
|
188
|
-
const reasons: string[] = []
|
|
189
|
-
if (acceptableRatios.has(entry.aspectRatioLabel)) reasons.push('aspect:' + ctx.shape + '≈' + entry.aspectRatioLabel)
|
|
190
|
-
if (domainHint !== null && entry.useCaseDomain.toLowerCase() === domainHint) reasons.push('domain:' + entry.useCaseDomain)
|
|
191
|
-
if (containsWord(lower, entry.tagForm)) reasons.push('tagForm:' + entry.tagForm)
|
|
192
|
-
if (containsWord(lower, entry.tagContext)) reasons.push('tagContext:' + entry.tagContext)
|
|
193
|
-
return reasons
|
|
194
|
-
},
|
|
195
|
-
})
|
|
196
|
-
}
|
|
197
|
-
`;
|
|
198
|
-
writeFileSync(OUT_TS, out);
|
|
199
|
-
console.log(`Wrote ${entries.length} entries → ${OUT_TS}`);
|
|
200
|
-
}
|
|
201
|
-
main();
|
|
202
|
-
//# sourceMappingURL=generate-stock-library-map.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-stock-library-map.js","sourceRoot":"","sources":["../../src/build/generate-stock-library-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Clay icon registry lookup for visual-resolver.ts tier 6 (D6, board item Clay Lifecycle D6).
|
|
3
|
-
*
|
|
4
|
-
* Reads packages/react/src/icons/icons.json at runtime (name/category/description/tags for all
|
|
5
|
-
* ~600 Clay line icons) rather than importing it as a TS module — packages/email's tsconfig sets
|
|
6
|
-
* rootDir: "src", so a cross-package relative TS import would violate it; a plain JSON file read
|
|
7
|
-
* doesn't, same trick build-email-assets.ts already uses to reach
|
|
8
|
-
* packages/react/src/icons/svg/*.svg for the actual SVG bytes. icons.json is itself generated by
|
|
9
|
-
* the real Clay icon pipeline (scripts/docs/generate-icons.ts) — nothing here is invented.
|
|
10
|
-
*/
|
|
11
|
-
import { type RankedMatch } from './asset-scoring';
|
|
12
|
-
export interface IconRegistryEntry {
|
|
13
|
-
name: string;
|
|
14
|
-
category: string;
|
|
15
|
-
description: string;
|
|
16
|
-
tags: string[];
|
|
17
|
-
/** Present only once scripts/cloudinary/upload-icons-to-cloudinary.ts has uploaded this icon. */
|
|
18
|
-
cloudinarySvgUrl?: string;
|
|
19
|
-
cloudinaryPngUrl?: string;
|
|
20
|
-
}
|
|
21
|
-
export declare const ICON_REGISTRY: IconRegistryEntry[];
|
|
22
|
-
/** Exact name match — for an `icon` slot whose assetRef already names a real Clay icon. */
|
|
23
|
-
export declare function findIconByName(name: string): IconRegistryEntry | null;
|
|
24
|
-
/**
|
|
25
|
-
* Stage 1: score each icon by how many of its tags appear as whole words in `intent` — same
|
|
26
|
-
* content-overlap rule as before. Stage 2 (only among icons tied for the max content score):
|
|
27
|
-
* break the tie by whether the icon's `category` appears as a whole word in `intent` — but only
|
|
28
|
-
* if that produces a single, strictly-positive winner. A generic word like "check" still ties
|
|
29
|
-
* dozens of icons on purpose, and same-category siblings (e.g. home-02/03/05, all "General") still
|
|
30
|
-
* tie on category too — this never guesses between plausible candidates. See asset-scoring.ts's
|
|
31
|
-
* pickRankedMatch for the exact two-stage rule.
|
|
32
|
-
*/
|
|
33
|
-
export declare function findIconEntry(intent: string): RankedMatch<IconRegistryEntry> | null;
|
|
34
|
-
//# sourceMappingURL=icon-registry-map.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icon-registry-map.d.ts","sourceRoot":"","sources":["../../src/build/icon-registry-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAKjF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,iGAAiG;IACjG,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAOD,eAAO,MAAM,aAAa,EAAE,iBAAiB,EAAuB,CAAA;AAEpE,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAErE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAOnF"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Clay icon registry lookup for visual-resolver.ts tier 6 (D6, board item Clay Lifecycle D6).
|
|
3
|
-
*
|
|
4
|
-
* Reads packages/react/src/icons/icons.json at runtime (name/category/description/tags for all
|
|
5
|
-
* ~600 Clay line icons) rather than importing it as a TS module — packages/email's tsconfig sets
|
|
6
|
-
* rootDir: "src", so a cross-package relative TS import would violate it; a plain JSON file read
|
|
7
|
-
* doesn't, same trick build-email-assets.ts already uses to reach
|
|
8
|
-
* packages/react/src/icons/svg/*.svg for the actual SVG bytes. icons.json is itself generated by
|
|
9
|
-
* the real Clay icon pipeline (scripts/docs/generate-icons.ts) — nothing here is invented.
|
|
10
|
-
*/
|
|
11
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
12
|
-
import { dirname, resolve } from 'node:path';
|
|
13
|
-
import { fileURLToPath } from 'node:url';
|
|
14
|
-
import { containsWord, pickRankedMatch } from './asset-scoring';
|
|
15
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
-
const ICONS_JSON = resolve(__dirname, '../../../../packages/react/src/icons/icons.json');
|
|
17
|
-
function loadIconRegistry() {
|
|
18
|
-
if (!existsSync(ICONS_JSON))
|
|
19
|
-
return [];
|
|
20
|
-
return JSON.parse(readFileSync(ICONS_JSON, 'utf-8'));
|
|
21
|
-
}
|
|
22
|
-
export const ICON_REGISTRY = loadIconRegistry();
|
|
23
|
-
/** Exact name match — for an `icon` slot whose assetRef already names a real Clay icon. */
|
|
24
|
-
export function findIconByName(name) {
|
|
25
|
-
return ICON_REGISTRY.find((e) => e.name === name) ?? null;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Stage 1: score each icon by how many of its tags appear as whole words in `intent` — same
|
|
29
|
-
* content-overlap rule as before. Stage 2 (only among icons tied for the max content score):
|
|
30
|
-
* break the tie by whether the icon's `category` appears as a whole word in `intent` — but only
|
|
31
|
-
* if that produces a single, strictly-positive winner. A generic word like "check" still ties
|
|
32
|
-
* dozens of icons on purpose, and same-category siblings (e.g. home-02/03/05, all "General") still
|
|
33
|
-
* tie on category too — this never guesses between plausible candidates. See asset-scoring.ts's
|
|
34
|
-
* pickRankedMatch for the exact two-stage rule.
|
|
35
|
-
*/
|
|
36
|
-
export function findIconEntry(intent) {
|
|
37
|
-
const lower = intent.toLowerCase();
|
|
38
|
-
return pickRankedMatch(ICON_REGISTRY, {
|
|
39
|
-
contentScore: (entry) => entry.tags.filter((tag) => containsWord(lower, tag)).length,
|
|
40
|
-
secondaryScore: (entry) => (containsWord(lower, entry.category.toLowerCase()) ? 1 : 0),
|
|
41
|
-
explainSecondary: (entry) => [`category:${entry.category}`],
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=icon-registry-map.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icon-registry-map.js","sourceRoot":"","sources":["../../src/build/icon-registry-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAoB,MAAM,iBAAiB,CAAA;AAEjF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,iDAAiD,CAAC,CAAA;AAYxF,SAAS,gBAAgB;IACvB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAA;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAwB,CAAA;AAC7E,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAwB,gBAAgB,EAAE,CAAA;AAEpE,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAA;AAC3D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;IAClC,OAAO,eAAe,CAAC,aAAa,EAAE;QACpC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM;QACpF,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,YAAY,KAAK,CAAC,QAAQ,EAAE,CAAC;KAC5D,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-off importer for real Email Love → Braze exports.
|
|
3
|
-
*
|
|
4
|
-
* These emails are NOT built from the DS MJML pipeline — they are finished exports from the
|
|
5
|
-
* Email Love builder (a self-contained HTML file + a co-located `Images/` folder), kept in the
|
|
6
|
-
* repo as reference artifacts of the desired output shape. This script normalizes each export
|
|
7
|
-
* into `src/examples/<slug>/` with a flat `Images/` folder and an `index.html` whose image
|
|
8
|
-
* references are collapsed to basenames, so the files resolve identically wherever they are served.
|
|
9
|
-
*
|
|
10
|
-
* Run once (or again to re-import after the source folder changes):
|
|
11
|
-
* pnpm --filter @clay-design-system/email tsx src/build/import-examples.ts "<path to Lifecycle HTML examples>"
|
|
12
|
-
*/
|
|
13
|
-
export {};
|
|
14
|
-
//# sourceMappingURL=import-examples.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"import-examples.d.ts","sourceRoot":"","sources":["../../src/build/import-examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-off importer for real Email Love → Braze exports.
|
|
3
|
-
*
|
|
4
|
-
* These emails are NOT built from the DS MJML pipeline — they are finished exports from the
|
|
5
|
-
* Email Love builder (a self-contained HTML file + a co-located `Images/` folder), kept in the
|
|
6
|
-
* repo as reference artifacts of the desired output shape. This script normalizes each export
|
|
7
|
-
* into `src/examples/<slug>/` with a flat `Images/` folder and an `index.html` whose image
|
|
8
|
-
* references are collapsed to basenames, so the files resolve identically wherever they are served.
|
|
9
|
-
*
|
|
10
|
-
* Run once (or again to re-import after the source folder changes):
|
|
11
|
-
* pnpm --filter @clay-design-system/email tsx src/build/import-examples.ts "<path to Lifecycle HTML examples>"
|
|
12
|
-
*/
|
|
13
|
-
import { readdirSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, rmSync, existsSync, statSync, } from 'node:fs';
|
|
14
|
-
import { resolve, join, dirname, basename, extname } from 'node:path';
|
|
15
|
-
import { fileURLToPath } from 'node:url';
|
|
16
|
-
import { EMAILS } from './email-list.js';
|
|
17
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const examplesDir = resolve(__dirname, '..', 'examples');
|
|
19
|
-
const DEFAULT_SOURCE = '/Users/eliorsi/Development/Landing pages Template/Lifecycle/Lifecycle HTML examples';
|
|
20
|
-
const source = process.argv[2] ?? DEFAULT_SOURCE;
|
|
21
|
-
const IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp']);
|
|
22
|
-
/** Recursively collect all file paths under a directory. */
|
|
23
|
-
function walk(dir) {
|
|
24
|
-
const out = [];
|
|
25
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
26
|
-
const full = join(dir, entry.name);
|
|
27
|
-
if (entry.isDirectory())
|
|
28
|
-
out.push(...walk(full));
|
|
29
|
-
else
|
|
30
|
-
out.push(full);
|
|
31
|
-
}
|
|
32
|
-
return out;
|
|
33
|
-
}
|
|
34
|
-
function importOne(slug, dir) {
|
|
35
|
-
const srcDir = join(source, dir);
|
|
36
|
-
if (!existsSync(srcDir))
|
|
37
|
-
throw new Error(`Source folder not found: ${srcDir}`);
|
|
38
|
-
const files = walk(srcDir);
|
|
39
|
-
const htmlFile = files.find((f) => extname(f).toLowerCase() === '.html');
|
|
40
|
-
if (!htmlFile)
|
|
41
|
-
throw new Error(`No .html found under ${srcDir}`);
|
|
42
|
-
const images = files.filter((f) => IMAGE_EXT.has(extname(f).toLowerCase()));
|
|
43
|
-
const destDir = join(examplesDir, slug);
|
|
44
|
-
const destImages = join(destDir, 'Images');
|
|
45
|
-
rmSync(destDir, { recursive: true, force: true });
|
|
46
|
-
mkdirSync(destImages, { recursive: true });
|
|
47
|
-
for (const img of images)
|
|
48
|
-
copyFileSync(img, join(destImages, basename(img)));
|
|
49
|
-
// Collapse any `Images/<any/nested/path>/<file>.ext` reference down to `Images/<file>.ext`.
|
|
50
|
-
let html = readFileSync(htmlFile, 'utf-8');
|
|
51
|
-
html = html.replace(/(["'(])Images\/[^"')]*?([^/"')]+\.(?:png|jpe?g|gif|svg|webp))/gi, (_m, open, file) => `${open}Images/${file}`);
|
|
52
|
-
writeFileSync(join(destDir, 'index.html'), html);
|
|
53
|
-
const bytes = images.reduce((n, f) => n + statSync(f).size, 0);
|
|
54
|
-
console.log(` ${slug.padEnd(18)} ${String(images.length).padStart(2)} images ` +
|
|
55
|
-
`(${(bytes / 1024).toFixed(0)} KB) ← ${dir}`);
|
|
56
|
-
}
|
|
57
|
-
function main() {
|
|
58
|
-
console.log(`Importing Email Love exports from:\n ${source}\n`);
|
|
59
|
-
mkdirSync(examplesDir, { recursive: true });
|
|
60
|
-
for (const { slug, dir } of EMAILS)
|
|
61
|
-
importOne(slug, dir);
|
|
62
|
-
console.log(`\nImported ${EMAILS.length} emails → ${examplesDir}`);
|
|
63
|
-
}
|
|
64
|
-
main();
|
|
65
|
-
//# sourceMappingURL=import-examples.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"import-examples.js","sourceRoot":"","sources":["../../src/build/import-examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,SAAS,EACT,YAAY,EACZ,MAAM,EACN,UAAU,EACV,QAAQ,GACT,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;AAExD,MAAM,cAAc,GAClB,qFAAqF,CAAA;AACvF,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,cAAc,CAAA;AAEhD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAE7E,4DAA4D;AAC5D,SAAS,IAAI,CAAC,GAAW;IACvB,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;;YAC3C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,GAAW;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAChC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAA;IAE9E,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,CAAA;IACxE,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAA;IAChE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IAE3E,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC1C,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACjD,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE1C,KAAK,MAAM,GAAG,IAAI,MAAM;QAAE,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAE5E,4FAA4F;IAC5F,IAAI,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,iEAAiE,EACjE,CAAC,EAAE,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,UAAU,IAAI,EAAE,CAC5D,CAAA;IACD,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,CAAA;IAEhD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9D,OAAO,CAAC,GAAG,CACT,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;QACjE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAChD,CAAA;AACH,CAAC;AAED,SAAS,IAAI;IACX,OAAO,CAAC,GAAG,CAAC,yCAAyC,MAAM,IAAI,CAAC,CAAA;IAChE,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3C,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,MAAM;QAAE,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACxD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,aAAa,WAAW,EAAE,CAAC,CAAA;AACpE,CAAC;AAED,IAAI,EAAE,CAAA"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Persona/feature agent name → illustrated character, for standalone agent-portrait resolution
|
|
3
|
-
* (visual-resolver.ts tier 1).
|
|
4
|
-
*
|
|
5
|
-
* Every entry here is sourced from something already committed to this repo — never invented.
|
|
6
|
-
* Per `skills/campaign-brief/references/agents-catalog.md` rule 4: "the persona/avatar a reader
|
|
7
|
-
* sees on the live card... IS the agent's identity... The brand asset bank supplies the artwork
|
|
8
|
-
* only when it contains that character... never substitute a different bank character." That is
|
|
9
|
-
* exactly why most entries below have `agentSlug: null` — the real character is documented, but
|
|
10
|
-
* it has no illustration in packages/react/src/visuals/agents yet, and inventing a stand-in would
|
|
11
|
-
* violate that rule. A `null` entry is not a smaller gap than an unknown name; visual-resolver.ts
|
|
12
|
-
* still reports it as a `'gap'`, just a more specific one (the character is known, not missing).
|
|
13
|
-
*
|
|
14
|
-
* ⚠ Living table, not a permanent fact — agents-catalog.md itself warns the live library drifts
|
|
15
|
-
* ("board ≠ live page names", agents renamed/added/removed). Re-verify against a fresh live
|
|
16
|
-
* screenshot before trusting an entry for a new campaign; don't silently extend this list from
|
|
17
|
-
* inference alone.
|
|
18
|
-
*/
|
|
19
|
-
export interface PersonaCharacterEntry {
|
|
20
|
-
/** Exact persona/feature name — must match the live library or MVP catalog board, never invented. */
|
|
21
|
-
persona: string;
|
|
22
|
-
/** The illustrated character shown on that persona's live card. */
|
|
23
|
-
character: string;
|
|
24
|
-
/** packages/react/src/visuals/agents AGENT_SLUGS key, only if that character is actually in the bank. */
|
|
25
|
-
agentSlug: string | null;
|
|
26
|
-
/** Where this pairing is documented/used in this repo. */
|
|
27
|
-
source: string;
|
|
28
|
-
}
|
|
29
|
-
export declare const PERSONA_CHARACTER_MAP: PersonaCharacterEntry[];
|
|
30
|
-
/** A single unambiguous persona match in the given text, or null if zero/multiple candidates match. */
|
|
31
|
-
export declare function findPersonaEntry(text: string): PersonaCharacterEntry | null;
|
|
32
|
-
//# sourceMappingURL=persona-character-map.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"persona-character-map.d.ts","sourceRoot":"","sources":["../../src/build/persona-character-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,qGAAqG;IACrG,OAAO,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;IACjB,yGAAyG;IACzG,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,qBAAqB,EAAE,qBAAqB,EAgExD,CAAA;AAED,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAO3E"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Persona/feature agent name → illustrated character, for standalone agent-portrait resolution
|
|
3
|
-
* (visual-resolver.ts tier 1).
|
|
4
|
-
*
|
|
5
|
-
* Every entry here is sourced from something already committed to this repo — never invented.
|
|
6
|
-
* Per `skills/campaign-brief/references/agents-catalog.md` rule 4: "the persona/avatar a reader
|
|
7
|
-
* sees on the live card... IS the agent's identity... The brand asset bank supplies the artwork
|
|
8
|
-
* only when it contains that character... never substitute a different bank character." That is
|
|
9
|
-
* exactly why most entries below have `agentSlug: null` — the real character is documented, but
|
|
10
|
-
* it has no illustration in packages/react/src/visuals/agents yet, and inventing a stand-in would
|
|
11
|
-
* violate that rule. A `null` entry is not a smaller gap than an unknown name; visual-resolver.ts
|
|
12
|
-
* still reports it as a `'gap'`, just a more specific one (the character is known, not missing).
|
|
13
|
-
*
|
|
14
|
-
* ⚠ Living table, not a permanent fact — agents-catalog.md itself warns the live library drifts
|
|
15
|
-
* ("board ≠ live page names", agents renamed/added/removed). Re-verify against a fresh live
|
|
16
|
-
* screenshot before trusting an entry for a new campaign; don't silently extend this list from
|
|
17
|
-
* inference alone.
|
|
18
|
-
*/
|
|
19
|
-
export const PERSONA_CHARACTER_MAP = [
|
|
20
|
-
{
|
|
21
|
-
persona: 'Onboarding Program Manager',
|
|
22
|
-
character: 'Sofia',
|
|
23
|
-
agentSlug: 'sofia',
|
|
24
|
-
source: 'skills/email-assets/knowledge/hero-masters-static.md (tp2a-onboarding-program-manager.html master); shipped in packages/email/src/emails/hr-trial-onboarding/tp2-first-agent',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
persona: 'Feature Request Agent',
|
|
28
|
-
character: 'Zoe',
|
|
29
|
-
agentSlug: 'zoe',
|
|
30
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
persona: 'Outbound Prospector',
|
|
34
|
-
character: 'Marco',
|
|
35
|
-
agentSlug: null,
|
|
36
|
-
source: 'skills/email-assets/knowledge/hero-masters-static.md ("Marco, Outbound Prospector"); shipped in packages/email/src/emails/sales-agent-activation/tp2a-outbound-prospector (Figma composite export, not AgentVisual)',
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
persona: 'Pipeline Guardian',
|
|
40
|
-
character: 'Noa',
|
|
41
|
-
agentSlug: null,
|
|
42
|
-
source: 'skills/email-assets/knowledge/hero-masters-static.md + hero-masters-carousel.md ("Noa, Pipeline Guardian"); shipped in packages/email/src/emails/sales-agent-activation/tp2b-pipeline-guardian (Figma composite export, not AgentVisual)',
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
persona: 'Contract Renewal Agent',
|
|
46
|
-
character: 'Enzo',
|
|
47
|
-
agentSlug: null,
|
|
48
|
-
source: 'skills/email-assets/knowledge/hero-masters-carousel.md ("Enzo" / "Contract Renewal Agent" card)',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
persona: 'Sprint Planner',
|
|
52
|
-
character: 'Kobi',
|
|
53
|
-
agentSlug: null,
|
|
54
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
persona: 'Release Notes Agent',
|
|
58
|
-
character: 'Clara',
|
|
59
|
-
agentSlug: null,
|
|
60
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
persona: 'PRD Writer & Keeper',
|
|
64
|
-
character: 'Daniel',
|
|
65
|
-
agentSlug: null,
|
|
66
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
persona: 'Feedback Digest Agent',
|
|
70
|
-
character: 'Jean',
|
|
71
|
-
agentSlug: null,
|
|
72
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
persona: 'Bug Triage Agent',
|
|
76
|
-
character: 'Felix',
|
|
77
|
-
agentSlug: null,
|
|
78
|
-
source: 'skills/campaign-brief/references/agents-catalog.md, Product & Engineering section, live-verified 2026-08-03',
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
/** A single unambiguous persona match in the given text, or null if zero/multiple candidates match. */
|
|
82
|
-
export function findPersonaEntry(text) {
|
|
83
|
-
const lower = text.toLowerCase();
|
|
84
|
-
const matches = PERSONA_CHARACTER_MAP.filter((entry) => {
|
|
85
|
-
const escaped = entry.persona.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
86
|
-
return new RegExp(`\\b${escaped}\\b`).test(lower);
|
|
87
|
-
});
|
|
88
|
-
return matches.length === 1 ? matches[0] : null;
|
|
89
|
-
}
|
|
90
|
-
//# sourceMappingURL=persona-character-map.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"persona-character-map.js","sourceRoot":"","sources":["../../src/build/persona-character-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAaH,MAAM,CAAC,MAAM,qBAAqB,GAA4B;IAC5D;QACE,OAAO,EAAE,4BAA4B;QACrC,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,OAAO;QAClB,MAAM,EACJ,8KAA8K;KACjL;IACD;QACE,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,6GAA6G;KACtH;IACD;QACE,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,IAAI;QACf,MAAM,EACJ,qNAAqN;KACxN;IACD;QACE,OAAO,EAAE,mBAAmB;QAC5B,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,MAAM,EACJ,0OAA0O;KAC7O;IACD;QACE,OAAO,EAAE,wBAAwB;QACjC,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,iGAAiG;KAC1G;IACD;QACE,OAAO,EAAE,gBAAgB;QACzB,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,6GAA6G;KACtH;IACD;QACE,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,6GAA6G;KACtH;IACD;QACE,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,6GAA6G;KACtH;IACD;QACE,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,6GAA6G;KACtH;IACD;QACE,OAAO,EAAE,kBAAkB;QAC3B,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,6GAA6G;KACtH;CACF,CAAA;AAED,uGAAuG;AACvG,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACrD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;QAClF,OAAO,IAAI,MAAM,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IACF,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACjD,CAAC"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Labelled email placeholder generator (K10 EM-2).
|
|
3
|
-
*
|
|
4
|
-
* An unresolved image slot (visual-resolver.ts status 'placeholder') needs a visible stand-in while
|
|
5
|
-
* the real asset is sourced. The shared `assets/placeholders/*.svg` tiles are blank and painted
|
|
6
|
-
* #e6e7ea, which is not on the approved placeholder tint list, and SVG doesn't render in Outlook or
|
|
7
|
-
* Gmail <img>. This module draws a **labelled** placeholder on an **approved tint** and writes it as
|
|
8
|
-
* a 2× PNG campaign asset, so `email:upload` can host it like any other campaign image.
|
|
9
|
-
*
|
|
10
|
-
* The tint list mirrors `policy.email.color-system.image-placeholder-background-colors`
|
|
11
|
-
* (19-email-color-system.md § Image Placeholder Background Colors); kb:test checks the two agree.
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* pnpm --filter @clay-design-system/email email:placeholder -- \
|
|
15
|
-
* --label="A monday board built from a template" --size=560x320 \
|
|
16
|
-
* [--tint=cool-grey|warm-cream|pale-blue|pale-lavender|pale-green|black] [--hero] [--scale=2] \
|
|
17
|
-
* --out=<abs path>/src/assets/<campaign>/<name>.png (or .svg for the vector source)
|
|
18
|
-
*/
|
|
19
|
-
/** The approved placeholder background tints, in the order the colour-system policy lists them. */
|
|
20
|
-
export declare const PLACEHOLDER_TINTS: {
|
|
21
|
-
readonly 'cool-grey': {
|
|
22
|
-
readonly hex: "#f3f4f5";
|
|
23
|
-
readonly use: "Default — safe for any content type";
|
|
24
|
-
};
|
|
25
|
-
readonly 'warm-cream': {
|
|
26
|
-
readonly hex: "#f7f3ea";
|
|
27
|
-
readonly use: "Warm-tinted sections (surfaceWarm)";
|
|
28
|
-
};
|
|
29
|
-
readonly 'pale-blue': {
|
|
30
|
-
readonly hex: "#eff5fd";
|
|
31
|
-
readonly use: "Conference, webinar, event imagery";
|
|
32
|
-
};
|
|
33
|
-
readonly 'pale-lavender': {
|
|
34
|
-
readonly hex: "#d9d7ff";
|
|
35
|
-
readonly use: "Creative/design feature sections";
|
|
36
|
-
};
|
|
37
|
-
readonly 'pale-green': {
|
|
38
|
-
readonly hex: "#ceead6";
|
|
39
|
-
readonly use: "Sustainability, success, governance imagery";
|
|
40
|
-
};
|
|
41
|
-
readonly black: {
|
|
42
|
-
readonly hex: "#000000";
|
|
43
|
-
readonly use: "Dark/dramatic hero image placeholder (above-fold hero only)";
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
export type PlaceholderTint = keyof typeof PLACEHOLDER_TINTS;
|
|
47
|
-
export interface PlaceholderOptions {
|
|
48
|
-
/** Display width in px (the column the image sits in, e.g. 560). */
|
|
49
|
-
width: number;
|
|
50
|
-
/** Display height in px. */
|
|
51
|
-
height: number;
|
|
52
|
-
/** What the real image will show — printed on the tile, so a reviewer knows what's missing. */
|
|
53
|
-
label: string;
|
|
54
|
-
/** Default 'cool-grey'. */
|
|
55
|
-
tint?: PlaceholderTint;
|
|
56
|
-
/** The slot is the above-fold hero — the only slot that may use the black tint. */
|
|
57
|
-
hero?: boolean;
|
|
58
|
-
}
|
|
59
|
-
/** Greedy word wrap to `maxChars` per line, at most `maxLines` lines (the last one ellipsised). */
|
|
60
|
-
export declare function wrapLabel(label: string, maxChars: number, maxLines: number): string[];
|
|
61
|
-
/** Validates the options; throws on anything the colour-system policy doesn't allow. */
|
|
62
|
-
export declare function checkPlaceholderOptions(opts: PlaceholderOptions): Required<PlaceholderOptions>;
|
|
63
|
-
/** The labelled placeholder as an SVG string at display size (the PNG renders it at `scale`×). */
|
|
64
|
-
export declare function placeholderSvg(opts: PlaceholderOptions): string;
|
|
65
|
-
/** Writes the placeholder: `.svg` → the vector source; anything else → a `scale`× PNG (via sharp). */
|
|
66
|
-
export declare function writePlaceholder(opts: PlaceholderOptions & {
|
|
67
|
-
out: string;
|
|
68
|
-
scale?: number;
|
|
69
|
-
}): Promise<{
|
|
70
|
-
out: string;
|
|
71
|
-
width: number;
|
|
72
|
-
height: number;
|
|
73
|
-
}>;
|
|
74
|
-
/** `--label=… --size=560x320 --tint=… --hero --scale=2 --out=…` → options. */
|
|
75
|
-
export declare function parsePlaceholderArgs(argv: string[]): PlaceholderOptions & {
|
|
76
|
-
out: string;
|
|
77
|
-
scale?: number;
|
|
78
|
-
};
|
|
79
|
-
//# sourceMappingURL=placeholder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"placeholder.d.ts","sourceRoot":"","sources":["../../src/build/placeholder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,mGAAmG;AACnG,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;CAOpB,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAE5D,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,+FAA+F;IAC/F,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAQD,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrF;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAa9F;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAwB/D;AAED,sGAAsG;AACtG,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB1J;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,kBAAkB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBzG"}
|