@clay-design-system/email 0.2.4 → 0.3.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/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
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Migrating `@clay-design-system/email` (Phase 2 release)
|
|
2
|
+
|
|
3
|
+
This release is a breaking minor (0.x), but only for what the package no longer ships. The public surface (the `exports` map) is the same
|
|
4
|
+
plus `./package.json`, and every subpath that resolved before resolves now.
|
|
5
|
+
|
|
6
|
+
| If you … | Do this |
|
|
7
|
+
|---|---|
|
|
8
|
+
| import `.`, `./catalog.json` or `./emails/*` | Nothing |
|
|
9
|
+
| read `node_modules/@clay-design-system/email/dist/exports/…`, `dist/examples/…`, `dist/build/…` or `dist/tokens/…` | Take the files from the repository instead (see below) |
|
|
10
|
+
| rely on source maps | There are none; build from source if you need them |
|
|
11
|
+
|
|
12
|
+
## What the package ships now
|
|
13
|
+
|
|
14
|
+
`dist/index.js` and `dist/index.d.ts` (the inline token constants), the two generated token files and the `Catalog` type they
|
|
15
|
+
reference (`dist/generated/email-tokens.*`, `dist/build/catalog.d.ts`), `dist/catalog.json`, and `dist/emails/*` (the compiled
|
|
16
|
+
HTML of each section and component email, 77 files). Packed size: 10.2 MB → about 0.46 MB (unpacked 15.0 → about 3.3 MB).
|
|
17
|
+
|
|
18
|
+
## What was removed
|
|
19
|
+
|
|
20
|
+
- **`dist/exports/`** (11 MB of Braze campaign exports and their images), **`dist/build/*.js`** and **`dist/tokens/*.js`** (the build scripts), **`dist/examples/`**
|
|
21
|
+
and all `.map` files. None of them was reachable through the `exports` map, so an import by package name never touched them. Only a
|
|
22
|
+
deep path into `node_modules` did, which was never public.
|
|
23
|
+
- If you need a campaign export or a build script, run it from the repository (`pnpm --filter @clay-design-system/email build`,
|
|
24
|
+
`export:braze`). The campaign images are not on the CDN yet; they were not published through the package either.
|
|
25
|
+
|
|
26
|
+
## Unchanged and new
|
|
27
|
+
|
|
28
|
+
- **Unchanged:** `.` (ESM only, `import` condition with `types`), `./catalog.json`, `./emails/*`. The package stays ESM-only.
|
|
29
|
+
- **New:** `./package.json` is an exported subpath. The `Catalog` type export resolves under Node16/NodeNext.
|
|
30
|
+
- **Tokens:** emails inline token values at build time (no `var(--clay-*)` in them), so they need no tokens CSS at runtime. The package
|
|
31
|
+
still lists `@clay-design-system/tokens` under `dependencies`, as before.
|
package/README.md
CHANGED
|
@@ -46,4 +46,11 @@ pnpm --filter @clay-design-system/email tokens:check # fail if generated token
|
|
|
46
46
|
pnpm --filter @clay-design-system/email test # vitest
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## What the npm package ships
|
|
50
|
+
|
|
51
|
+
Only the public surface: `dist/index.js` + types (the inline token constants), `@clay-design-system/email/catalog.json`, `…/emails/*` (compiled HTML,
|
|
52
|
+
Braze and static variants). Source maps, `dist/build`, `dist/examples` and `dist/exports` (the Braze campaign exports with their
|
|
53
|
+
images, ~11 MB) stay in the repo: they are build output, not importable through the `exports` map. `package.json` `files` is an
|
|
54
|
+
allowlist, so new build output is not published until it is added there.
|
|
55
|
+
|
|
49
56
|
Documented in Storybook under **Lifecycle/Email/**.
|
package/dist/build/catalog.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -5,5 +5,4 @@
|
|
|
5
5
|
* catalog types. Compiled email HTML is read from `@clay-design-system/email/catalog.json`.
|
|
6
6
|
*/
|
|
7
7
|
export * from './generated/email-tokens.js';
|
|
8
|
-
export type { Catalog, CatalogItem, CatalogKind } from './build/catalog';
|
|
9
|
-
//# sourceMappingURL=index.d.ts.map
|
|
8
|
+
export type { Catalog, CatalogItem, CatalogKind } from './build/catalog.js';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clay-design-system/email",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -8,13 +8,22 @@
|
|
|
8
8
|
"import": "./dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"./catalog.json": "./dist/catalog.json",
|
|
11
|
-
"./emails/*": "./dist/emails/*"
|
|
11
|
+
"./emails/*": "./dist/emails/*",
|
|
12
|
+
"./package.json": "./package.json"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
|
-
"dist"
|
|
15
|
+
"dist/index.js",
|
|
16
|
+
"dist/index.d.ts",
|
|
17
|
+
"dist/generated/email-tokens.js",
|
|
18
|
+
"dist/generated/email-tokens.d.ts",
|
|
19
|
+
"dist/build/catalog.d.ts",
|
|
20
|
+
"dist/catalog.json",
|
|
21
|
+
"dist/emails",
|
|
22
|
+
"MIGRATION.md",
|
|
23
|
+
"!dist/**/*.map"
|
|
15
24
|
],
|
|
16
25
|
"dependencies": {
|
|
17
|
-
"@clay-design-system/tokens": "0.
|
|
26
|
+
"@clay-design-system/tokens": "0.15.0"
|
|
18
27
|
},
|
|
19
28
|
"devDependencies": {
|
|
20
29
|
"@types/mjml": "^4.7.4",
|
|
@@ -28,7 +37,7 @@
|
|
|
28
37
|
"vitest": "^2.1.0"
|
|
29
38
|
},
|
|
30
39
|
"scripts": {
|
|
31
|
-
"build": "tsx src/tokens/build-email-tokens.ts && tsx src/tokens/build-email-assets.ts && tsc && tsx src/build/compile.ts && tsx src/build/export-braze.ts",
|
|
40
|
+
"build": "tsx src/tokens/build-email-tokens.ts && tsx src/tokens/build-email-assets.ts && tsc -p tsconfig.build.json && tsx src/build/compile.ts && tsx src/build/export-braze.ts",
|
|
32
41
|
"dev": "tsx src/build/compile.ts --watch",
|
|
33
42
|
"typecheck": "tsc --noEmit",
|
|
34
43
|
"test": "vitest run",
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared two-stage ranked-match algorithm for visual-resolver.ts's asset pickers
|
|
3
|
-
* (stock-library-map.ts, icon-registry-map.ts) — the "never guess between plausible candidates"
|
|
4
|
-
* rule, in exactly one place, extended to use more than one data column without weakening it.
|
|
5
|
-
*
|
|
6
|
-
* Stage 1 (content gate): a candidate must have positive `contentScore` to be considered at all —
|
|
7
|
-
* a secondary signal (aspect ratio, domain, category, ...) can never rescue a zero-content-overlap
|
|
8
|
-
* candidate, and can never outrank a candidate with a strictly higher content score.
|
|
9
|
-
* Stage 2 (tie-break): only among the candidates tied for the *maximum* content score, break the
|
|
10
|
-
* tie using `secondaryScore` — but only if that produces a unique, strictly-positive top scorer.
|
|
11
|
-
* A genuine tie (including an all-zero secondary tie) still returns null, same as before this
|
|
12
|
-
* module existed.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Word-boundary match, not substring — shared by every fuzzy text matcher in this build pipeline
|
|
16
|
-
* (visual-resolver.ts, icon-registry-map.ts, stock-library-map.ts) so the "whole word" rule can't
|
|
17
|
-
* drift between them.
|
|
18
|
-
*/
|
|
19
|
-
export declare function containsWord(haystackLower: string, word: string): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* A visual slot's rough layout shape — derived automatically from the slot spec (see
|
|
22
|
-
* visual-resolver.ts's deriveSlotShape), never hand-authored in a brief. Used only as a
|
|
23
|
-
* stage-2 tie-breaker (see pickRankedMatch below), never as a stage-1 filter.
|
|
24
|
-
*/
|
|
25
|
-
export type SlotShape = 'hero' | 'card' | 'banner' | 'icon' | 'unknown';
|
|
26
|
-
/**
|
|
27
|
-
* Which of stock-library-source.csv's curated `ratio` values ('square' | 'wide' | 'super wide')
|
|
28
|
-
* count as a fit for each shape. Deliberately permissive (a shape can accept more than one ratio)
|
|
29
|
-
* — the real section survey behind this showed sections sharing a shape name still vary in actual
|
|
30
|
-
* aspect (e.g. product-ui-hero is 1.6:1 landscape, image-hero is ~1:1, newsletter-hero is 0.82:1
|
|
31
|
-
* portrait), so this is a coarse signal, not an exact-ratio requirement. `icon`/`unknown` never
|
|
32
|
-
* score — icons have no aspect axis, and `unknown` is the shape for every slot whose text doesn't
|
|
33
|
-
* name one (including every existing test's `slot: 'x'`), so it's a guaranteed no-op there.
|
|
34
|
-
*/
|
|
35
|
-
export declare const SHAPE_ACCEPTABLE_RATIOS: Record<SlotShape, Set<string>>;
|
|
36
|
-
export interface RankOptions<T> {
|
|
37
|
-
contentScore(entry: T): number;
|
|
38
|
-
secondaryScore(entry: T): number;
|
|
39
|
-
/** Only called on the eventual tie-break winner, to explain which signals fired for it. */
|
|
40
|
-
explainSecondary?(entry: T): string[];
|
|
41
|
-
}
|
|
42
|
-
export interface RankedMatch<T> {
|
|
43
|
-
entry: T;
|
|
44
|
-
/** Empty when the winner was a unique content-score winner (identical to pre-ranking behavior). Populated only when a content tie was broken by secondaryScore. */
|
|
45
|
-
disambiguatedBy: string[];
|
|
46
|
-
}
|
|
47
|
-
export declare function pickRankedMatch<T>(candidates: T[], opts: RankOptions<T>): RankedMatch<T> | null;
|
|
48
|
-
//# sourceMappingURL=asset-scoring.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset-scoring.d.ts","sourceRoot":"","sources":["../../src/build/asset-scoring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAA;AAEvE;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAMlE,CAAA;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,YAAY,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAA;IAC9B,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAA;IAChC,2FAA2F;IAC3F,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,EAAE,CAAA;CACtC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAA;IACR,mKAAmK;IACnK,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAgB/F"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared two-stage ranked-match algorithm for visual-resolver.ts's asset pickers
|
|
3
|
-
* (stock-library-map.ts, icon-registry-map.ts) — the "never guess between plausible candidates"
|
|
4
|
-
* rule, in exactly one place, extended to use more than one data column without weakening it.
|
|
5
|
-
*
|
|
6
|
-
* Stage 1 (content gate): a candidate must have positive `contentScore` to be considered at all —
|
|
7
|
-
* a secondary signal (aspect ratio, domain, category, ...) can never rescue a zero-content-overlap
|
|
8
|
-
* candidate, and can never outrank a candidate with a strictly higher content score.
|
|
9
|
-
* Stage 2 (tie-break): only among the candidates tied for the *maximum* content score, break the
|
|
10
|
-
* tie using `secondaryScore` — but only if that produces a unique, strictly-positive top scorer.
|
|
11
|
-
* A genuine tie (including an all-zero secondary tie) still returns null, same as before this
|
|
12
|
-
* module existed.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Word-boundary match, not substring — shared by every fuzzy text matcher in this build pipeline
|
|
16
|
-
* (visual-resolver.ts, icon-registry-map.ts, stock-library-map.ts) so the "whole word" rule can't
|
|
17
|
-
* drift between them.
|
|
18
|
-
*/
|
|
19
|
-
export function containsWord(haystackLower, word) {
|
|
20
|
-
const escaped = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
21
|
-
// Whole word, tolerating a simple English plural in the haystack ("agents" matches tag "agent").
|
|
22
|
-
return new RegExp(`\\b${escaped}(?:s|es)?\\b`).test(haystackLower);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Which of stock-library-source.csv's curated `ratio` values ('square' | 'wide' | 'super wide')
|
|
26
|
-
* count as a fit for each shape. Deliberately permissive (a shape can accept more than one ratio)
|
|
27
|
-
* — the real section survey behind this showed sections sharing a shape name still vary in actual
|
|
28
|
-
* aspect (e.g. product-ui-hero is 1.6:1 landscape, image-hero is ~1:1, newsletter-hero is 0.82:1
|
|
29
|
-
* portrait), so this is a coarse signal, not an exact-ratio requirement. `icon`/`unknown` never
|
|
30
|
-
* score — icons have no aspect axis, and `unknown` is the shape for every slot whose text doesn't
|
|
31
|
-
* name one (including every existing test's `slot: 'x'`), so it's a guaranteed no-op there.
|
|
32
|
-
*/
|
|
33
|
-
export const SHAPE_ACCEPTABLE_RATIOS = {
|
|
34
|
-
hero: new Set(['wide', 'super wide']),
|
|
35
|
-
card: new Set(['square']),
|
|
36
|
-
banner: new Set(['super wide']),
|
|
37
|
-
icon: new Set([]),
|
|
38
|
-
unknown: new Set([]),
|
|
39
|
-
};
|
|
40
|
-
export function pickRankedMatch(candidates, opts) {
|
|
41
|
-
const scored = candidates.map((entry) => ({ entry, contentScore: opts.contentScore(entry) })).filter((s) => s.contentScore > 0);
|
|
42
|
-
if (!scored.length)
|
|
43
|
-
return null;
|
|
44
|
-
const maxContent = Math.max(...scored.map((s) => s.contentScore));
|
|
45
|
-
const contentWinners = scored.filter((s) => s.contentScore === maxContent);
|
|
46
|
-
if (contentWinners.length === 1)
|
|
47
|
-
return { entry: contentWinners[0].entry, disambiguatedBy: [] };
|
|
48
|
-
const withSecondary = contentWinners.map((s) => ({ entry: s.entry, secondaryScore: opts.secondaryScore(s.entry) }));
|
|
49
|
-
const maxSecondary = Math.max(...withSecondary.map((s) => s.secondaryScore));
|
|
50
|
-
if (maxSecondary <= 0)
|
|
51
|
-
return null;
|
|
52
|
-
const secondaryWinners = withSecondary.filter((s) => s.secondaryScore === maxSecondary);
|
|
53
|
-
if (secondaryWinners.length !== 1)
|
|
54
|
-
return null;
|
|
55
|
-
const winner = secondaryWinners[0].entry;
|
|
56
|
-
return { entry: winner, disambiguatedBy: opts.explainSecondary ? opts.explainSecondary(winner) : [] };
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=asset-scoring.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset-scoring.js","sourceRoot":"","sources":["../../src/build/asset-scoring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,aAAqB,EAAE,IAAY;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IAC3D,iGAAiG;IACjG,OAAO,IAAI,MAAM,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;AACpE,CAAC;AASD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmC;IACrE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzB,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;IAC/B,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;IACjB,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;CACrB,CAAA;AAeD,MAAM,UAAU,eAAe,CAAI,UAAe,EAAE,IAAoB;IACtE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;IAC/H,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAE/B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;IACjE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC,CAAA;IAC1E,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,CAAA;IAE/F,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IACnH,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAA;IAC5E,IAAI,YAAY,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAElC,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,YAAY,CAAC,CAAA;IACvF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9C,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACxC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AACvG,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Braze export transform.
|
|
3
|
-
*
|
|
4
|
-
* Chunk 1 = **full-template import** mode: the whole HTML document is preserved (so head media-queries
|
|
5
|
-
* and the dark-mode block survive — Braze content-block export would strip the <head>). We only:
|
|
6
|
-
* 1. replace the footer unsubscribe placeholder with Braze's Liquid unsubscribe token, and
|
|
7
|
-
* 2. optionally wrap flagged strings in Liquid (off by default — plumbing for later chunks).
|
|
8
|
-
*
|
|
9
|
-
* Content-block mode (head-CSS re-injection) is deferred to a later chunk.
|
|
10
|
-
*/
|
|
11
|
-
/** Placeholder token authored into the footer section; swapped for the ESP's real unsubscribe URL. */
|
|
12
|
-
export declare const UNSUBSCRIBE_PLACEHOLDER = "%%UNSUBSCRIBE_URL%%";
|
|
13
|
-
export interface BrazeConfig {
|
|
14
|
-
mode?: 'template' | 'content-block';
|
|
15
|
-
unsubscribe?: boolean;
|
|
16
|
-
/** map of placeholder → Liquid expression, applied verbatim (optional) */
|
|
17
|
-
liquid?: Record<string, string>;
|
|
18
|
-
}
|
|
19
|
-
export declare function brazeTransform(html: string, config?: BrazeConfig): string;
|
|
20
|
-
//# sourceMappingURL=braze-transform.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"braze-transform.d.ts","sourceRoot":"","sources":["../../src/build/braze-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,sGAAsG;AACtG,eAAO,MAAM,uBAAuB,wBAAwB,CAAA;AAK5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,UAAU,GAAG,eAAe,CAAA;IACnC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,WAAgB,GAAG,MAAM,CAa7E"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Braze export transform.
|
|
3
|
-
*
|
|
4
|
-
* Chunk 1 = **full-template import** mode: the whole HTML document is preserved (so head media-queries
|
|
5
|
-
* and the dark-mode block survive — Braze content-block export would strip the <head>). We only:
|
|
6
|
-
* 1. replace the footer unsubscribe placeholder with Braze's Liquid unsubscribe token, and
|
|
7
|
-
* 2. optionally wrap flagged strings in Liquid (off by default — plumbing for later chunks).
|
|
8
|
-
*
|
|
9
|
-
* Content-block mode (head-CSS re-injection) is deferred to a later chunk.
|
|
10
|
-
*/
|
|
11
|
-
/** Placeholder token authored into the footer section; swapped for the ESP's real unsubscribe URL. */
|
|
12
|
-
export const UNSUBSCRIBE_PLACEHOLDER = '%%UNSUBSCRIBE_URL%%';
|
|
13
|
-
/** Braze Liquid personalization tag for the unsubscribe URL. */
|
|
14
|
-
const BRAZE_UNSUBSCRIBE = '{{${set_user_to_unsubscribed_url}}}';
|
|
15
|
-
export function brazeTransform(html, config = {}) {
|
|
16
|
-
const { unsubscribe = true, liquid = {} } = config;
|
|
17
|
-
let out = html;
|
|
18
|
-
if (unsubscribe) {
|
|
19
|
-
out = out.split(UNSUBSCRIBE_PLACEHOLDER).join(BRAZE_UNSUBSCRIBE);
|
|
20
|
-
}
|
|
21
|
-
for (const [placeholder, expr] of Object.entries(liquid)) {
|
|
22
|
-
out = out.split(placeholder).join(expr);
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=braze-transform.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"braze-transform.js","sourceRoot":"","sources":["../../src/build/braze-transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,sGAAsG;AACtG,MAAM,CAAC,MAAM,uBAAuB,GAAG,qBAAqB,CAAA;AAE5D,gEAAgE;AAChE,MAAM,iBAAiB,GAAG,qCAAqC,CAAA;AAS/D,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,SAAsB,EAAE;IACnE,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,MAAM,CAAA;IAClD,IAAI,GAAG,GAAG,IAAI,CAAA;IAEd,IAAI,WAAW,EAAE,CAAC;QAChB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAClE,CAAC;IAED,KAAK,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzC,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/build/catalog.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAEnF,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAEzE,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAA;IACV,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,WAAW,CAAA;IACjB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,sBAAsB;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,WAAW,EAAE,CAAA;CACrB"}
|
package/dist/build/catalog.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/build/catalog.ts"],"names":[],"mappings":"AAAA,mFAAmF"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloudinary credential loader.
|
|
3
|
-
*
|
|
4
|
-
* Reads CLOUDINARY_CLOUD_NAME / CLOUDINARY_API_KEY / CLOUDINARY_API_SECRET from the repo-root
|
|
5
|
-
* `.env` (untracked — see skills/email-campaign/OPEN-QUESTIONS.md Q4). Never hardcode or log the
|
|
6
|
-
* raw secret values; this module only reports which *names* are missing.
|
|
7
|
-
*/
|
|
8
|
-
export interface CloudinaryEnv {
|
|
9
|
-
cloudName: string;
|
|
10
|
-
apiKey: string;
|
|
11
|
-
apiSecret: string;
|
|
12
|
-
}
|
|
13
|
-
/** Throws a clear, actionable error (pointing at Q4) if any credential is missing. */
|
|
14
|
-
export declare function loadCloudinaryEnv(): CloudinaryEnv;
|
|
15
|
-
//# sourceMappingURL=cloudinary-env.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudinary-env.d.ts","sourceRoot":"","sources":["../../src/build/cloudinary-env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,IAAI,aAAa,CA0BjD"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloudinary credential loader.
|
|
3
|
-
*
|
|
4
|
-
* Reads CLOUDINARY_CLOUD_NAME / CLOUDINARY_API_KEY / CLOUDINARY_API_SECRET from the repo-root
|
|
5
|
-
* `.env` (untracked — see skills/email-campaign/OPEN-QUESTIONS.md Q4). Never hardcode or log the
|
|
6
|
-
* raw secret values; this module only reports which *names* are missing.
|
|
7
|
-
*/
|
|
8
|
-
import { existsSync } from 'node:fs';
|
|
9
|
-
import { dirname, resolve } from 'node:path';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
11
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const repoRoot = resolve(__dirname, '../../../..');
|
|
13
|
-
const envPath = resolve(repoRoot, '.env');
|
|
14
|
-
/** Throws a clear, actionable error (pointing at Q4) if any credential is missing. */
|
|
15
|
-
export function loadCloudinaryEnv() {
|
|
16
|
-
if (existsSync(envPath)) {
|
|
17
|
-
process.loadEnvFile(envPath);
|
|
18
|
-
}
|
|
19
|
-
const cloudName = process.env.CLOUDINARY_CLOUD_NAME;
|
|
20
|
-
const apiKey = process.env.CLOUDINARY_API_KEY;
|
|
21
|
-
const apiSecret = process.env.CLOUDINARY_API_SECRET;
|
|
22
|
-
const missing = [
|
|
23
|
-
!cloudName && 'CLOUDINARY_CLOUD_NAME',
|
|
24
|
-
!apiKey && 'CLOUDINARY_API_KEY',
|
|
25
|
-
!apiSecret && 'CLOUDINARY_API_SECRET',
|
|
26
|
-
].filter((v) => Boolean(v));
|
|
27
|
-
if (missing.length) {
|
|
28
|
-
throw new Error(`Missing Cloudinary credentials: ${missing.join(', ')}.\n` +
|
|
29
|
-
`Add them to an untracked .env at the repo root (${envPath}) — see ` +
|
|
30
|
-
`skills/email-campaign/OPEN-QUESTIONS.md Q4:\n` +
|
|
31
|
-
` CLOUDINARY_CLOUD_NAME=...\n CLOUDINARY_API_KEY=...\n CLOUDINARY_API_SECRET=...\n` +
|
|
32
|
-
`Use --dry-run to preview what would be uploaded without credentials.`);
|
|
33
|
-
}
|
|
34
|
-
return { cloudName: cloudName, apiKey: apiKey, apiSecret: apiSecret };
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=cloudinary-env.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudinary-env.js","sourceRoot":"","sources":["../../src/build/cloudinary-env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;AAClD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AAQzC,sFAAsF;AACtF,MAAM,UAAU,iBAAiB;IAC/B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAA;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAA;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAA;IAEnD,MAAM,OAAO,GAAG;QACd,CAAC,SAAS,IAAI,uBAAuB;QACrC,CAAC,MAAM,IAAI,oBAAoB;QAC/B,CAAC,SAAS,IAAI,uBAAuB;KACtC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAExC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YACxD,mDAAmD,OAAO,UAAU;YACpE,+CAA+C;YAC/C,sFAAsF;YACtF,sEAAsE,CACzE,CAAA;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,SAAU,EAAE,MAAM,EAAE,MAAO,EAAE,SAAS,EAAE,SAAU,EAAE,CAAA;AAC1E,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared manifest shape + path for the Cloudinary upload pipeline.
|
|
3
|
-
*
|
|
4
|
-
* `upload-assets.ts` writes this file; `compile.ts` reads it (if present) to swap a campaign
|
|
5
|
-
* asset's `src` for its hosted URL instead of inlining it as base64. Both import from here so the
|
|
6
|
-
* path and shape can never drift between writer and reader.
|
|
7
|
-
*/
|
|
8
|
-
/** dist/ is gitignored — this is local, regenerable build output, not committed. */
|
|
9
|
-
export declare const cloudinaryManifestPath: string;
|
|
10
|
-
export interface CloudinaryManifestEntry {
|
|
11
|
-
/** Path relative to src/assets/, e.g. "sales-agent-activation/tp1-library-hero.png". */
|
|
12
|
-
sourcePath: string;
|
|
13
|
-
/** Top-level dir under src/emails/ that referenced this asset. */
|
|
14
|
-
campaign: string;
|
|
15
|
-
/** The specific email (fileBaseName) that referenced this asset. */
|
|
16
|
-
email: string;
|
|
17
|
-
/** Cloudinary secure_url returned by the upload. */
|
|
18
|
-
url: string;
|
|
19
|
-
bytes: number;
|
|
20
|
-
/** sha256 of the local file content — lets re-runs skip an unchanged upload. */
|
|
21
|
-
contentHash: string;
|
|
22
|
-
uploadedAt: string;
|
|
23
|
-
}
|
|
24
|
-
export interface CloudinaryManifest {
|
|
25
|
-
generatedFrom: string;
|
|
26
|
-
cloudName: string;
|
|
27
|
-
/** Keyed by Cloudinary public_id, e.g. "lifecycle/sales-agent-activation/tp1a-library/tp1-library-hero". */
|
|
28
|
-
assets: Record<string, CloudinaryManifestEntry>;
|
|
29
|
-
}
|
|
30
|
-
export declare function loadCloudinaryManifest(): CloudinaryManifest | null;
|
|
31
|
-
/** Lookup keyed by `${campaign}/${email}/${filename}` for O(1) resolution during compile. */
|
|
32
|
-
export declare function indexManifestByCampaignEmailFile(manifest: CloudinaryManifest): Map<string, string>;
|
|
33
|
-
//# sourceMappingURL=cloudinary-manifest.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudinary-manifest.d.ts","sourceRoot":"","sources":["../../src/build/cloudinary-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,QAAsD,CAAA;AAEzF,MAAM,WAAW,uBAAuB;IACtC,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,4GAA4G;IAC5G,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;CAChD;AAED,wBAAgB,sBAAsB,IAAI,kBAAkB,GAAG,IAAI,CAOlE;AAED,6FAA6F;AAC7F,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQlG"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared manifest shape + path for the Cloudinary upload pipeline.
|
|
3
|
-
*
|
|
4
|
-
* `upload-assets.ts` writes this file; `compile.ts` reads it (if present) to swap a campaign
|
|
5
|
-
* asset's `src` for its hosted URL instead of inlining it as base64. Both import from here so the
|
|
6
|
-
* path and shape can never drift between writer and reader.
|
|
7
|
-
*/
|
|
8
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
-
import { dirname, resolve } from 'node:path';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
11
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const pkgDir = resolve(__dirname, '..', '..');
|
|
13
|
-
/** dist/ is gitignored — this is local, regenerable build output, not committed. */
|
|
14
|
-
export const cloudinaryManifestPath = resolve(pkgDir, 'dist', 'cloudinary-manifest.json');
|
|
15
|
-
export function loadCloudinaryManifest() {
|
|
16
|
-
if (!existsSync(cloudinaryManifestPath))
|
|
17
|
-
return null;
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(readFileSync(cloudinaryManifestPath, 'utf-8'));
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/** Lookup keyed by `${campaign}/${email}/${filename}` for O(1) resolution during compile. */
|
|
26
|
-
export function indexManifestByCampaignEmailFile(manifest) {
|
|
27
|
-
const index = new Map();
|
|
28
|
-
for (const entry of Object.values(manifest.assets)) {
|
|
29
|
-
const filename = entry.sourcePath.split('/').pop();
|
|
30
|
-
if (!filename)
|
|
31
|
-
continue;
|
|
32
|
-
index.set(`${entry.campaign}/${entry.email}/${filename}`, entry.url);
|
|
33
|
-
}
|
|
34
|
-
return index;
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=cloudinary-manifest.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudinary-manifest.js","sourceRoot":"","sources":["../../src/build/cloudinary-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;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;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAE7C,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,0BAA0B,CAAC,CAAA;AAwBzF,MAAM,UAAU,sBAAsB;IACpC,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC;QAAE,OAAO,IAAI,CAAA;IACpD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAuB,CAAA;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,gCAAgC,CAAC,QAA4B;IAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;QAClD,IAAI,CAAC,QAAQ;YAAE,SAAQ;QACvB,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,IAAI,QAAQ,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;IACtE,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
|
package/dist/build/compile.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MJML compile pipeline.
|
|
3
|
-
*
|
|
4
|
-
* Discovers the container, section previews, and full email compositions; compiles each with MJML;
|
|
5
|
-
* writes standalone HTML (+ Braze + static variants for emails) to dist/emails/, and a dist/catalog.json
|
|
6
|
-
* that Storybook and the docs read from.
|
|
7
|
-
*
|
|
8
|
-
* Run via tsx (not the emitted dist copy). Pass --watch to recompile on change.
|
|
9
|
-
*/
|
|
10
|
-
export {};
|
|
11
|
-
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/build/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|