@nxgt/mail-i18n 0.2.0 → 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/README.md CHANGED
@@ -88,6 +88,7 @@ file is how the editor learns them. See
88
88
  | `createTranslator(catalogues, getLanguage)` | `t(key, args?, language?)` outside templates, shaped like `@nxgt/i18n`, but it throws on a missing key |
89
89
  | `emailKey(email)` | Where an e-mail's messages live: `auth/reset-password` → `auth.resetPassword` |
90
90
  | `MANIFEST_FILE` | `'mail-manifest.json'`, the manifest's name in the output folder |
91
+ | `MANIFEST_FORMAT` | `1`, the manifest format this version writes as `formatVersion`: it changes only with the manifest's shape, and `@nxgt/mail`'s renderer reads every format up to its own within 0.x |
91
92
  | `WRAPPERS_DIR` | `'.maizzle/emails'`, where the generated files go |
92
93
  | `I18nOptions`, `Layout`, `TemplateSource` | The plugin's options, `'nested' \| 'flat'`, and a package's folder of templates for `templates` |
93
94
  | `Catalogue`, `Catalogues`, `ArgumentKind` | A catalogue as written, catalogues by locale, and `'string' \| 'number' \| 'date'` |
@@ -260,11 +261,13 @@ catalogues`. See [Catalogues](docs/guide/catalogues.md#the-subject).
260
261
  ### The manifest
261
262
 
262
263
  `dist/mail-manifest.json` is written by `maizzle build`, for the code that
263
- sends. For each e-mail, it records its placeholders, the ones a link or an
264
- image URL starts with, its subject in each locale, and its files:
264
+ sends. It starts with its format; then, for each e-mail, it records its
265
+ placeholders, the ones a link or an image URL starts with, its subject in each
266
+ locale, and its files:
265
267
 
266
268
  ```json
267
269
  {
270
+ "formatVersion": 1,
268
271
  "locales": ["en", "fr"],
269
272
  "fallbackLocale": "en",
270
273
  "emails": {
@@ -286,7 +289,9 @@ image URL starts with, its subject in each locale, and its files:
286
289
 
287
290
  `createMailRenderer` from `@nxgt/mail/renderer` reads it at send time:
288
291
  `createMailRenderer({ dir: 'dist' }).render('verify-email', { name, link })`
289
- answers the subject, HTML and text, every value escaped.
292
+ answers the subject, HTML and text, every value escaped. Within 0.x, a newer
293
+ `@nxgt/mail` reads a build from any earlier `@nxgt/mail-i18n`: see
294
+ [The manifest — `formatVersion`](docs/guide/manifest.md#formatversion).
290
295
 
291
296
  After the manifest, each build writes `generated/mail.ts`, in the project — the manifest's e-mails
292
297
  and variables as a type, rewritten only when they change. **Git-ignore it**
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import './vue';
19
19
  export type { ArgumentKind, Catalogue, Catalogues, } from './catalogues';
20
- export { emailKey, type Manifest, type ManifestEmail, } from './manifest';
20
+ export { emailKey, MANIFEST_FORMAT, type Manifest, type ManifestEmail, } from './manifest';
21
21
  export { type I18nOptions, i18n, MANIFEST_FILE, WRAPPERS_DIR, } from './plugin';
22
22
  export type { TemplateSource } from './sources';
23
23
  export { createTranslator, type LanguageProvider, type MessageArgs, type Translate, } from './translator';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,OAAO,CAAC;AAEf,YAAY,EACX,YAAY,EACZ,SAAS,EACT,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,aAAa,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,KAAK,WAAW,EAChB,IAAI,EACJ,aAAa,EACb,YAAY,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACN,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACzE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,OAAO,CAAC;AAEf,YAAY,EACX,YAAY,EACZ,SAAS,EACT,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,QAAQ,EACR,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,KAAK,WAAW,EAChB,IAAI,EACJ,aAAa,EACb,YAAY,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACN,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACzE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -186,6 +186,7 @@ function watchTemplates(emailsDir, regenerate) {
186
186
  }
187
187
 
188
188
  // src/manifest.ts
189
+ var MANIFEST_FORMAT = 1;
189
190
  var PLACEHOLDER = /\{\{\s*([a-z][a-zA-Z0-9]*)\s*\}\}/g;
190
191
  var URL_ATTRIBUTE = /\s(?:href|src|background|poster|action)\s*=\s*(?:"\s*(\{\{[^"]*)"|'\s*(\{\{[^']*)')/gi;
191
192
  var placeholderMark = (name) => `{{ ${name} }}`;
@@ -267,6 +268,7 @@ function buildManifest(options) {
267
268
  };
268
269
  }
269
270
  return {
271
+ formatVersion: MANIFEST_FORMAT,
270
272
  locales: [...locales],
271
273
  fallbackLocale: options.fallbackLocale,
272
274
  emails
@@ -665,11 +667,12 @@ function i18n(options) {
665
667
  }
666
668
  export {
667
669
  MANIFEST_FILE,
670
+ MANIFEST_FORMAT,
668
671
  WRAPPERS_DIR,
669
672
  createTranslator,
670
673
  emailKey,
671
674
  i18n
672
675
  };
673
676
 
674
- //# debugId=8EAF60F48839FE4D64756E2164756E21
677
+ //# debugId=3C814EA0EFDDBF5664756E2164756E21
675
678
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,7 +2,7 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/manifest.ts", "../src/translator.ts", "../src/wrappers.ts", "../src/plugin.ts", "../src/catalogues.ts", "../src/sources.ts", "../src/template.ts", "../src/types.ts"],
4
4
  "sourcesContent": [
5
- "import { readFileSync } from 'node:fs';\nimport { isAbsolute, join, relative, sep } from 'node:path';\nimport type { Messages } from './catalogues';\nimport { createFormatter } from './translator';\nimport { type Entry, entryPath, type Layout, parseEntry } from './wrappers';\n\n/** One e-mail, as the renderer reads it. */\nexport interface ManifestEmail {\n\t/** Every placeholder of the e-mail, in any locale, sorted. */\n\treadonly variables: readonly string[];\n\t/**\n\t * The placeholders a URL attribute starts with — `href`, `src`,\n\t * `background`, `poster`, `action`: they decide the scheme, so a URL fills\n\t * them. One later in the value, as `?token={{ token }}`, is not one.\n\t */\n\treadonly urlVariables: readonly string[];\n\t/** The subject per locale, its placeholders kept as `{{ name }}`. */\n\treadonly subject: Readonly<Record<string, string>>;\n\t/** The built files per locale, relative to the output folder. */\n\treadonly files: Readonly<\n\t\tRecord<string, { readonly html: string; readonly text: string | null }>\n\t>;\n}\n\n/** `dist/mail-manifest.json`: what the build wrote, for the renderer. */\nexport interface Manifest {\n\treadonly locales: readonly string[];\n\treadonly fallbackLocale: string;\n\treadonly emails: Readonly<Record<string, ManifestEmail>>;\n}\n\n// Copied in packages/mail/src/renderer.ts, which reads this manifest: change both.\nconst PLACEHOLDER = /\\{\\{\\s*([a-z][a-zA-Z0-9]*)\\s*\\}\\}/g;\n/** An attribute that holds a URL, its value starting with a placeholder: that placeholder is the whole scheme. */\nconst URL_ATTRIBUTE =\n\t/\\s(?:href|src|background|poster|action)\\s*=\\s*(?:\"\\s*(\\{\\{[^\"]*)\"|'\\s*(\\{\\{[^']*)')/gi;\n\n/** `{{ name }}` — what `placeholder('name')` writes. */\nexport const placeholderMark = (name: string) => `{{ ${name} }}`;\n\nconst placeholdersIn = (text: string) =>\n\t[...text.matchAll(PLACEHOLDER)].map((match) => match[1] as string);\n\n/** `auth/reset-password` → `auth.resetPassword`: where its messages live. */\nexport const emailKey = (email: string) =>\n\temail\n\t\t.split('/')\n\t\t.map((segment) =>\n\t\t\tsegment.replace(/-([a-z0-9])/g, (_, char: string) => char.toUpperCase()),\n\t\t)\n\t\t.join('.');\n\n/**\n * The subject of `email` in `locale`: the message `<emailKey>.subject`, each\n * argument a placeholder. A missing subject, or one with an argument that is\n * not a string, **throws**.\n */\nfunction subjectOf(\n\temail: string,\n\tlocale: string,\n\tmessages: Messages,\n\tformat: ReturnType<typeof createFormatter>,\n): string {\n\tconst key = `${emailKey(email)}.subject`;\n\tconst message = messages.get(key);\n\tif (message === undefined) {\n\t\tthrow new Error(\n\t\t\t`i18n: ${email} has no subject — add ${key} to the catalogues`,\n\t\t);\n\t}\n\tconst args: Record<string, string> = {};\n\tfor (const [name, kind] of message.args) {\n\t\tif (message.selects.has(name)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${locale}: ${key} chooses on {${name}} with a select — a subject's arguments are placeholders, which always choose other`,\n\t\t\t);\n\t\t}\n\t\tif (kind !== 'string') {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${locale}: ${key} uses {${name}} as a ${kind} — a subject's arguments are placeholders, filled at send time as strings`,\n\t\t\t);\n\t\t}\n\t\targs[name] = placeholderMark(name);\n\t}\n\treturn format(locale, key, message.text, args);\n}\n\n/** One e-mail in one locale, as found in the build's files. */\ninterface Built {\n\treadonly entry: Entry;\n\thtml: string | null;\n\ttext: string | null;\n}\n\nconst sorted = (values: Iterable<string>) => [...new Set(values)].sort();\n\n/**\n * Reads what the build wrote — `files`, absolute, under `outputDir` — and\n * answers the manifest: for each e-mail its placeholders, those in a URL, its\n * subject per locale and its files.\n */\nexport function buildManifest(options: {\n\treadonly files: readonly string[];\n\treadonly outputDir: string;\n\treadonly htmlExtension: string;\n\treadonly layout: Layout;\n\treadonly locales: readonly string[];\n\treadonly fallbackLocale: string;\n\treadonly messages: ReadonlyMap<string, Messages>;\n}): Manifest {\n\tconst { layout, locales } = options;\n\tconst format = createFormatter('i18n');\n\tconst found = new Map<string, Built>();\n\tfor (const file of options.files) {\n\t\tconst path = relative(options.outputDir, file).split(sep).join('/');\n\t\tif (path.startsWith('../') || isAbsolute(path)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${path} was written outside the output folder — the i18n plugin lays out every e-mail; set no plaintext.destination and no output path in a template`,\n\t\t\t);\n\t\t}\n\t\tconst dot = path.lastIndexOf('.');\n\t\tconst base = path.slice(0, Math.max(dot, 0));\n\t\tconst entry = dot > 0 ? parseEntry(base, layout, locales) : null;\n\t\tif (entry === null) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${path} is not where the i18n plugin puts an e-mail — set no output path in a template`,\n\t\t\t);\n\t\t}\n\t\tconst seen = found.get(base) ?? { entry, html: null, text: null };\n\t\tif (path.slice(dot + 1) === options.htmlExtension) seen.html = path;\n\t\telse seen.text = path;\n\t\tfound.set(base, seen);\n\t}\n\n\tconst emails: Record<string, ManifestEmail> = {};\n\tfor (const email of sorted(\n\t\t[...found.values()].map((seen) => seen.entry.email),\n\t)) {\n\t\tconst variables: string[] = [];\n\t\tconst urlVariables: string[] = [];\n\t\tconst subject: Record<string, string> = {};\n\t\tconst files: Record<string, { html: string; text: string | null }> = {};\n\t\tfor (const locale of locales) {\n\t\t\tconst seen = found.get(entryPath({ email, locale }, layout));\n\t\t\tif (seen?.html == null) {\n\t\t\t\tthrow new Error(`i18n: ${email} was not built in ${locale}`);\n\t\t\t}\n\t\t\tconst html = readFileSync(join(options.outputDir, seen.html), 'utf8');\n\t\t\t// Vue renders an unresolved component as nothing, and Maizzle still\n\t\t\t// writes the doctype: the build would pass with an empty e-mail.\n\t\t\tif (html.replace(/<!doctype[^>]*>/i, '').trim() === '') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`i18n: ${seen.html} is empty — a tag of its template resolved to no component; list the plugin that brings it, as ui()`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tvariables.push(...placeholdersIn(html));\n\t\t\tfor (const match of html.matchAll(URL_ATTRIBUTE)) {\n\t\t\t\turlVariables.push(\n\t\t\t\t\t...placeholdersIn(match[1] ?? match[2] ?? '').slice(0, 1),\n\t\t\t\t);\n\t\t\t}\n\t\t\t// A <Plaintext> block is in the text part only.\n\t\t\tif (seen.text !== null) {\n\t\t\t\tconst text = readFileSync(join(options.outputDir, seen.text), 'utf8');\n\t\t\t\tvariables.push(...placeholdersIn(text));\n\t\t\t}\n\t\t\tsubject[locale] = subjectOf(\n\t\t\t\temail,\n\t\t\t\tlocale,\n\t\t\t\toptions.messages.get(locale) as Messages,\n\t\t\t\tformat,\n\t\t\t);\n\t\t\tvariables.push(...placeholdersIn(subject[locale]));\n\t\t\tfiles[locale] = { html: seen.html, text: seen.text };\n\t\t}\n\t\temails[email] = {\n\t\t\tvariables: sorted(variables),\n\t\t\turlVariables: sorted(urlVariables),\n\t\t\tsubject,\n\t\t\tfiles,\n\t\t};\n\t}\n\treturn {\n\t\tlocales: [...locales],\n\t\tfallbackLocale: options.fallbackLocale,\n\t\temails,\n\t};\n}\n",
5
+ "import { readFileSync } from 'node:fs';\nimport { isAbsolute, join, relative, sep } from 'node:path';\nimport type { Messages } from './catalogues';\nimport { createFormatter } from './translator';\nimport { type Entry, entryPath, type Layout, parseEntry } from './wrappers';\n\n/** One e-mail, as the renderer reads it. */\nexport interface ManifestEmail {\n\t/** Every placeholder of the e-mail, in any locale, sorted. */\n\treadonly variables: readonly string[];\n\t/**\n\t * The placeholders a URL attribute starts with — `href`, `src`,\n\t * `background`, `poster`, `action`: they decide the scheme, so a URL fills\n\t * them. One later in the value, as `?token={{ token }}`, is not one.\n\t */\n\treadonly urlVariables: readonly string[];\n\t/** The subject per locale, its placeholders kept as `{{ name }}`. */\n\treadonly subject: Readonly<Record<string, string>>;\n\t/** The built files per locale, relative to the output folder. */\n\treadonly files: Readonly<\n\t\tRecord<string, { readonly html: string; readonly text: string | null }>\n\t>;\n}\n\n/**\n * The manifest's format. It changes only with the manifest's shape, and\n * `@nxgt/mail`'s renderer reads every format up to its own within 0.x: a\n * build from an older `@nxgt/mail-i18n` keeps working with a newer renderer.\n * Copied in packages/mail/src/renderer.ts: change both.\n */\nexport const MANIFEST_FORMAT = 1;\n\n/** `dist/mail-manifest.json`: what the build wrote, for the renderer. */\nexport interface Manifest {\n\t/**\n\t * {@link MANIFEST_FORMAT} when built, and the first key written. This type\n\t * is what this version writes: a manifest from `@nxgt/mail-i18n` 0.1 or\n\t * 0.2 has no such field, and the renderer reads it as format 1.\n\t */\n\treadonly formatVersion: number;\n\treadonly locales: readonly string[];\n\treadonly fallbackLocale: string;\n\treadonly emails: Readonly<Record<string, ManifestEmail>>;\n}\n\n// Copied in packages/mail/src/renderer.ts, which reads this manifest: change both.\nconst PLACEHOLDER = /\\{\\{\\s*([a-z][a-zA-Z0-9]*)\\s*\\}\\}/g;\n/** An attribute that holds a URL, its value starting with a placeholder: that placeholder is the whole scheme. */\nconst URL_ATTRIBUTE =\n\t/\\s(?:href|src|background|poster|action)\\s*=\\s*(?:\"\\s*(\\{\\{[^\"]*)\"|'\\s*(\\{\\{[^']*)')/gi;\n\n/** `{{ name }}` — what `placeholder('name')` writes. */\nexport const placeholderMark = (name: string) => `{{ ${name} }}`;\n\nconst placeholdersIn = (text: string) =>\n\t[...text.matchAll(PLACEHOLDER)].map((match) => match[1] as string);\n\n/** `auth/reset-password` → `auth.resetPassword`: where its messages live. */\nexport const emailKey = (email: string) =>\n\temail\n\t\t.split('/')\n\t\t.map((segment) =>\n\t\t\tsegment.replace(/-([a-z0-9])/g, (_, char: string) => char.toUpperCase()),\n\t\t)\n\t\t.join('.');\n\n/**\n * The subject of `email` in `locale`: the message `<emailKey>.subject`, each\n * argument a placeholder. A missing subject, or one with an argument that is\n * not a string, **throws**.\n */\nfunction subjectOf(\n\temail: string,\n\tlocale: string,\n\tmessages: Messages,\n\tformat: ReturnType<typeof createFormatter>,\n): string {\n\tconst key = `${emailKey(email)}.subject`;\n\tconst message = messages.get(key);\n\tif (message === undefined) {\n\t\tthrow new Error(\n\t\t\t`i18n: ${email} has no subject — add ${key} to the catalogues`,\n\t\t);\n\t}\n\tconst args: Record<string, string> = {};\n\tfor (const [name, kind] of message.args) {\n\t\tif (message.selects.has(name)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${locale}: ${key} chooses on {${name}} with a select — a subject's arguments are placeholders, which always choose other`,\n\t\t\t);\n\t\t}\n\t\tif (kind !== 'string') {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${locale}: ${key} uses {${name}} as a ${kind} — a subject's arguments are placeholders, filled at send time as strings`,\n\t\t\t);\n\t\t}\n\t\targs[name] = placeholderMark(name);\n\t}\n\treturn format(locale, key, message.text, args);\n}\n\n/** One e-mail in one locale, as found in the build's files. */\ninterface Built {\n\treadonly entry: Entry;\n\thtml: string | null;\n\ttext: string | null;\n}\n\nconst sorted = (values: Iterable<string>) => [...new Set(values)].sort();\n\n/**\n * Reads what the build wrote — `files`, absolute, under `outputDir` — and\n * answers the manifest: for each e-mail its placeholders, those in a URL, its\n * subject per locale and its files.\n */\nexport function buildManifest(options: {\n\treadonly files: readonly string[];\n\treadonly outputDir: string;\n\treadonly htmlExtension: string;\n\treadonly layout: Layout;\n\treadonly locales: readonly string[];\n\treadonly fallbackLocale: string;\n\treadonly messages: ReadonlyMap<string, Messages>;\n}): Manifest {\n\tconst { layout, locales } = options;\n\tconst format = createFormatter('i18n');\n\tconst found = new Map<string, Built>();\n\tfor (const file of options.files) {\n\t\tconst path = relative(options.outputDir, file).split(sep).join('/');\n\t\tif (path.startsWith('../') || isAbsolute(path)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${path} was written outside the output folder — the i18n plugin lays out every e-mail; set no plaintext.destination and no output path in a template`,\n\t\t\t);\n\t\t}\n\t\tconst dot = path.lastIndexOf('.');\n\t\tconst base = path.slice(0, Math.max(dot, 0));\n\t\tconst entry = dot > 0 ? parseEntry(base, layout, locales) : null;\n\t\tif (entry === null) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${path} is not where the i18n plugin puts an e-mail — set no output path in a template`,\n\t\t\t);\n\t\t}\n\t\tconst seen = found.get(base) ?? { entry, html: null, text: null };\n\t\tif (path.slice(dot + 1) === options.htmlExtension) seen.html = path;\n\t\telse seen.text = path;\n\t\tfound.set(base, seen);\n\t}\n\n\tconst emails: Record<string, ManifestEmail> = {};\n\tfor (const email of sorted(\n\t\t[...found.values()].map((seen) => seen.entry.email),\n\t)) {\n\t\tconst variables: string[] = [];\n\t\tconst urlVariables: string[] = [];\n\t\tconst subject: Record<string, string> = {};\n\t\tconst files: Record<string, { html: string; text: string | null }> = {};\n\t\tfor (const locale of locales) {\n\t\t\tconst seen = found.get(entryPath({ email, locale }, layout));\n\t\t\tif (seen?.html == null) {\n\t\t\t\tthrow new Error(`i18n: ${email} was not built in ${locale}`);\n\t\t\t}\n\t\t\tconst html = readFileSync(join(options.outputDir, seen.html), 'utf8');\n\t\t\t// Vue renders an unresolved component as nothing, and Maizzle still\n\t\t\t// writes the doctype: the build would pass with an empty e-mail.\n\t\t\tif (html.replace(/<!doctype[^>]*>/i, '').trim() === '') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`i18n: ${seen.html} is empty — a tag of its template resolved to no component; list the plugin that brings it, as ui()`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tvariables.push(...placeholdersIn(html));\n\t\t\tfor (const match of html.matchAll(URL_ATTRIBUTE)) {\n\t\t\t\turlVariables.push(\n\t\t\t\t\t...placeholdersIn(match[1] ?? match[2] ?? '').slice(0, 1),\n\t\t\t\t);\n\t\t\t}\n\t\t\t// A <Plaintext> block is in the text part only.\n\t\t\tif (seen.text !== null) {\n\t\t\t\tconst text = readFileSync(join(options.outputDir, seen.text), 'utf8');\n\t\t\t\tvariables.push(...placeholdersIn(text));\n\t\t\t}\n\t\t\tsubject[locale] = subjectOf(\n\t\t\t\temail,\n\t\t\t\tlocale,\n\t\t\t\toptions.messages.get(locale) as Messages,\n\t\t\t\tformat,\n\t\t\t);\n\t\t\tvariables.push(...placeholdersIn(subject[locale]));\n\t\t\tfiles[locale] = { html: seen.html, text: seen.text };\n\t\t}\n\t\temails[email] = {\n\t\t\tvariables: sorted(variables),\n\t\t\turlVariables: sorted(urlVariables),\n\t\t\tsubject,\n\t\t\tfiles,\n\t\t};\n\t}\n\treturn {\n\t\tformatVersion: MANIFEST_FORMAT,\n\t\tlocales: [...locales],\n\t\tfallbackLocale: options.fallbackLocale,\n\t\temails,\n\t};\n}\n",
6
6
  "import { IntlMessageFormat } from 'intl-messageformat';\nimport type { Catalogue, Catalogues } from './catalogues';\n\n/** The values a message's arguments take: `{ name: 'Ada', count: 3 }`. */\nexport type MessageArgs = Readonly<Record<string, string | number | Date>>;\n\n/** A locale, or a function that answers it at each call — as in `@nxgt/i18n`. */\nexport type LanguageProvider = string | (() => string);\n\n/** `t(key, args?, language?)`: the message `key`, formatted in the language. */\nexport type Translate = (\n\tkey: string,\n\targs?: MessageArgs,\n\tlanguage?: LanguageProvider,\n) => string;\n\nfunction lookup(catalogue: Catalogue, key: string): string | null {\n\tlet node: string | Catalogue | undefined = catalogue;\n\tfor (const segment of key.split('.')) {\n\t\tif (typeof node !== 'object' || !Object.hasOwn(node, segment)) return null;\n\t\tnode = node[segment];\n\t}\n\treturn typeof node === 'string' ? node : null;\n}\n\nconst resolveLanguage = (language: LanguageProvider): unknown =>\n\ttypeof language === 'function' ? language() : language;\n\n/**\n * Formats with a cache of compiled messages, one per locale and key. A\n * message that does not format **throws**, the formatter's error as the\n * cause.\n */\nexport function createFormatter(prefix: string) {\n\tconst compiled = new Map<string, IntlMessageFormat>();\n\treturn (locale: string, key: string, text: string, args?: MessageArgs) => {\n\t\tconst id = `${locale}\\u0000${key}`;\n\t\ttry {\n\t\t\tlet format = compiled.get(id);\n\t\t\tif (format === undefined) {\n\t\t\t\tformat = new IntlMessageFormat(text, locale, undefined, {\n\t\t\t\t\tignoreTag: true,\n\t\t\t\t});\n\t\t\t\tcompiled.set(id, format);\n\t\t\t}\n\t\t\treturn String(format.format(args));\n\t\t} catch (cause) {\n\t\t\tthrow new Error(`${prefix}: ${locale}: ${key} could not be formatted`, {\n\t\t\t\tcause,\n\t\t\t});\n\t\t}\n\t};\n}\n\n/**\n * The translator of `@nxgt/i18n`, for mail: `createTranslator(catalogues,\n * getLanguage)` answers `t(key, args?, language?)`.\n *\n * Where `@nxgt/i18n` answers the key, this **throws**: a key the language's\n * catalogue does not have, a language with no catalogue, and a message that\n * does not format. An e-mail is not sent with a key in it.\n *\n * ```ts\n * import en from './locales/en.json';\n * import fr from './locales/fr.json';\n *\n * const t = createTranslator({ en, fr }, () => pickLocale(user.locale, ['en', 'fr'], 'en'));\n * t('verifyEmail.subject');\n * ```\n */\nexport function createTranslator(\n\tcatalogues: Catalogues,\n\tgetLanguage: LanguageProvider,\n): Translate {\n\tif (typeof catalogues !== 'object' || catalogues === null) {\n\t\tthrow new TypeError(\n\t\t\t'createTranslator: catalogues must be an object of catalogues by locale, as { en, fr }',\n\t\t);\n\t}\n\tif (typeof getLanguage !== 'string' && typeof getLanguage !== 'function') {\n\t\tthrow new TypeError(\n\t\t\t'createTranslator: getLanguage must be a locale or a function that answers one',\n\t\t);\n\t}\n\tconst format = createFormatter('t');\n\treturn (key, args, language = getLanguage) => {\n\t\tconst locale = resolveLanguage(language);\n\t\tif (typeof locale !== 'string' || !Object.hasOwn(catalogues, locale)) {\n\t\t\tthrow new Error(\n\t\t\t\t't: the language is not a locale of the catalogues — pick one with pickLocale',\n\t\t\t);\n\t\t}\n\t\tconst text = lookup(catalogues[locale] as Catalogue, key);\n\t\tif (text === null) throw new Error(`t: ${locale}: ${key} is not a key`);\n\t\treturn format(locale, key, text, args);\n\t};\n}\n",
7
7
  "import {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { dirname, join, relative, sep } from 'node:path';\n\n/**\n * Where each locale's output goes: `nested` writes `en/verify-email.html`,\n * `flat` writes `verify-email.en.html`.\n */\nexport type Layout = 'nested' | 'flat';\n\n/** One e-mail in one locale: `{ email: 'auth/reset-password', locale: 'fr' }`. */\nexport interface Entry {\n\treadonly email: string;\n\treadonly locale: string;\n}\n\nconst NAME = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\n\nconst posix = (path: string) => path.split(sep).join('/');\n\n/** Every `.vue` file under `dir`, as a slash-separated path without `.vue`. */\nfunction listEmails(dir: string, label: string): string[] {\n\tif (!existsSync(dir)) return [];\n\treturn readdirSync(dir, { recursive: true, encoding: 'utf8' })\n\t\t.filter((file) => file.endsWith('.vue'))\n\t\t.map((file) => {\n\t\t\tconst email = posix(file).slice(0, -'.vue'.length);\n\t\t\tfor (const segment of email.split('/')) {\n\t\t\t\tif (!NAME.test(segment)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`i18n: ${label}/${email}.vue is not a kebab-case name — name a template as verify-email.vue`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn email;\n\t\t})\n\t\t.sort();\n}\n\n/** The path of `entry`'s file under a folder laid out as `layout`, without an extension. */\nexport function entryPath(entry: Entry, layout: Layout): string {\n\treturn layout === 'nested'\n\t\t? `${entry.locale}/${entry.email}`\n\t\t: `${entry.email}.${entry.locale}`;\n}\n\n/**\n * Reads back what {@link entryPath} wrote — `path` relative to its folder,\n * slash-separated, without an extension — or `null` for a path that is not\n * one e-mail in one of `locales`.\n */\nexport function parseEntry(\n\tpath: string,\n\tlayout: Layout,\n\tlocales: readonly string[],\n): Entry | null {\n\tif (layout === 'nested') {\n\t\tconst [locale, ...rest] = path.split('/');\n\t\tif (locale === undefined || rest.length === 0) return null;\n\t\treturn locales.includes(locale) ? { email: rest.join('/'), locale } : null;\n\t}\n\tconst dot = path.lastIndexOf('.');\n\tconst locale = path.slice(dot + 1);\n\treturn dot > 0 && locales.includes(locale)\n\t\t? { email: path.slice(0, dot), locale }\n\t\t: null;\n}\n\nfunction wrapperSource(wrapper: string, template: string): string {\n\tconst from = posix(relative(dirname(wrapper), template));\n\treturn [\n\t\t'<!-- Generated by @nxgt/mail-i18n: one per template and locale. Never edited, never committed. -->',\n\t\t'<script setup>',\n\t\t`import Email from '${from.startsWith('.') ? from : `./${from}`}';`,\n\t\t'</script>',\n\t\t'<template><Email /></template>',\n\t\t'',\n\t].join('\\n');\n}\n\n/** Every file under `dir`, absolute. */\nfunction listFiles(dir: string): string[] {\n\tif (!existsSync(dir)) return [];\n\treturn readdirSync(dir, { recursive: true, encoding: 'utf8' })\n\t\t.map((file) => join(dir, file))\n\t\t.filter((file) => file.endsWith('.vue'));\n}\n\n/**\n * A folder of templates. `label` names it in an error: `emails`, or\n * `templates[0]` for a package's. `only`, when given, keeps those e-mails of\n * the folder and no other. A `packaged` folder — a package's — must hold\n * templates, and shares no name with another package's.\n */\nexport interface TemplateFolder {\n\treadonly dir: string;\n\treadonly label: string;\n\treadonly only?: readonly string[];\n\treadonly packaged?: boolean;\n}\n\n/** The e-mails of `folder`, the ones it keeps, checked. */\nfunction folderEmails({\n\tdir,\n\tlabel,\n\tonly,\n\tpackaged,\n}: TemplateFolder): string[] {\n\tconst emails = listEmails(dir, label);\n\tif (packaged && emails.length === 0) {\n\t\tthrow new Error(\n\t\t\t`i18n: ${label} holds no template — is ${dir} the folder of a package's e-mails?`,\n\t\t);\n\t}\n\tfor (const email of only ?? []) {\n\t\tif (!emails.includes(email)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${label} has no template ${email}.vue — name one of its e-mails`,\n\t\t\t);\n\t\t}\n\t}\n\treturn [...(only ?? emails)];\n}\n\n/**\n * Each e-mail of `folders` and its file. The project's folder, first, wins\n * over a package's; two packages with the same e-mail **throw**, since\n * neither would be the obvious one.\n */\nfunction collectTemplates(\n\tfolders: readonly TemplateFolder[],\n): Map<string, string> {\n\tconst templates = new Map<string, string>();\n\tconst owners = new Map<string, TemplateFolder>();\n\tfor (const folder of folders) {\n\t\tfor (const email of folderEmails(folder)) {\n\t\t\tconst owner = owners.get(email);\n\t\t\tif (owner === undefined) {\n\t\t\t\towners.set(email, folder);\n\t\t\t\ttemplates.set(email, join(folder.dir, `${email}.vue`));\n\t\t\t} else if (owner.packaged) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`i18n: ${owner.label} and ${folder.label} both have ${email}.vue — keep one with emails: [...], or write the project's own in its folder`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\treturn templates;\n}\n\n/**\n * Writes one wrapper per template of `folders` and locale under\n * `wrappersDir` — the project's folder first, so its template replaces a\n * package's of the same name — each only when its text changed, and removes\n * the wrappers of templates that are gone, so a running dev server sees a\n * change only where there is one. Answers the e-mails, sorted.\n */\nexport function writeWrappers(options: {\n\treadonly folders: readonly TemplateFolder[];\n\treadonly wrappersDir: string;\n\treadonly locales: readonly string[];\n\treadonly layout: Layout;\n}): string[] {\n\tconst { wrappersDir, locales, layout } = options;\n\tconst templates = collectTemplates(options.folders);\n\tconst wanted = new Set<string>();\n\tfor (const [email, template] of templates) {\n\t\tfor (const locale of locales) {\n\t\t\tconst wrapper = join(\n\t\t\t\twrappersDir,\n\t\t\t\t`${entryPath({ email, locale }, layout)}.vue`,\n\t\t\t);\n\t\t\twanted.add(wrapper);\n\t\t\tconst source = wrapperSource(wrapper, template);\n\t\t\tif (existsSync(wrapper) && readFileSync(wrapper, 'utf8') === source) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmkdirSync(dirname(wrapper), { recursive: true });\n\t\t\twriteFileSync(wrapper, source);\n\t\t}\n\t}\n\tfor (const file of listFiles(wrappersDir)) {\n\t\tif (!wanted.has(file)) rmSync(file);\n\t}\n\treturn [...templates.keys()].sort();\n}\n\n/** The part of Vite's dev server the watcher uses. */\ninterface WatchedServer {\n\treadonly watcher: {\n\t\tadd(path: string): void;\n\t\ton(event: 'add' | 'unlink', listener: (file: string) => void): void;\n\t};\n}\n\n/**\n * A Vite plugin for Maizzle's renderer: under `maizzle serve`, a template\n * added to or removed from `emailsDir` gets its wrappers at once, so the\n * preview lists it without a restart. A template the build would refuse is\n * reported, never thrown: an error in a watcher would stop the server.\n */\nexport function watchTemplates(emailsDir: string, regenerate: () => void) {\n\treturn {\n\t\tname: 'nxgt-mail-i18n:wrappers',\n\t\tconfigureServer(server: WatchedServer) {\n\t\t\tserver.watcher.add(emailsDir);\n\t\t\tconst onTemplate = (file: string) => {\n\t\t\t\tif (!file.startsWith(emailsDir + sep) || !file.endsWith('.vue')) return;\n\t\t\t\ttry {\n\t\t\t\t\tregenerate();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(error instanceof Error ? error.message : error);\n\t\t\t\t}\n\t\t\t};\n\t\t\tserver.watcher.on('add', onTemplate);\n\t\t\tserver.watcher.on('unlink', onTemplate);\n\t\t},\n\t};\n}\n",
8
8
  "import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join, relative, resolve, sep } from 'node:path';\nimport { isMainThread } from 'node:worker_threads';\nimport { defineMailPlugin, type MailPlugin } from '@nxgt/mail-config';\nimport {\n\ttype Catalogue,\n\ttype Catalogues,\n\tcheckCatalogues,\n\tlayerCatalogues,\n\ttype Messages,\n} from './catalogues';\nimport { buildManifest } from './manifest';\nimport {\n\tcheckTemplates,\n\ttype TemplateSource,\n\ttemplateFolders,\n} from './sources';\nimport { templateProperties } from './template';\nimport { createFormatter } from './translator';\nimport {\n\tRENDERER_TYPES_FILE,\n\trendererTypes,\n\tTYPES_FILE,\n\ttemplateTypes,\n\twriteIfChanged,\n\twriteRendererTypes,\n} from './types';\nimport {\n\ttype Layout,\n\tparseEntry,\n\twatchTemplates,\n\twriteWrappers,\n} from './wrappers';\n\nexport interface I18nOptions {\n\t/** Every locale the project writes, as BCP 47 tags: `['en', 'fr']`. */\n\treadonly locales: readonly string[];\n\t/** The reference every other locale is checked against. Default the first locale. */\n\treadonly fallbackLocale?: string;\n\t/** The folder of `<locale>.json` catalogues. Default `locales`. */\n\treadonly dir?: string;\n\t/** The folder of templates. Default `emails`. */\n\treadonly emails?: string;\n\t/** `nested` writes `dist/en/verify-email.html`; `flat` writes `dist/verify-email.en.html`. Default `nested`. */\n\treadonly layout?: Layout;\n\t/**\n\t * Catalogues under the project's own, as a package ships them —\n\t * `[uiCatalogues]` from `@nxgt/mail-ui`. Each is merged key by key under\n\t * the next, and the project's `<locale>.json` over all of them.\n\t */\n\treadonly catalogues?: readonly Catalogues[];\n\t/**\n\t * Folders of templates under the project's own, as a package ships them —\n\t * `presets().templates` from `@nxgt/mail-presets`. A template in the\n\t * project's `emails/` replaces a package's of the same name.\n\t */\n\treadonly templates?: readonly TemplateSource[];\n\t/**\n\t * The module typing the renderer, written after each build: `MailEmails`,\n\t * for `createMailRenderer<MailEmails>(…)` in the code that sends. A path\n\t * from where `maizzle` runs — outside the project too, as\n\t * `../api/src/generated/mail.ts` — or `false` to write none. Default\n\t * `generated/mail.ts`.\n\t */\n\treadonly rendererTypes?: string | false;\n}\n\n/** Where the wrappers go, under the project. */\nexport const WRAPPERS_DIR = '.maizzle/emails';\n\n/** The manifest's name, in the output folder. */\nexport const MANIFEST_FILE = 'mail-manifest.json';\n\nconst LOCALE = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value);\n\nfunction checkOptions(options: I18nOptions): void {\n\tif (typeof options !== 'object' || options === null) {\n\t\tthrow new TypeError(\n\t\t\t\"i18n: options must be an object, as { locales: ['en', 'fr'] }\",\n\t\t);\n\t}\n\tconst { locales } = options;\n\tif (!Array.isArray(locales) || locales.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t\"i18n: locales must hold at least one locale, as ['en', 'fr']\",\n\t\t);\n\t}\n\tfor (const locale of locales) {\n\t\tif (typeof locale !== 'string' || !LOCALE.test(locale)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'i18n: locales holds something that is not a locale — write each as a BCP 47 tag, as en or pt-BR',\n\t\t\t);\n\t\t}\n\t}\n\tif (new Set(locales).size !== locales.length) {\n\t\tthrow new TypeError('i18n: locales holds the same locale twice');\n\t}\n\tif (\n\t\toptions.fallbackLocale !== undefined &&\n\t\t!locales.includes(options.fallbackLocale)\n\t) {\n\t\tthrow new TypeError('i18n: fallbackLocale must be one of locales');\n\t}\n\tfor (const key of ['dir', 'emails'] as const) {\n\t\tconst value = options[key];\n\t\tif (value !== undefined && (typeof value !== 'string' || value === '')) {\n\t\t\tthrow new TypeError(`i18n: ${key} must be a folder of the project`);\n\t\t}\n\t}\n\tif (\n\t\toptions.layout !== undefined &&\n\t\toptions.layout !== 'nested' &&\n\t\toptions.layout !== 'flat'\n\t) {\n\t\tthrow new TypeError(\"i18n: layout must be 'nested' or 'flat'\");\n\t}\n\tconst { catalogues } = options;\n\tif (\n\t\tcatalogues !== undefined &&\n\t\t(!Array.isArray(catalogues) ||\n\t\t\t!catalogues.every(\n\t\t\t\t(source) => isObject(source) && Object.values(source).every(isObject),\n\t\t\t))\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'i18n: catalogues must be a list of catalogues by locale, as [{ en: {...}, fr: {...} }]',\n\t\t);\n\t}\n\tconst typesPath = options.rendererTypes;\n\tif (\n\t\ttypesPath !== undefined &&\n\t\ttypesPath !== false &&\n\t\t(typeof typesPath !== 'string' || !typesPath.endsWith('.ts'))\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'i18n: rendererTypes must be the path of a .ts file, as generated/mail.ts, or false',\n\t\t);\n\t}\n\tcheckTemplates(options.templates);\n}\n\n/** Reads `<dir>/<locale>.json` for each locale. A missing or broken file **throws**. */\nfunction readCatalogues(\n\tdir: string,\n\tdirName: string,\n\tlocales: readonly string[],\n): Record<string, Catalogue> {\n\tconst out: Record<string, Catalogue> = {};\n\tfor (const locale of locales) {\n\t\tconst file = join(dir, `${locale}.json`);\n\t\tconst name = `${dirName}/${locale}.json`;\n\t\tif (!existsSync(file)) {\n\t\t\tthrow new Error(\n\t\t\t\t`i18n: ${name} is missing — every locale has a catalogue`,\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tout[locale] = JSON.parse(readFileSync(file, 'utf8'));\n\t\t} catch {\n\t\t\tthrow new Error(`i18n: ${name} is not valid JSON`);\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * The i18n plugin, for `defineMailConfig`:\n *\n * ```ts\n * defineMailConfig({ plugins: [i18n({ locales: ['en', 'fr'] })] });\n * ```\n *\n * It checks `locales/<locale>.json`, writes one wrapper per template and\n * locale under `.maizzle/emails/` so one build writes every locale, gives each\n * template `t`, `locale` and `placeholder`, and writes\n * `dist/mail-manifest.json`. A catalogue or a template that cannot be right\n * **fails the build**, naming the locale and the key.\n */\nexport function i18n(options: I18nOptions): MailPlugin {\n\tcheckOptions(options);\n\tconst { locales } = options;\n\tconst fallbackLocale = options.fallbackLocale ?? (locales[0] as string);\n\tconst layout = options.layout ?? 'nested';\n\tconst dirName = options.dir ?? 'locales';\n\tconst emailsName = options.emails ?? 'emails';\n\tconst cwd = process.cwd();\n\tconst emailsDir = resolve(cwd, emailsName);\n\tconst wrappersDir = resolve(cwd, WRAPPERS_DIR);\n\n\tconst messages = checkCatalogues(\n\t\tlayerCatalogues(\n\t\t\toptions.catalogues ?? [],\n\t\t\treadCatalogues(resolve(cwd, dirName), dirName, locales),\n\t\t),\n\t\tlocales,\n\t\tfallbackLocale,\n\t);\n\tconst reference = messages.get(fallbackLocale) as Messages;\n\tconst format = createFormatter('i18n');\n\tconst regenerate = () =>\n\t\twriteWrappers({\n\t\t\tfolders: templateFolders(\n\t\t\t\t{ dir: emailsDir, name: emailsName },\n\t\t\t\toptions.templates ?? [],\n\t\t\t),\n\t\t\twrappersDir,\n\t\t\tlocales,\n\t\t\tlayout,\n\t\t});\n\t// A parallel build loads the config again in each worker: only the main\n\t// thread writes, so two workers never write the same file.\n\tif (isMainThread) {\n\t\tregenerate();\n\t\twriteIfChanged(\n\t\t\tresolve(cwd, TYPES_FILE),\n\t\t\ttemplateTypes(reference, fallbackLocale),\n\t\t);\n\t}\n\n\treturn defineMailPlugin({\n\t\tname: 'i18n',\n\t\tcontent: [`${wrappersDir}/**/*.vue`],\n\t\t// `maizzle serve` watches locales/ already; another folder is added.\n\t\t...(dirName === 'locales' ? {} : { server: { watch: [`${dirName}/**`] } }),\n\t\tvite: { plugins: [watchTemplates(emailsDir, regenerate)] },\n\t\tbeforeRender({ config, template }) {\n\t\t\tconst path = relative(\n\t\t\t\twrappersDir,\n\t\t\t\tjoin(template.path.dir, template.path.name),\n\t\t\t)\n\t\t\t\t.split(sep)\n\t\t\t\t.join('/');\n\t\t\tconst entry = parseEntry(path, layout, locales);\n\t\t\tif (entry === null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`i18n: ${relative(cwd, join(template.path.dir, template.path.base))} is not built through the i18n plugin — leave content to it, and put templates in ${emailsName}/`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconfig.vue ??= {};\n\t\t\tconfig.vue.globalProperties = {\n\t\t\t\t...config.vue.globalProperties,\n\t\t\t\t...templateProperties({\n\t\t\t\t\t...entry,\n\t\t\t\t\tmessages: messages.get(entry.locale) as Messages,\n\t\t\t\t\treference,\n\t\t\t\t\tformat,\n\t\t\t\t}),\n\t\t\t};\n\t\t},\n\t\tafterBuild({ files, config }) {\n\t\t\tconst outputDir = resolve(cwd, config.output?.path ?? 'dist');\n\t\t\tconst manifest = buildManifest({\n\t\t\t\tfiles,\n\t\t\t\toutputDir,\n\t\t\t\thtmlExtension: config.output?.extension ?? 'html',\n\t\t\t\tlayout,\n\t\t\t\tlocales,\n\t\t\t\tfallbackLocale,\n\t\t\t\tmessages,\n\t\t\t});\n\t\t\twriteFileSync(\n\t\t\t\tjoin(outputDir, MANIFEST_FILE),\n\t\t\t\t`${JSON.stringify(manifest, null, '\\t')}\\n`,\n\t\t\t);\n\t\t\tconst typesFile = options.rendererTypes ?? RENDERER_TYPES_FILE;\n\t\t\tif (typesFile !== false) {\n\t\t\t\twriteRendererTypes(\n\t\t\t\t\tresolve(cwd, typesFile),\n\t\t\t\t\ttypesFile,\n\t\t\t\t\trendererTypes(manifest),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n}\n",
@@ -11,7 +11,7 @@
11
11
  "import type { ArgumentKind, Messages } from './catalogues';\nimport { placeholderMark } from './manifest';\nimport type { createFormatter, MessageArgs } from './translator';\n\nconst NAME = /^[a-z][a-zA-Z0-9]*$/;\n\nconst KINDS: Record<ArgumentKind, (value: unknown) => boolean> = {\n\tstring: (value) => typeof value === 'string' || typeof value === 'number',\n\tnumber: (value) => typeof value === 'number',\n\tdate: (value) => value instanceof Date || typeof value === 'number',\n};\n\nconst isPlaceholder = (value: unknown) =>\n\ttypeof value === 'string' && /^\\{\\{ [a-z][a-zA-Z0-9]* \\}\\}$/.test(value);\n\nconst kindOf = (value: unknown) =>\n\tvalue === null ? 'null' : value instanceof Date ? 'date' : typeof value;\n\n/**\n * What one template gets in one locale: `t`, `locale` and `placeholder`.\n *\n * `t` is checked against the fallback locale's message, which declares every\n * argument: an unknown key, an argument left out, one the message does not\n * use, or one of the wrong kind **fails the build**, naming the locale, the\n * template and the key.\n */\nexport function templateProperties(options: {\n\treadonly email: string;\n\treadonly locale: string;\n\treadonly messages: Messages;\n\treadonly reference: Messages;\n\treadonly format: ReturnType<typeof createFormatter>;\n}) {\n\tconst { email, locale, messages, reference, format } = options;\n\tconst where = `i18n: ${locale}: ${email}`;\n\treturn {\n\t\tlocale,\n\t\tt(key: string, args: MessageArgs = {}): string {\n\t\t\tconst message = typeof key === 'string' ? messages.get(key) : undefined;\n\t\t\tconst declared = typeof key === 'string' ? reference.get(key) : undefined;\n\t\t\tif (message === undefined || declared === undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${where} calls t('${String(key)}'), which is not a key of the catalogues`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof args !== 'object' || args === null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${where} calls t('${key}') with arguments that are not an object, as { name: placeholder('name') }`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [name, kind] of declared.args) {\n\t\t\t\tif (!Object.hasOwn(args, name)) {\n\t\t\t\t\tthrow new Error(`${where} calls t('${key}') without {${name}}`);\n\t\t\t\t}\n\t\t\t\tif (declared.selects.has(name) && isPlaceholder(args[name])) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${where} passes a placeholder to {${name}}, which ${key} chooses on with a select — a placeholder always chooses other`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!KINDS[kind](args[name])) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${where} passes {${name}} to ${key} as a ${kindOf(args[name])} — the message uses it as a ${kind}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const name of Object.keys(args)) {\n\t\t\t\tif (!declared.args.has(name)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${where} passes {${name}} to ${key}, which does not use it`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn format(locale, key, message.text, args);\n\t\t},\n\t\tplaceholder(name: string): string {\n\t\t\tif (typeof name !== 'string' || !NAME.test(name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${where} calls placeholder() with a name that is not camelCase — as placeholder('firstName')`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn placeholderMark(name);\n\t\t},\n\t};\n}\n",
12
12
  "import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { ArgumentKind, Messages } from './catalogues';\nimport type { Manifest } from './manifest';\n\n/** Where the template types go, under the project: `.maizzle/*.d.ts` is in the starter's `tsconfig.json`. */\nexport const TYPES_FILE = '.maizzle/nxgt-mail-i18n.d.ts';\n\n/** What `t` accepts for each kind — as the build checks it. */\nconst TYPE_OF: Readonly<Record<ArgumentKind, string>> = {\n\tstring: 'string | number',\n\tnumber: 'number',\n\tdate: 'Date | number',\n};\n\n/**\n * The declaration file that types `t` in the templates: each key of the\n * `reference` catalogue, with its arguments, so an editor completes a key and\n * flags an unknown one or a missing argument. Keys and names are checked\n * before this runs, so they are safe to write quoted.\n */\nexport function templateTypes(\n\treference: Messages,\n\tfallbackLocale: string,\n): string {\n\tconst entries = [...reference.entries()]\n\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\t.map(([key, message]) => {\n\t\t\tconst args = [...message.args.entries()]\n\t\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\t\t\t.map(([name, kind]) => `${name}: ${TYPE_OF[kind]}`);\n\t\t\treturn `\\t\\t'${key}': { ${args.join('; ')}${args.length > 0 ? ' ' : ''}};`;\n\t\t});\n\treturn [\n\t\t`// Generated by @nxgt/mail-i18n from the ${fallbackLocale} catalogue, each time the config loads.`,\n\t\t'// Never edited, never committed: it types t() in the templates.',\n\t\t\"import type {} from '@nxgt/mail-i18n';\",\n\t\t'',\n\t\t\"declare module '@nxgt/mail-i18n' {\",\n\t\t'\\tinterface TemplateMessages {',\n\t\t...entries,\n\t\t'\\t}',\n\t\t'}',\n\t\t'',\n\t].join('\\n');\n}\n\n/** The first line of the renderer's types: a file without it is not the plugin's to replace. */\nconst RENDERER_TYPES_HEADER = '// Generated by @nxgt/mail-i18n from the build';\n\n/** Where the renderer's types go, under the project, by default. */\nexport const RENDERER_TYPES_FILE = 'generated/mail.ts';\n\n/**\n * The module that types the renderer: `MailEmails`, each e-mail of the build\n * with the variables it takes at send time, for\n * `createMailRenderer<MailEmails>(…)`. A URL variable takes a string; any\n * other a string or a number, as `render` writes it. `@nxgt/mail`'s\n * `RenderArguments` reads `Readonly<Record<string, never>>` as an e-mail\n * without variables, and its type specs copy this output: change them\n * together.\n */\nexport function rendererTypes(manifest: Manifest): string {\n\tconst entries = Object.entries(manifest.emails)\n\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n\t\t.map(([email, { variables, urlVariables }]) => {\n\t\t\tconst fields = variables.map(\n\t\t\t\t(name) =>\n\t\t\t\t\t`readonly ${name}: ${urlVariables.includes(name) ? 'string' : 'string | number'}`,\n\t\t\t);\n\t\t\tconst type =\n\t\t\t\tfields.length > 0\n\t\t\t\t\t? `{ ${fields.join('; ')} }`\n\t\t\t\t\t: 'Readonly<Record<string, never>>';\n\t\t\t// A name is a file's path, quoted as JSON: valid TypeScript whatever it holds.\n\t\t\treturn `\\t${JSON.stringify(email)}: ${type};`;\n\t\t});\n\treturn [\n\t\t`${RENDERER_TYPES_HEADER}, after each maizzle build.`,\n\t\t'// Never edited, never committed: git-ignore it, and build before type-checking.',\n\t\t'',\n\t\t'/** The e-mails of the build, each with the variables it takes when it is sent. */',\n\t\t'export interface MailEmails {',\n\t\t...entries,\n\t\t'}',\n\t\t'',\n\t].join('\\n');\n}\n\n/**\n * Writes the renderer's types to `file`, shown as `path` — unless `file` holds\n * something the plugin did not write: that **throws**, and the file is kept.\n */\nexport function writeRendererTypes(\n\tfile: string,\n\tpath: string,\n\tsource: string,\n): void {\n\tif (\n\t\texistsSync(file) &&\n\t\t!readFileSync(file, 'utf8').startsWith(RENDERER_TYPES_HEADER)\n\t) {\n\t\tthrow new Error(\n\t\t\t`i18n: ${path} was not written by i18n() — point rendererTypes at a file of its own`,\n\t\t);\n\t}\n\twriteIfChanged(file, source);\n}\n\n/** Writes `source` to `file` only when it changed, so an editor or a watcher sees a change only where there is one. */\nexport function writeIfChanged(file: string, source: string): void {\n\tif (existsSync(file) && readFileSync(file, 'utf8') === source) return;\n\tmkdirSync(dirname(file), { recursive: true });\n\twriteFileSync(file, source);\n}\n"
13
13
  ],
14
- "mappings": "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",
15
- "debugId": "8EAF60F48839FE4D64756E2164756E21",
14
+ "mappings": "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",
15
+ "debugId": "3C814EA0EFDDBF5664756E2164756E21",
16
16
  "names": []
17
17
  }
@@ -18,8 +18,21 @@ export interface ManifestEmail {
18
18
  readonly text: string | null;
19
19
  }>>;
20
20
  }
21
+ /**
22
+ * The manifest's format. It changes only with the manifest's shape, and
23
+ * `@nxgt/mail`'s renderer reads every format up to its own within 0.x: a
24
+ * build from an older `@nxgt/mail-i18n` keeps working with a newer renderer.
25
+ * Copied in packages/mail/src/renderer.ts: change both.
26
+ */
27
+ export declare const MANIFEST_FORMAT = 1;
21
28
  /** `dist/mail-manifest.json`: what the build wrote, for the renderer. */
22
29
  export interface Manifest {
30
+ /**
31
+ * {@link MANIFEST_FORMAT} when built, and the first key written. This type
32
+ * is what this version writes: a manifest from `@nxgt/mail-i18n` 0.1 or
33
+ * 0.2 has no such field, and the renderer reads it as format 1.
34
+ */
35
+ readonly formatVersion: number;
23
36
  readonly locales: readonly string[];
24
37
  readonly fallbackLocale: string;
25
38
  readonly emails: Readonly<Record<string, ManifestEmail>>;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAyB,KAAK,MAAM,EAAc,MAAM,YAAY,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CACvB,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CACvE,CAAC;CACF;AAED,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CACzD;AAQD,wDAAwD;AACxD,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,WAAoB,CAAC;AAKjE,6EAA6E;AAC7E,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,WAM1B,CAAC;AA8Cb;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACjD,GAAG,QAAQ,CA8EX"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAyB,KAAK,MAAM,EAAc,MAAM,YAAY,CAAC;AAE5E,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CACvB,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CACvE,CAAC;CACF;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACxB;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CACzD;AAQD,wDAAwD;AACxD,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,WAAoB,CAAC;AAKjE,6EAA6E;AAC7E,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,WAM1B,CAAC;AA8Cb;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACjD,GAAG,QAAQ,CA+EX"}
package/docs/README.md CHANGED
@@ -10,7 +10,7 @@ in the
10
10
  | --- | --- |
11
11
  | [Catalogues](guide/catalogues.md) | You are writing `locales/<locale>.json`: nesting and `camelCase`, the kinds of argument, what each locale is checked for against the fallback locale, the subject key of each e-mail, catalogues a package ships (the `catalogues` option), and every build failure a catalogue causes |
12
12
  | [Templates](guide/templates.md) | You are writing `emails/*.vue`: `t`, `locale` and `placeholder`, where a placeholder can go, templates a package ships (the `templates` option), what fails the build, the files the build writes, and `maizzle serve` and its watcher |
13
- | [The manifest](guide/manifest.md) | You are reading `dist/mail-manifest.json`, the file the sending code uses: each field, how it is computed, and the flat layout; and `generated/mail.ts`, the `MailEmails` type that types `createMailRenderer`, with the `rendererTypes` option |
13
+ | [The manifest](guide/manifest.md) | You are reading `dist/mail-manifest.json`, the file the sending code uses: each field, how it is computed, and the flat layout; `formatVersion` and which `@nxgt/mail` reads it; shipping a build in a package; and `generated/mail.ts`, the `MailEmails` type that types `createMailRenderer`, with the `rendererTypes` option |
14
14
  | [Editor and type checking](guide/editor.md) | You want the editor to complete `t('…')` and flag an unknown key or a wrong argument, and `vue-tsc` to check your templates in CI: the tsconfig, `maizzle prepare`, the generated `.maizzle/nxgt-mail-i18n.d.ts`, what each kind of argument accepts, and `TemplateMessages`, `TemplateKey`, `TemplateArgs` |
15
15
  | [Translating outside templates](guide/translator.md) | You need a message in your application's code (a notification, a text message, a test) with `createTranslator`, and want to know how it differs from `@nxgt/i18n` |
16
16
  | [Troubleshooting](troubleshooting.md) | You have an error message and want its cause and its fix |
@@ -39,6 +39,7 @@ against:
39
39
 
40
40
  ```json
41
41
  {
42
+ "formatVersion": 1,
42
43
  "locales": ["en", "fr"],
43
44
  "fallbackLocale": "en",
44
45
  "emails": {
@@ -85,7 +86,10 @@ against:
85
86
  ## The shape
86
87
 
87
88
  ```ts
89
+ const MANIFEST_FORMAT = 1;
90
+
88
91
  interface Manifest {
92
+ readonly formatVersion: number;
89
93
  readonly locales: readonly string[];
90
94
  readonly fallbackLocale: string;
91
95
  readonly emails: Readonly<Record<string, ManifestEmail>>;
@@ -101,6 +105,7 @@ interface ManifestEmail {
101
105
 
102
106
  | Field | Holds |
103
107
  | --- | --- |
108
+ | `formatVersion` | The manifest's format, `MANIFEST_FORMAT` of the `@nxgt/mail-i18n` that built it: `1`. Written first |
104
109
  | `locales` | The plugin's `locales`, in the order given |
105
110
  | `fallbackLocale` | The plugin's `fallbackLocale`, or the first locale |
106
111
  | `emails` | One entry per e-mail, keyed by its template's path under `emails/` without `.vue` (`auth/reset-password`), sorted |
@@ -114,6 +119,30 @@ Each e-mail:
114
119
  | `subject` | The subject per locale, formatted from `<emailKey>.subject`, each argument kept as `{{ name }}` |
115
120
  | `files` | The built files per locale, relative to the output folder: `html`, and `text` or `null` when there is no plain-text part |
116
121
 
122
+ ### `formatVersion`
123
+
124
+ The format of the manifest's shape, so the renderer knows what it reads:
125
+
126
+ ```ts
127
+ import { MANIFEST_FORMAT } from '@nxgt/mail-i18n';
128
+
129
+ MANIFEST_FORMAT; // 1 — what this version writes as formatVersion
130
+ ```
131
+
132
+ - **It changes only when the manifest's shape does.** A new
133
+ `@nxgt/mail-i18n` that writes the same fields writes the same format.
134
+ - **`@nxgt/mail`'s renderer reads every format up to its own**, its
135
+ `MANIFEST_FORMAT` from `@nxgt/mail/renderer`, within 0.x. A build from any
136
+ earlier `@nxgt/mail-i18n` 0.x keeps working with a newer `@nxgt/mail`; a
137
+ newer format fails at start-up with `… is manifest format 2, newer than this
138
+ @nxgt/mail reads (1) — upgrade @nxgt/mail`.
139
+ - **A manifest without it is format 1**, as `@nxgt/mail-i18n` 0.1 and 0.2
140
+ wrote it.
141
+
142
+ See
143
+ [Rendering — which builds it reads](https://github.com/softistx/nxgt-mail/blob/develop/packages/mail/docs/guide/rendering.md#which-builds-it-reads--manifest_format)
144
+ in `@nxgt/mail`.
145
+
117
146
  ### `variables`
118
147
 
119
148
  Collected from the built files, not from the template's source: every
@@ -351,8 +380,66 @@ describe('the built e-mails', () => {
351
380
  `acme-mails` stands for wherever your built project lives: a package of its
352
381
  own, a folder of the repository, a build artefact.
353
382
 
383
+ ## Shipping a build in a package
384
+
385
+ A package can publish its e-mails already built — `mails/`, with its manifest
386
+ — so the application that installs it only creates a renderer. The build
387
+ decides which `@nxgt/mail` can read it, so the package peers the range whose
388
+ renderers read its format, and checks it when it builds:
389
+
390
+ ```json
391
+ {
392
+ "name": "acme-mails",
393
+ "files": ["mails"],
394
+ "scripts": {
395
+ "build": "maizzle build && bun run scripts/check-manifest-format.ts"
396
+ },
397
+ "peerDependencies": {
398
+ "@nxgt/mail": ">=0.1.0 <1"
399
+ },
400
+ "devDependencies": {
401
+ "@nxgt/mail": "0.5.1",
402
+ "@nxgt/mail-i18n": "^0.3.0"
403
+ }
404
+ }
405
+ ```
406
+
407
+ `maizzle.config.ts` writes the build there, with Maizzle's `output.path`:
408
+ `defineMailConfig({ output: { path: 'mails' }, plugins: [i18n({ locales:
409
+ ['en', 'fr'] })] })`. The check reads the format the build wrote, and compares
410
+ it with what the oldest `@nxgt/mail` you support reads:
411
+
412
+ ```ts
413
+ // scripts/check-manifest-format.ts — after maizzle build, before publishing
414
+ import { readFileSync } from 'node:fs';
415
+ import { MANIFEST_FILE, MANIFEST_FORMAT, type Manifest } from '@nxgt/mail-i18n';
416
+ import { MANIFEST_FORMAT as READABLE } from '@nxgt/mail/renderer'; // the devDependency: the oldest @nxgt/mail supported
417
+
418
+ const manifest: Manifest = JSON.parse(readFileSync(`mails/${MANIFEST_FILE}`, 'utf8'));
419
+
420
+ if (manifest.formatVersion !== MANIFEST_FORMAT) {
421
+ throw new Error(`mails/ is manifest format ${manifest.formatVersion}, not ${MANIFEST_FORMAT} — run maizzle build again`);
422
+ }
423
+ if (manifest.formatVersion > READABLE) {
424
+ throw new Error(
425
+ `mails/ is manifest format ${manifest.formatVersion}; the oldest @nxgt/mail supported reads up to ${READABLE} — raise the @nxgt/mail peer and devDependency`,
426
+ );
427
+ }
428
+ ```
429
+
430
+ - **The devDependency is the peer's lower bound**, so `MANIFEST_FORMAT` from
431
+ `@nxgt/mail/renderer` is what the oldest renderer an application may install
432
+ reads. `@nxgt/mail` 0.5.0 and earlier do not export it; they read format 1,
433
+ as 0.5.1 does, so a format-1 build pins 0.5.1 and still peers
434
+ `>=0.1.0 <1`.
435
+ - **When `@nxgt/mail-i18n` writes a new format**, the second check fails the
436
+ build: raise the peer's lower bound, and the devDependency with it, to the
437
+ first `@nxgt/mail` that reads it.
438
+ - **The first check** catches a `mails/` folder left from another build, made
439
+ before `@nxgt/mail-i18n` was upgraded.
440
+
354
441
  ## See also
355
442
 
356
- - [Rendering](https://github.com/softistx/nxgt-mail/blob/develop/packages/mail/docs/guide/rendering.md) in `@nxgt/mail` — the renderer that reads the manifest at send time.
443
+ - [Rendering](https://github.com/softistx/nxgt-mail/blob/develop/packages/mail/docs/guide/rendering.md) in `@nxgt/mail` — the renderer that reads the manifest at send time, and the formats it reads.
357
444
  - [Templates](templates.md) — where placeholders come from.
358
445
  - [Catalogues](catalogues.md#the-subject) — the subject of each e-mail.
package/docs/roadmap.md CHANGED
@@ -5,11 +5,10 @@ no dates here, and the version something shipped in is the only number.
5
5
 
6
6
  ## Now
7
7
 
8
- - **The wrappers under `.maizzle/emails/`** — the files generated per
9
- template and locale move from `.maizzle/i18n/` to `.maizzle/emails/`, so
10
- `maizzle serve` lists the e-mails under `.maizzle/emails/en` rather than a
11
- folder named after the plugin. The build output does not move. Built, not
12
- yet published.
8
+ - **The manifest's format, versioned** — `mail-manifest.json` starts with
9
+ `formatVersion`, `MANIFEST_FORMAT` is exported, and the format changes only
10
+ with the manifest's shape: any later `@nxgt/mail` 0.x reads the build.
11
+ Built, not yet published.
13
12
 
14
13
  ## Next
15
14
 
@@ -42,6 +41,11 @@ Nothing yet. A request is welcome as an
42
41
  The last ten, newest first, each with the version it came in. Everything
43
42
  before is in the [CHANGELOG](../CHANGELOG.md).
44
43
 
44
+ - **The wrappers under `.maizzle/emails/`, v0.2.0** — the files generated per
45
+ template and locale move from `.maizzle/i18n/` to `.maizzle/emails/`, so
46
+ `maizzle serve` lists the e-mails under `.maizzle/emails/en` rather than a
47
+ folder named after the plugin; `WRAPPERS_DIR` follows. The build output
48
+ does not move. Delete the old `.maizzle/i18n/` after upgrading.
45
49
  - **i18n as a plugin, v0.1.0** — `i18n({ locales, fallbackLocale })`, listed in
46
50
  `defineMailConfig`'s `plugins`: one template per e-mail, its text keys into
47
51
  `locales/<locale>.json` ICU catalogues, and one output per locale from a
@@ -88,8 +92,3 @@ before is in the [CHANGELOG](../CHANGELOG.md).
88
92
  unknown e-mail, a missing or unknown variable, or a number for a URL at
89
93
  compile time. Rewritten only when it changes;
90
94
  `rendererTypes` moves it, or `false` turns it off.
91
- - **A starter project, with v0.1.0** — the official Maizzle starter with
92
- `defineMailConfig`, the i18n and the UI plugins wired in as the READMEs
93
- say, built, rendered in `en` and `fr` and served in CI, so the snippets are
94
- known to work: [`examples/starter`](https://github.com/softistx/nxgt-mail/tree/develop/examples/starter).
95
- In the repository; its README says how to start your own from npm.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/mail-i18n",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "An i18n plugin for a Maizzle project: ICU catalogues checked at build time, t() in templates, one output per locale, and the manifest the renderer reads. createTranslator for use outside templates.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,14 +52,14 @@
52
52
  "devDependencies": {
53
53
  "@maizzle/framework": "6.1.7",
54
54
  "@maizzle/tailwindcss": "1.5.6",
55
- "@nxgt/mail-config": "0.1.0",
55
+ "@nxgt/mail-config": "0.2.0",
56
56
  "@types/bun": "^1.4.2",
57
57
  "vue": "3.5.43",
58
58
  "vue-tsc": "^3.3.11"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@maizzle/framework": "^6.1.7",
62
- "@nxgt/mail-config": "^0.1.0",
62
+ "@nxgt/mail-config": "^0.2.0",
63
63
  "typescript": "^6.0.3",
64
64
  "vue": "^3.5.0"
65
65
  },