@contentrain/query 5.1.5 → 6.1.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.
Files changed (36) hide show
  1. package/README.md +13 -0
  2. package/dist/cdn/index.cjs +1 -1
  3. package/dist/cdn/index.d.cts +1 -1
  4. package/dist/cdn/index.d.mts +1 -1
  5. package/dist/cdn/index.mjs +1 -1
  6. package/dist/{cdn-SOuikUcY.mjs → cdn-CNdH7sKk.mjs} +23 -2
  7. package/dist/cdn-CNdH7sKk.mjs.map +1 -0
  8. package/dist/{cdn-5ycdk2ET.cjs → cdn-aeCpH9Dt.cjs} +22 -1
  9. package/dist/cli.cjs +1 -1
  10. package/dist/cli.mjs +1 -1
  11. package/dist/{generate-DAaCl3Np.cjs → generate-DN3mAbvC.cjs} +108 -44
  12. package/dist/{generate-B5P14n43.mjs → generate-mpKW9Y8v.mjs} +109 -45
  13. package/dist/generate-mpKW9Y8v.mjs.map +1 -0
  14. package/dist/generator/generate.cjs +1 -1
  15. package/dist/generator/generate.d.cts +8 -0
  16. package/dist/generator/generate.d.cts.map +1 -1
  17. package/dist/generator/generate.d.mts +8 -0
  18. package/dist/generator/generate.d.mts.map +1 -1
  19. package/dist/generator/generate.mjs +1 -1
  20. package/dist/{index-BChs94uA.d.cts → index-mBPlkuGU.d.cts} +4 -1
  21. package/dist/index-mBPlkuGU.d.cts.map +1 -0
  22. package/dist/{index-CsCpovuB.d.mts → index-tyAxQaPt.d.mts} +4 -1
  23. package/dist/index-tyAxQaPt.d.mts.map +1 -0
  24. package/dist/index.cjs +24 -3
  25. package/dist/index.d.cts +4 -1
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.mts +4 -1
  28. package/dist/index.d.mts.map +1 -1
  29. package/dist/index.mjs +24 -3
  30. package/dist/index.mjs.map +1 -1
  31. package/package.json +2 -2
  32. package/skills/contentrain-query/references/bundler-config.md +10 -8
  33. package/dist/cdn-SOuikUcY.mjs.map +0 -1
  34. package/dist/generate-B5P14n43.mjs.map +0 -1
  35. package/dist/index-BChs94uA.d.cts.map +0 -1
  36. package/dist/index-CsCpovuB.d.mts.map +0 -1
@@ -46,6 +46,7 @@ async function readProjectManifest(projectRoot) {
46
46
  domains: rawConfig?.domains ?? [],
47
47
  repository: rawConfig?.repository,
48
48
  assets_path: rawConfig?.assets_path,
49
+ cdn: rawConfig?.cdn,
49
50
  branchRetention: rawConfig?.branchRetention
50
51
  };
51
52
  const modelsDir = join(crDir, "models");
@@ -144,7 +145,7 @@ async function mapDocumentLocale(dir, model, locale, strategy) {
144
145
  }
145
146
  //#endregion
146
147
  //#region src/generator/type-emitter.ts
147
- function emitTypes(models) {
148
+ function emitTypes(models, hasMedia = false) {
148
149
  const lines = [
149
150
  "/* eslint-disable */",
150
151
  "/* oxlint-disable */",
@@ -159,12 +160,19 @@ function emitTypes(models) {
159
160
  if (model.kind === "dictionary") lines.push(`export type ${kebabToPascal(model.id)} = Record<string, string>`);
160
161
  else {
161
162
  lines.push(`export interface ${kebabToPascal(model.id)} {`);
162
- if (model.kind === "collection") lines.push(" id: string");
163
+ const baseNames = /* @__PURE__ */ new Set();
164
+ if (model.kind === "collection") {
165
+ lines.push(" id: string");
166
+ baseNames.add("id");
167
+ }
163
168
  if (model.kind === "document") {
164
169
  lines.push(" slug: string");
165
- lines.push(" content: string");
170
+ lines.push(" body: string");
171
+ baseNames.add("slug");
172
+ baseNames.add("body");
166
173
  }
167
174
  if (model.fields) for (const [name, field] of Object.entries(model.fields)) {
175
+ if (baseNames.has(name)) continue;
168
176
  const tsType = fieldToTS(field);
169
177
  const optional = field.required ? "" : "?";
170
178
  lines.push(` ${name}${optional}: ${tsType}`);
@@ -180,7 +188,7 @@ function emitTypes(models) {
180
188
  sort<K extends keyof T>(field: K, order?: 'asc' | 'desc'): QueryBuilder<T>
181
189
  limit(n: number): QueryBuilder<T>
182
190
  offset(n: number): QueryBuilder<T>
183
- include(...fields: string[]): QueryBuilder<T>
191
+ include<K extends keyof T & string>(...fields: K[]): QueryBuilder<T>
184
192
  count(): number
185
193
  first(): T | undefined
186
194
  all(): T[]
@@ -188,7 +196,7 @@ function emitTypes(models) {
188
196
  lines.push("");
189
197
  lines.push(`export interface SingletonAccessor<T> {
190
198
  locale(lang: string): SingletonAccessor<T>
191
- include(...fields: string[]): SingletonAccessor<T>
199
+ include<K extends keyof T & string>(...fields: K[]): SingletonAccessor<T>
192
200
  get(): T
193
201
  }`);
194
202
  lines.push("");
@@ -203,7 +211,8 @@ function emitTypes(models) {
203
211
  locale(lang: string): DocumentQuery<T>
204
212
  where<K extends keyof T>(field: K, value: T[K]): DocumentQuery<T>
205
213
  where<K extends keyof T>(field: K, op: WhereOp, value: unknown): DocumentQuery<T>
206
- include(...fields: string[]): DocumentQuery<T>
214
+ sort<K extends keyof T>(field: K, order?: 'asc' | 'desc'): DocumentQuery<T>
215
+ include<K extends keyof T & string>(...fields: K[]): DocumentQuery<T>
207
216
  bySlug(slug: string): T | undefined
208
217
  count(): number
209
218
  first(): T | undefined
@@ -226,6 +235,11 @@ function emitTypes(models) {
226
235
  for (const m of documents) lines.push(`export declare function document(model: '${m.id}'): DocumentQuery<${kebabToPascal(m.id)}>`);
227
236
  lines.push("export declare function document(model: string): DocumentQuery<Record<string, unknown>>");
228
237
  lines.push("");
238
+ if (hasMedia) {
239
+ lines.push("/** Resolve a stored `media/...` path to its absolute delivery URL. External URLs and already-absolute values pass through unchanged. */");
240
+ lines.push("export declare function media(value: string): string");
241
+ lines.push("");
242
+ }
229
243
  lines.push("export interface ContentrainClient {");
230
244
  for (const m of collections) lines.push(` query(model: '${m.id}'): QueryBuilder<${kebabToPascal(m.id)}>`);
231
245
  lines.push(" query(model: string): QueryBuilder<Record<string, unknown>>");
@@ -259,12 +273,16 @@ function fieldToTS(field) {
259
273
  case "image":
260
274
  case "video":
261
275
  case "file":
262
- case "relation":
276
+ case "relation": {
263
277
  if (Array.isArray(field.model) && field.model.length > 1) return `{ model: ${field.model.map((m) => `'${m}'`).join(" | ")}; ref: string }`;
264
- return "string";
265
- case "relations":
278
+ const target = Array.isArray(field.model) ? field.model[0] : field.model;
279
+ return target ? `string | ${kebabToPascal(target)}` : "string";
280
+ }
281
+ case "relations": {
266
282
  if (Array.isArray(field.model) && field.model.length > 1) return `Array<{ model: ${field.model.map((m) => `'${m}'`).join(" | ")}; ref: string }>`;
267
- return "string[]";
283
+ const target = Array.isArray(field.model) ? field.model[0] : field.model;
284
+ return target ? `Array<string | ${kebabToPascal(target)}>` : "string[]";
285
+ }
268
286
  case "number":
269
287
  case "integer":
270
288
  case "decimal":
@@ -367,12 +385,12 @@ async function emitSingleModule(ref, models) {
367
385
  case "document": {
368
386
  const rawText = await readText(ref.filePath);
369
387
  if (!rawText) return null;
370
- const { frontmatter, body } = parseFrontmatter(rawText);
388
+ const { frontmatter, body } = parseFrontmatter(rawText, stringLikeFieldKeys(model));
371
389
  const slug = ref.slug ?? model.id;
372
390
  const data = {
373
391
  slug,
374
392
  ...frontmatter,
375
- content: body
393
+ body
376
394
  };
377
395
  return {
378
396
  fileName: `${model.id}--${slug}${localeSuffix}.mjs`,
@@ -382,7 +400,34 @@ async function emitSingleModule(ref, models) {
382
400
  default: return null;
383
401
  }
384
402
  }
385
- function parseFrontmatter(text) {
403
+ const STRING_LIKE_TYPES = new Set([
404
+ "string",
405
+ "text",
406
+ "email",
407
+ "url",
408
+ "slug",
409
+ "color",
410
+ "phone",
411
+ "code",
412
+ "icon",
413
+ "markdown",
414
+ "richtext",
415
+ "date",
416
+ "datetime",
417
+ "image",
418
+ "video",
419
+ "file",
420
+ "select",
421
+ "relation"
422
+ ]);
423
+ function stringLikeFieldKeys(model) {
424
+ const keys = /* @__PURE__ */ new Set();
425
+ if (model.fields) {
426
+ for (const [name, field] of Object.entries(model.fields)) if (STRING_LIKE_TYPES.has(field.type)) keys.add(name);
427
+ }
428
+ return keys;
429
+ }
430
+ function parseFrontmatter(text, stringKeys = /* @__PURE__ */ new Set()) {
386
431
  const normalized = text.replace(/\r\n/g, "\n");
387
432
  const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
388
433
  if (!match) return {
@@ -433,25 +478,28 @@ function parseFrontmatter(text) {
433
478
  current[key] = rawValue.slice(1, -1).split(",").map((s) => s.trim()).filter(Boolean);
434
479
  continue;
435
480
  }
436
- current[key] = parseValue(rawValue);
481
+ current[key] = parseValue(rawValue, current === frontmatter && stringKeys.has(key));
437
482
  }
438
483
  return {
439
484
  frontmatter,
440
485
  body
441
486
  };
442
487
  }
443
- function parseValue(raw) {
488
+ function parseValue(raw, forceString = false) {
489
+ const isQuoted = raw.startsWith("\"") && raw.endsWith("\"") || raw.startsWith("'") && raw.endsWith("'");
490
+ const unquoted = isQuoted ? raw.slice(1, -1) : raw;
491
+ if (forceString) return unquoted;
492
+ if (isQuoted) return unquoted;
444
493
  if (raw === "true") return true;
445
494
  if (raw === "false") return false;
446
495
  if (raw === "null") return null;
447
496
  if (/^-?\d+$/.test(raw)) return parseInt(raw, 10);
448
497
  if (/^-?\d+\.\d+$/.test(raw)) return parseFloat(raw);
449
- if (raw.startsWith("\"") && raw.endsWith("\"") || raw.startsWith("'") && raw.endsWith("'")) return raw.slice(1, -1);
450
498
  return raw;
451
499
  }
452
500
  //#endregion
453
501
  //#region src/generator/runtime-emitter.ts
454
- function emitRuntimeModule(models, dataModules, defaultLocale) {
502
+ function emitRuntimeModule(models, dataModules, defaultLocale, cdnBaseUrl) {
455
503
  const lines = [
456
504
  "/* eslint-disable */",
457
505
  "/* oxlint-disable */",
@@ -462,6 +510,10 @@ function emitRuntimeModule(models, dataModules, defaultLocale) {
462
510
  lines.push(`const _defaultLocale = '${defaultLocale}'`);
463
511
  lines.push("");
464
512
  }
513
+ if (cdnBaseUrl) {
514
+ lines.push(`const _mediaBase = ${JSON.stringify(cdnBaseUrl.replace(/\/+$/, ""))}`);
515
+ lines.push("");
516
+ }
465
517
  for (const dm of dataModules) {
466
518
  const varName = fileNameToVar(dm.fileName);
467
519
  lines.push(`import ${varName} from './data/${dm.fileName}'`);
@@ -489,15 +541,17 @@ function emitRuntimeModule(models, dataModules, defaultLocale) {
489
541
  lines.push("// ─── Relation Resolver ───");
490
542
  lines.push("");
491
543
  lines.push("function _resolveEntry(model, id, locale) {");
492
- lines.push(" const localeKey = locale ?? '_default'");
544
+ lines.push(" const localeKeys = locale ? [locale, '_default'] : ['_default']");
545
+ lines.push(" for (const localeKey of localeKeys) {");
493
546
  if (collections.length > 0) {
494
- lines.push(" const colData = _collectionRegistry[model]?.get(localeKey)");
495
- lines.push(" if (colData) { const e = colData.find(x => x.id === id); if (e) return e; }");
547
+ lines.push(" const colData = _collectionRegistry[model]?.get(localeKey)");
548
+ lines.push(" if (colData) { const e = colData.find(x => x.id === id); if (e) return e; }");
496
549
  }
497
550
  if (documents.length > 0) {
498
- lines.push(" const docData = _documentRegistry[model]?.get(localeKey)");
499
- lines.push(" if (docData) { const e = docData.find(x => x.slug === id); if (e) return e; }");
551
+ lines.push(" const docData = _documentRegistry[model]?.get(localeKey)");
552
+ lines.push(" if (docData) { const e = docData.find(x => x.slug === id); if (e) return e; }");
500
553
  }
554
+ lines.push(" }");
501
555
  lines.push(" return undefined");
502
556
  lines.push("}");
503
557
  lines.push("");
@@ -607,31 +661,36 @@ function emitRuntimeModule(models, dataModules, defaultLocale) {
607
661
  lines.push("}");
608
662
  lines.push("");
609
663
  }
664
+ if (cdnBaseUrl) {
665
+ lines.push("// ─── Media ───");
666
+ lines.push("");
667
+ lines.push("export function media(value) {");
668
+ lines.push(" if (typeof value !== 'string' || !value.startsWith('media/')) return value");
669
+ lines.push(" return _mediaBase + '/' + value");
670
+ lines.push("}");
671
+ lines.push("");
672
+ }
610
673
  return lines.join("\n") + "\n";
611
674
  }
612
- function emitCjsWrapper(models) {
675
+ function emitCjsWrapper(models, hasMedia = false) {
613
676
  const exports = [];
614
677
  if (models.some((m) => m.kind === "collection")) exports.push("query");
615
678
  if (models.some((m) => m.kind === "singleton")) exports.push("singleton");
616
679
  if (models.some((m) => m.kind === "dictionary")) exports.push("dictionary");
617
680
  if (models.some((m) => m.kind === "document")) exports.push("document");
681
+ if (hasMedia) exports.push("media");
618
682
  return `/* eslint-disable */
619
683
  /* oxlint-disable */
620
684
  // Auto-generated CJS proxy — delegates to ESM via dynamic import()
621
- // Sync usage: const client = require('#contentrain'); client.query('model')
622
- // Async usage: const client = await require('#contentrain').init()
685
+ // The generated client is ESM-first. From CommonJS, await init() once before
686
+ // accessing exports:
687
+ // const client = await require('#contentrain').init()
688
+ // client.query('model')
689
+ // Prefer native ESM (import) where possible.
623
690
  'use strict'
624
691
  let _mod = null
625
692
  let _promise = null
626
693
 
627
- function _ensure() {
628
- if (_mod) return _mod
629
- throw new Error(
630
- 'Contentrain client not initialized. Call .init() first, then access exports.\\n'
631
- + 'Example: require("#contentrain").init().then(c => c.query("model"))'
632
- )
633
- }
634
-
635
694
  module.exports.init = function() {
636
695
  if (!_promise) _promise = import('./index.mjs').then(function(m) {
637
696
  _mod = m
@@ -701,7 +760,7 @@ function _applyWhere(item, clause) {
701
760
  const val = item[clause.field];
702
761
  switch (clause.op) {
703
762
  case 'eq': return Array.isArray(val) ? val.includes(clause.value) : val === clause.value;
704
- case 'ne': return val !== clause.value;
763
+ case 'ne': return Array.isArray(val) ? !val.includes(clause.value) : val !== clause.value;
705
764
  case 'gt': return val > clause.value;
706
765
  case 'gte': return val >= clause.value;
707
766
  case 'lt': return val < clause.value;
@@ -738,11 +797,12 @@ class QueryBuilder {
738
797
  first() { return this.all()[0]; }
739
798
  _resolveIncludes(item) {
740
799
  const resolved = { ...item };
800
+ const _loc = this._locale ?? this._defaultLocale;
741
801
  for (const field of this._includes) {
742
802
  const meta = this._relationMeta[field]; if (!meta) continue;
743
803
  const targets = Array.isArray(meta.target) ? meta.target : [meta.target];
744
- if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, this._locale); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, this._locale); if (r) return r; } return id; }); } }
745
- else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, this._locale); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, this._locale); if (r) resolved[field] = r; } }
804
+ if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) return r; } return id; }); } }
805
+ else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) resolved[field] = r; } }
746
806
  }
747
807
  return resolved;
748
808
  }
@@ -780,15 +840,16 @@ class DictionaryAccessor {
780
840
  if (key === undefined) return dict;
781
841
  const val = dict[key];
782
842
  if (val === undefined) return undefined;
783
- if (params) return val.replace(/{(w+)}/g, (m, k) => { const v = params[k]; return v !== undefined ? String(v) : m; });
843
+ if (params) return val.replace(/\\{(\\w+)\\}/g, (m, k) => { const v = params[k]; return v !== undefined ? String(v) : m; });
784
844
  return val;
785
845
  }
786
846
  }
787
847
 
788
848
  class DocumentQuery {
789
- constructor(data, relationMeta, resolver, defaultLocale) { this._data = data; this._filters = []; this._locale = null; this._includes = []; this._relationMeta = relationMeta || {}; this._resolver = resolver || null; this._defaultLocale = defaultLocale || null; }
849
+ constructor(data, relationMeta, resolver, defaultLocale) { this._data = data; this._filters = []; this._sortField = null; this._sortOrder = 'asc'; this._locale = null; this._includes = []; this._relationMeta = relationMeta || {}; this._resolver = resolver || null; this._defaultLocale = defaultLocale || null; }
790
850
  locale(lang) { this._locale = lang; return this; }
791
851
  where(field, opOrValue, value) { if (value !== undefined) { this._filters.push({ field, op: opOrValue, value }); } else { this._filters.push({ field, op: 'eq', value: opOrValue }); } return this; }
852
+ sort(field, order = 'asc') { this._sortField = field; this._sortOrder = order; return this; }
792
853
  include(...fields) { this._includes.push(...fields); return this; }
793
854
  bySlug(slug) {
794
855
  const items = this._resolveData(); const item = items.find(x => x.slug === slug);
@@ -797,15 +858,16 @@ class DocumentQuery {
797
858
  }
798
859
  count() { return this.all().length; }
799
860
  first() { return this.all()[0]; }
800
- all() { let items = this._resolveData(); for (const clause of this._filters) items = items.filter(item => _applyWhere(item, clause)); if (this._includes.length > 0 && this._resolver) { items = items.map(item => this._resolveIncludes(item)); } return items; }
861
+ all() { let items = this._resolveData(); for (const clause of this._filters) items = items.filter(item => _applyWhere(item, clause)); if (this._sortField) { const sf = this._sortField; const d = this._sortOrder === 'asc' ? 1 : -1; items.sort((a, b) => { const va = a[sf], vb = b[sf]; if (va == null && vb == null) return 0; if (va == null) return d; if (vb == null) return -d; return va < vb ? -d : va > vb ? d : 0; }); } if (this._includes.length > 0 && this._resolver) { items = items.map(item => this._resolveIncludes(item)); } return items; }
801
862
  _resolveData() { let key; if (this._locale) { key = this._locale; } else if (this._defaultLocale && this._data.has(this._defaultLocale)) { key = this._defaultLocale; } else { key = this._data.keys().next().value; } return [...(this._data.get(key) ?? [])]; }
802
863
  _resolveIncludes(item) {
803
864
  const resolved = { ...item };
865
+ const _loc = this._locale ?? this._defaultLocale;
804
866
  for (const field of this._includes) {
805
867
  const meta = this._relationMeta[field]; if (!meta) continue;
806
868
  const targets = Array.isArray(meta.target) ? meta.target : [meta.target];
807
- if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, this._locale); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, this._locale); if (r) return r; } return id; }); } }
808
- else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, this._locale); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, this._locale); if (r) resolved[field] = r; } }
869
+ if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) return r; } return id; }); } }
870
+ else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) resolved[field] = r; } }
809
871
  }
810
872
  return resolved;
811
873
  }
@@ -848,10 +910,12 @@ async function generate(options) {
848
910
  const clientDir = join(projectRoot, ".contentrain", "client");
849
911
  const dataDir = join(clientDir, "data");
850
912
  const manifest = await readProjectManifest(projectRoot);
913
+ const cdnBaseUrl = options.cdnBaseUrl ?? manifest.config.cdn?.url;
914
+ const hasMedia = Boolean(cdnBaseUrl);
851
915
  const dataModules = await emitDataModules(manifest.models, manifest.contentFiles);
852
- const typesContent = emitTypes(manifest.models);
853
- const runtimeContent = emitRuntimeModule(manifest.models, dataModules, manifest.config.locales.default);
854
- const cjsContent = emitCjsWrapper(manifest.models);
916
+ const typesContent = emitTypes(manifest.models, hasMedia);
917
+ const runtimeContent = emitRuntimeModule(manifest.models, dataModules, manifest.config.locales.default, cdnBaseUrl);
918
+ const cjsContent = emitCjsWrapper(manifest.models, hasMedia);
855
919
  const newFileNames = new Set(dataModules.map((dm) => dm.fileName));
856
920
  try {
857
921
  const existing = await readDir(dataDir);
@@ -880,4 +944,4 @@ async function generate(options) {
880
944
  //#endregion
881
945
  export { generate as t };
882
946
 
883
- //# sourceMappingURL=generate-B5P14n43.mjs.map
947
+ //# sourceMappingURL=generate-mpKW9Y8v.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-mpKW9Y8v.mjs","names":[],"sources":["../src/generator/utils.ts","../src/generator/config-reader.ts","../src/generator/type-emitter.ts","../src/generator/data-emitter.ts","../src/generator/runtime-emitter.ts","../src/generator/package-json.ts","../src/generator/generate.ts"],"sourcesContent":["import { readFile, readdir, writeFile, mkdir } from 'node:fs/promises'\nimport { join, dirname } from 'node:path'\n\nexport async function readJson<T>(filePath: string): Promise<T | null> {\n try {\n const raw = await readFile(filePath, 'utf-8')\n return JSON.parse(raw) as T\n } catch {\n return null\n }\n}\n\nexport async function readDir(dirPath: string): Promise<string[]> {\n try {\n return await readdir(dirPath)\n } catch {\n return []\n }\n}\n\nexport async function readText(filePath: string): Promise<string | null> {\n try {\n return await readFile(filePath, 'utf-8')\n } catch {\n return null\n }\n}\n\nexport async function writeText(filePath: string, content: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true })\n await writeFile(filePath, content, 'utf-8')\n}\n\nexport function contentrainDir(projectRoot: string): string {\n return join(projectRoot, '.contentrain')\n}\n","import type { ContentrainConfig, ModelDefinition, LocaleStrategy } from '@contentrain/types'\nimport { join } from 'node:path'\nimport { readJson, readDir, readText, contentrainDir } from './utils.js'\n\nexport interface ContentFileRef {\n modelId: string\n locale: string | null\n filePath: string\n kind: ModelDefinition['kind']\n /** Extracted slug for document kind (from filename, not frontmatter) */\n slug?: string\n}\n\nexport interface ProjectManifest {\n config: ContentrainConfig\n models: ModelDefinition[]\n contentFiles: ContentFileRef[]\n}\n\nexport async function readProjectManifest(projectRoot: string): Promise<ProjectManifest> {\n const crDir = contentrainDir(projectRoot)\n\n // 1. Read config\n const rawConfig = await readJson<Partial<ContentrainConfig>>(join(crDir, 'config.json'))\n const config: ContentrainConfig = {\n version: rawConfig?.version ?? 1,\n stack: (rawConfig?.stack ?? 'other') as ContentrainConfig['stack'],\n workflow: (rawConfig?.workflow ?? 'auto-merge') as ContentrainConfig['workflow'],\n locales: {\n default: rawConfig?.locales?.default ?? 'en',\n supported: rawConfig?.locales?.supported ?? [rawConfig?.locales?.default ?? 'en'],\n },\n domains: rawConfig?.domains ?? [],\n repository: rawConfig?.repository,\n assets_path: rawConfig?.assets_path,\n cdn: rawConfig?.cdn,\n branchRetention: rawConfig?.branchRetention,\n }\n\n // 2. Read all models (parallel)\n const modelsDir = join(crDir, 'models')\n const modelFiles = (await readDir(modelsDir)).filter(f => f.endsWith('.json'))\n const modelResults = await Promise.all(\n modelFiles.map(file => readJson<ModelDefinition>(join(modelsDir, file))),\n )\n const models = modelResults\n .filter((m): m is ModelDefinition => m != null && Boolean(m.id))\n .toSorted((a, b) => a.id.localeCompare(b.id, 'en'))\n\n // 3. Map content files (parallel per model)\n const allRefs = await Promise.all(\n models.map(model => mapContentFiles(projectRoot, model, config)),\n )\n const contentFiles = allRefs.flat()\n\n return { config, models, contentFiles }\n}\n\nfunction getContentDir(projectRoot: string, model: ModelDefinition): string {\n if (model.content_path) return join(projectRoot, model.content_path)\n return join(contentrainDir(projectRoot), 'content', model.domain, model.id)\n}\n\nfunction getLocaleStrategy(model: ModelDefinition): LocaleStrategy {\n return model.locale_strategy ?? 'file'\n}\n\nfunction jsonFilePath(dir: string, model: ModelDefinition, locale: string): string {\n const strategy = getLocaleStrategy(model)\n switch (strategy) {\n case 'suffix': return join(dir, `${model.id}.${locale}.json`)\n case 'directory': return join(dir, locale, `${model.id}.json`)\n case 'none': return join(dir, `${model.id}.json`)\n case 'file':\n default: return join(dir, `${locale}.json`)\n }\n}\n\nasync function mapContentFiles(\n projectRoot: string,\n model: ModelDefinition,\n config: ContentrainConfig,\n): Promise<ContentFileRef[]> {\n const dir = getContentDir(projectRoot, model)\n\n if (model.kind === 'document') {\n return mapDocumentFiles(dir, model, config)\n }\n\n // JSON-based models (singleton, collection, dictionary)\n if (model.i18n) {\n const results = await Promise.all(\n config.locales.supported.map(async (locale) => {\n const filePath = jsonFilePath(dir, model, locale)\n const content = await readJson(filePath)\n if (content === null) return null\n return { modelId: model.id, locale, filePath, kind: model.kind } as ContentFileRef\n }),\n )\n return results.filter(Boolean) as ContentFileRef[]\n }\n\n // Non-i18n: always data.json\n const filePath = join(dir, 'data.json')\n const content = await readJson(filePath)\n if (content === null) return []\n return [{ modelId: model.id, locale: null, filePath, kind: model.kind }]\n}\n\nasync function mapDocumentFiles(\n dir: string,\n model: ModelDefinition,\n config: ContentrainConfig,\n): Promise<ContentFileRef[]> {\n const strategy = getLocaleStrategy(model)\n\n if (!model.i18n) {\n // Non-i18n documents: {dir}/{slug}.md\n const files = (await readDir(dir)).filter(f => f.endsWith('.md'))\n return files.map(f => ({\n modelId: model.id,\n locale: null,\n filePath: join(dir, f),\n kind: 'document' as const,\n slug: f.replace('.md', ''),\n }))\n }\n\n // i18n documents — resolve per locale in parallel\n const allLocaleRefs = await Promise.all(\n config.locales.supported.map(locale => mapDocumentLocale(dir, model, locale, strategy)),\n )\n return allLocaleRefs.flat()\n}\n\nasync function mapDocumentLocale(\n dir: string,\n model: ModelDefinition,\n locale: string,\n strategy: LocaleStrategy,\n): Promise<ContentFileRef[]> {\n if (strategy === 'file') {\n // Each slug is a directory: {dir}/{slug}/{locale}.md\n const entries = await readDir(dir)\n const results = await Promise.all(\n entries.map(async (entry) => {\n const filePath = join(dir, entry, `${locale}.md`)\n const content = await readText(filePath)\n if (content === null) return null\n return { modelId: model.id, locale, filePath, kind: 'document', slug: entry } as ContentFileRef\n }),\n )\n return results.filter(Boolean) as ContentFileRef[]\n }\n\n if (strategy === 'directory') {\n // {dir}/{locale}/{slug}.md\n const localeDir = join(dir, locale)\n const files = (await readDir(localeDir)).filter(f => f.endsWith('.md'))\n return files.map(f => ({\n modelId: model.id,\n locale,\n filePath: join(localeDir, f),\n kind: 'document' as const,\n slug: f.replace('.md', ''),\n }))\n }\n\n if (strategy === 'suffix') {\n // {dir}/{slug}.{locale}.md\n const suffix = `.${locale}.md`\n const files = (await readDir(dir)).filter(f => f.endsWith(suffix))\n return files.map(f => ({\n modelId: model.id,\n locale,\n filePath: join(dir, f),\n kind: 'document' as const,\n slug: f.slice(0, -suffix.length),\n }))\n }\n\n return []\n}\n","import type { ModelDefinition, FieldDef } from '@contentrain/types'\n\nexport function emitTypes(models: ModelDefinition[], hasMedia = false): string {\n const lines: string[] = [\n '/* eslint-disable */',\n '/* oxlint-disable */',\n '// Auto-generated by @contentrain/query — do not edit manually',\n '// Re-generate with: npx contentrain-query generate',\n '',\n \"export type ContentStatus = 'draft' | 'published' | 'in_review' | 'rejected' | 'archived'\",\n \"export type WhereOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains'\",\n '',\n ]\n\n // Model interfaces\n for (const model of models) {\n if (model.kind === 'dictionary') {\n lines.push(`export type ${kebabToPascal(model.id)} = Record<string, string>`)\n } else {\n lines.push(`export interface ${kebabToPascal(model.id)} {`)\n // System fields by kind. Track their names so a model-defined field of\n // the same name is not emitted twice (the base field wins).\n const baseNames = new Set<string>()\n if (model.kind === 'collection') {\n lines.push(' id: string')\n baseNames.add('id')\n }\n if (model.kind === 'document') {\n lines.push(' slug: string')\n lines.push(' body: string')\n baseNames.add('slug')\n baseNames.add('body')\n }\n // User fields\n if (model.fields) {\n for (const [name, field] of Object.entries(model.fields)) {\n if (baseNames.has(name)) continue\n const tsType = fieldToTS(field)\n const optional = field.required ? '' : '?'\n lines.push(` ${name}${optional}: ${tsType}`)\n }\n }\n lines.push('}')\n }\n lines.push('')\n }\n\n // Query interfaces\n lines.push(`export interface QueryBuilder<T> {\n locale(lang: string): QueryBuilder<T>\n where<K extends keyof T>(field: K, value: T[K]): QueryBuilder<T>\n where<K extends keyof T>(field: K, op: WhereOp, value: unknown): QueryBuilder<T>\n sort<K extends keyof T>(field: K, order?: 'asc' | 'desc'): QueryBuilder<T>\n limit(n: number): QueryBuilder<T>\n offset(n: number): QueryBuilder<T>\n include<K extends keyof T & string>(...fields: K[]): QueryBuilder<T>\n count(): number\n first(): T | undefined\n all(): T[]\n}`)\n lines.push('')\n\n lines.push(`export interface SingletonAccessor<T> {\n locale(lang: string): SingletonAccessor<T>\n include<K extends keyof T & string>(...fields: K[]): SingletonAccessor<T>\n get(): T\n}`)\n lines.push('')\n\n lines.push(`export interface DictionaryAccessor {\n locale(lang: string): DictionaryAccessor\n get(): Record<string, string>\n get(key: string): string | undefined\n get(key: string, params: Record<string, string | number>): string\n}`)\n lines.push('')\n\n lines.push(`export interface DocumentQuery<T> {\n locale(lang: string): DocumentQuery<T>\n where<K extends keyof T>(field: K, value: T[K]): DocumentQuery<T>\n where<K extends keyof T>(field: K, op: WhereOp, value: unknown): DocumentQuery<T>\n sort<K extends keyof T>(field: K, order?: 'asc' | 'desc'): DocumentQuery<T>\n include<K extends keyof T & string>(...fields: K[]): DocumentQuery<T>\n bySlug(slug: string): T | undefined\n count(): number\n first(): T | undefined\n all(): T[]\n}`)\n lines.push('')\n\n // Overloaded entry points\n const collections = models.filter(m => m.kind === 'collection')\n const singletons = models.filter(m => m.kind === 'singleton')\n const dictionaries = models.filter(m => m.kind === 'dictionary')\n const documents = models.filter(m => m.kind === 'document')\n\n // query() overloads\n for (const m of collections) {\n lines.push(`export declare function query(model: '${m.id}'): QueryBuilder<${kebabToPascal(m.id)}>`)\n }\n lines.push('export declare function query(model: string): QueryBuilder<Record<string, unknown>>')\n lines.push('')\n\n // singleton() overloads\n for (const m of singletons) {\n lines.push(`export declare function singleton(model: '${m.id}'): SingletonAccessor<${kebabToPascal(m.id)}>`)\n }\n lines.push('export declare function singleton(model: string): SingletonAccessor<Record<string, unknown>>')\n lines.push('')\n\n // dictionary() overloads\n for (const m of dictionaries) {\n lines.push(`export declare function dictionary(model: '${m.id}'): DictionaryAccessor`)\n }\n lines.push('export declare function dictionary(model: string): DictionaryAccessor')\n lines.push('')\n\n // document() overloads\n for (const m of documents) {\n lines.push(`export declare function document(model: '${m.id}'): DocumentQuery<${kebabToPascal(m.id)}>`)\n }\n lines.push('export declare function document(model: string): DocumentQuery<Record<string, unknown>>')\n lines.push('')\n\n // media() resolver — emitted only when a CDN delivery base is configured.\n if (hasMedia) {\n lines.push('/** Resolve a stored `media/...` path to its absolute delivery URL. External URLs and already-absolute values pass through unchanged. */')\n lines.push('export declare function media(value: string): string')\n lines.push('')\n }\n\n // Typed client interface\n lines.push('export interface ContentrainClient {')\n for (const m of collections) {\n lines.push(` query(model: '${m.id}'): QueryBuilder<${kebabToPascal(m.id)}>`)\n }\n lines.push(' query(model: string): QueryBuilder<Record<string, unknown>>')\n for (const m of singletons) {\n lines.push(` singleton(model: '${m.id}'): SingletonAccessor<${kebabToPascal(m.id)}>`)\n }\n lines.push(' singleton(model: string): SingletonAccessor<Record<string, unknown>>')\n for (const m of dictionaries) {\n lines.push(` dictionary(model: '${m.id}'): DictionaryAccessor`)\n }\n lines.push(' dictionary(model: string): DictionaryAccessor')\n for (const m of documents) {\n lines.push(` document(model: '${m.id}'): DocumentQuery<${kebabToPascal(m.id)}>`)\n }\n lines.push(' document(model: string): DocumentQuery<Record<string, unknown>>')\n lines.push('}')\n lines.push('')\n lines.push('export declare function createContentrainClient(): ContentrainClient')\n lines.push('')\n\n return lines.join('\\n') + '\\n'\n}\n\nfunction fieldToTS(field: FieldDef): string {\n switch (field.type) {\n case 'string': case 'text': case 'email': case 'url': case 'slug':\n case 'color': case 'phone': case 'code': case 'icon':\n case 'markdown': case 'richtext':\n case 'date': case 'datetime':\n case 'image': case 'video': case 'file':\n case 'relation': {\n if (Array.isArray(field.model) && field.model.length > 1) {\n const union = field.model.map(m => `'${m}'`).join(' | ')\n return `{ model: ${union}; ref: string }`\n }\n // Single-target relation: stored as an id string, but include() resolves\n // it to the target entry, so the field can be either at read time.\n const target = Array.isArray(field.model) ? field.model[0] : field.model\n return target ? `string | ${kebabToPascal(target)}` : 'string'\n }\n\n case 'relations': {\n if (Array.isArray(field.model) && field.model.length > 1) {\n const union = field.model.map(m => `'${m}'`).join(' | ')\n return `Array<{ model: ${union}; ref: string }>`\n }\n const target = Array.isArray(field.model) ? field.model[0] : field.model\n return target ? `Array<string | ${kebabToPascal(target)}>` : 'string[]'\n }\n\n case 'number': case 'integer': case 'decimal': case 'percent': case 'rating':\n return 'number'\n\n case 'boolean':\n return 'boolean'\n\n case 'select':\n if (field.options && field.options.length > 0) {\n return field.options.map(o => `'${o}'`).join(' | ')\n }\n return 'string'\n\n case 'array':\n if (field.items) {\n if (typeof field.items === 'string') {\n return `${primitiveToTS(field.items)}[]`\n }\n // items is a FieldDef\n return `${fieldToTS(field.items)}[]`\n }\n return 'unknown[]'\n\n case 'object':\n if (field.fields) {\n const entries = Object.entries(field.fields)\n .map(([k, v]) => `${k}${v.required ? '' : '?'}: ${fieldToTS(v)}`)\n .join('; ')\n return `{ ${entries} }`\n }\n return 'Record<string, unknown>'\n\n default:\n return 'unknown'\n }\n}\n\nfunction primitiveToTS(type: string): string {\n if (['string', 'text', 'email', 'url', 'slug', 'color', 'phone', 'code', 'icon',\n 'markdown', 'richtext', 'date', 'datetime', 'image', 'video', 'file', 'relation'].includes(type)) {\n return 'string'\n }\n if (['number', 'integer', 'decimal', 'percent', 'rating'].includes(type)) {\n return 'number'\n }\n if (type === 'boolean') return 'boolean'\n return 'unknown'\n}\n\nfunction kebabToPascal(s: string): string {\n return s.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n","import type { ModelDefinition } from '@contentrain/types'\nimport type { ContentFileRef } from './config-reader.js'\nimport { readJson, readText } from './utils.js'\n\n/** Deterministic JSON: sorted keys, 2-space indent, trailing newline */\nfunction canonicalStringify(data: unknown): string {\n return JSON.stringify(data, (_, v) => {\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n return Object.keys(v).toSorted().reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = (v as Record<string, unknown>)[k]\n return acc\n }, {})\n }\n return v\n }, 2)\n}\n\nexport interface DataModule {\n fileName: string\n content: string\n}\n\nexport async function emitDataModules(\n models: ModelDefinition[],\n contentFiles: ContentFileRef[],\n): Promise<DataModule[]> {\n const results = await Promise.all(\n contentFiles.map(ref => emitSingleModule(ref, models)),\n )\n return results.filter((r): r is DataModule => r !== null)\n}\n\nasync function emitSingleModule(\n ref: ContentFileRef,\n models: ModelDefinition[],\n): Promise<DataModule | null> {\n const model = models.find(m => m.id === ref.modelId)\n if (!model) return null\n\n const localeSuffix = ref.locale ? `.${ref.locale}` : ''\n\n switch (model.kind) {\n case 'collection': {\n const raw = await readJson<Record<string, Record<string, unknown>>>(ref.filePath)\n if (!raw) return null\n const entries = Object.entries(raw)\n .toSorted(([a], [b]) => a.localeCompare(b, 'en'))\n .map(([id, fields]) => Object.assign({ id }, fields))\n return { fileName: `${model.id}${localeSuffix}.mjs`, content: `export default ${canonicalStringify(entries)}\\n` }\n }\n\n case 'singleton': {\n const raw = await readJson<Record<string, unknown>>(ref.filePath)\n if (!raw) return null\n return { fileName: `${model.id}${localeSuffix}.mjs`, content: `export default ${canonicalStringify(raw)}\\n` }\n }\n\n case 'dictionary': {\n const raw = await readJson<Record<string, string>>(ref.filePath)\n if (!raw) return null\n return { fileName: `${model.id}${localeSuffix}.mjs`, content: `export default ${canonicalStringify(raw)}\\n` }\n }\n\n case 'document': {\n const rawText = await readText(ref.filePath)\n if (!rawText) return null\n const { frontmatter, body } = parseFrontmatter(rawText, stringLikeFieldKeys(model))\n const slug = ref.slug ?? model.id\n // Canonical document field is `body` (matches @contentrain/types\n // DocumentEntry.body and the MCP document_save schema).\n const data = { slug, ...frontmatter, body }\n return { fileName: `${model.id}--${slug}${localeSuffix}.mjs`, content: `export default ${canonicalStringify(data)}\\n` }\n }\n\n default:\n return null\n }\n}\n\n// Field types that map to `string` in the generated types — their frontmatter\n// values must NOT be numerically coerced (e.g. a string SKU \"007\").\nconst STRING_LIKE_TYPES = new Set([\n 'string', 'text', 'email', 'url', 'slug', 'color', 'phone', 'code', 'icon',\n 'markdown', 'richtext', 'date', 'datetime', 'image', 'video', 'file',\n 'select', 'relation',\n])\n\nfunction stringLikeFieldKeys(model: ModelDefinition): Set<string> {\n const keys = new Set<string>()\n if (model.fields) {\n for (const [name, field] of Object.entries(model.fields)) {\n if (STRING_LIKE_TYPES.has(field.type)) keys.add(name)\n }\n }\n return keys\n}\n\n// Minimal frontmatter parser (replicated from MCP pattern)\nfunction parseFrontmatter(text: string, stringKeys: Set<string> = new Set()): { frontmatter: Record<string, unknown>; body: string } {\n const normalized = text.replace(/\\r\\n/g, '\\n')\n const match = normalized.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/)\n if (!match) return { frontmatter: {}, body: normalized }\n\n const fmStr = match[1]!\n const body = match[2]!.trim()\n const frontmatter: Record<string, unknown> = {}\n\n // Stack-based parser that handles nested objects and arrays\n const lines = fmStr.split('\\n')\n const stack: Array<{ obj: Record<string, unknown>; indent: number }> = [{ obj: frontmatter, indent: -1 }]\n\n for (const line of lines) {\n // Skip empty lines\n if (line.trim() === '') continue\n\n // Array item\n const arrayMatch = line.match(/^(\\s*)-\\s+(.*)$/)\n if (arrayMatch) {\n const arrIndent = arrayMatch[1]!.length\n const value = arrayMatch[2]!.trim()\n // Find the parent that owns this array\n while (stack.length > 1 && stack[stack.length - 1]!.indent >= arrIndent) {\n stack.pop()\n }\n const parent = stack[stack.length - 1]!.obj\n const lastKey = Object.keys(parent).pop()\n if (lastKey && Array.isArray(parent[lastKey])) {\n (parent[lastKey] as unknown[]).push(parseValue(value))\n }\n continue\n }\n\n // Key-value pair\n const kvMatch = line.match(/^(\\s*)([\\w][\\w.-]*)\\s*:\\s*(.*)$/)\n if (!kvMatch) continue\n\n const kvIndent = kvMatch[1]!.length\n const key = kvMatch[2]!\n const rawValue = kvMatch[3]!.trim()\n\n // Pop stack to find correct parent based on indentation\n while (stack.length > 1 && stack[stack.length - 1]!.indent >= kvIndent) {\n stack.pop()\n }\n const current = stack[stack.length - 1]!.obj\n\n if (rawValue === '') {\n // Could be nested object or array — peek next line\n const nextLineIdx = lines.indexOf(line) + 1\n const nextLine = nextLineIdx < lines.length ? lines[nextLineIdx]! : ''\n if (nextLine.trim().startsWith('-')) {\n current[key] = []\n } else {\n const nested: Record<string, unknown> = {}\n current[key] = nested\n stack.push({ obj: nested, indent: kvIndent })\n }\n continue\n }\n\n if (rawValue.startsWith('[') && rawValue.endsWith(']')) {\n current[key] = rawValue.slice(1, -1).split(',').map(s => s.trim()).filter(Boolean)\n continue\n }\n\n // Only top-level keys are matched against the model's declared field types.\n const forceString = current === frontmatter && stringKeys.has(key)\n current[key] = parseValue(rawValue, forceString)\n }\n\n return { frontmatter, body }\n}\n\nfunction parseValue(raw: string, forceString = false): unknown {\n const isQuoted = (raw.startsWith('\"') && raw.endsWith('\"')) || (raw.startsWith(\"'\") && raw.endsWith(\"'\"))\n const unquoted = isQuoted ? raw.slice(1, -1) : raw\n if (forceString) return unquoted\n if (isQuoted) return unquoted\n if (raw === 'true') return true\n if (raw === 'false') return false\n if (raw === 'null') return null\n if (/^-?\\d+$/.test(raw)) return parseInt(raw, 10)\n if (/^-?\\d+\\.\\d+$/.test(raw)) return parseFloat(raw)\n return raw\n}\n","import type { ModelDefinition } from '@contentrain/types'\nimport type { DataModule } from './data-emitter.js'\n\nexport function emitRuntimeModule(models: ModelDefinition[], dataModules: DataModule[], defaultLocale?: string, cdnBaseUrl?: string): string {\n const lines: string[] = [\n '/* eslint-disable */',\n '/* oxlint-disable */',\n '// Auto-generated by @contentrain/query — do not edit manually',\n '',\n ]\n\n // Emit default locale constant if provided\n if (defaultLocale) {\n lines.push(`const _defaultLocale = '${defaultLocale}'`)\n lines.push('')\n }\n\n // Emit the media delivery base constant if a CDN base was configured. The\n // base is trimmed of trailing slashes here so the resolver is a plain join.\n if (cdnBaseUrl) {\n lines.push(`const _mediaBase = ${JSON.stringify(cdnBaseUrl.replace(/\\/+$/, ''))}`)\n lines.push('')\n }\n\n // Import data modules\n for (const dm of dataModules) {\n const varName = fileNameToVar(dm.fileName)\n lines.push(`import ${varName} from './data/${dm.fileName}'`)\n }\n lines.push('')\n\n // Inline minimal runtime classes\n lines.push(RUNTIME_CODE)\n lines.push('')\n\n // Build registry\n lines.push('// ─── Data Registry ───')\n lines.push('')\n\n // Group data modules by modelId\n const modelDataMap = new Map<string, { varName: string; locale: string | null }[]>()\n for (const dm of dataModules) {\n const { modelId, locale } = parseDataFileName(dm.fileName)\n if (!modelDataMap.has(modelId)) modelDataMap.set(modelId, [])\n modelDataMap.get(modelId)!.push({ varName: fileNameToVar(dm.fileName), locale })\n }\n\n // Create factory functions for each kind\n const collections = models.filter(m => m.kind === 'collection')\n const singletons = models.filter(m => m.kind === 'singleton')\n const dictionaries = models.filter(m => m.kind === 'dictionary')\n const documents = models.filter(m => m.kind === 'document')\n\n // Generate relation metadata for models that have relation fields\n const relationMetaMap = buildRelationMetaMap(models)\n\n // Generate _resolveEntry helper (needed if any model has relations)\n if (relationMetaMap.size > 0) {\n lines.push('// ─── Relation Resolver ───')\n lines.push('')\n lines.push('function _resolveEntry(model, id, locale) {')\n // Try the requested locale first, then fall back to the locale-agnostic\n // '_default' key. i18n:true targets are keyed by locale string ('en'),\n // i18n:false targets are keyed '_default' — this fallback resolves both\n // regardless of the source query's active locale.\n lines.push(' const localeKeys = locale ? [locale, \\'_default\\'] : [\\'_default\\']')\n lines.push(' for (const localeKey of localeKeys) {')\n // Search in collection registry\n if (collections.length > 0) {\n lines.push(' const colData = _collectionRegistry[model]?.get(localeKey)')\n lines.push(' if (colData) { const e = colData.find(x => x.id === id); if (e) return e; }')\n }\n // Search in document registry\n if (documents.length > 0) {\n lines.push(' const docData = _documentRegistry[model]?.get(localeKey)')\n lines.push(' if (docData) { const e = docData.find(x => x.slug === id); if (e) return e; }')\n }\n lines.push(' }')\n lines.push(' return undefined')\n lines.push('}')\n lines.push('')\n\n // Emit relation meta objects\n lines.push('const _relationMeta = {')\n for (const [modelId, meta] of relationMetaMap) {\n lines.push(` '${modelId}': {`)\n for (const [field, info] of Object.entries(meta)) {\n const targetStr = Array.isArray(info.target)\n ? `[${info.target.map(t => `'${t}'`).join(', ')}]`\n : `'${info.target}'`\n lines.push(` '${field}': { target: ${targetStr}, multi: ${info.multi} },`)\n }\n lines.push(' },')\n }\n lines.push('}')\n lines.push('')\n }\n\n // query() function\n if (collections.length > 0) {\n lines.push('const _collectionRegistry = {')\n for (const m of collections) {\n const entries = modelDataMap.get(m.id) ?? []\n lines.push(` '${m.id}': new Map([`)\n for (const e of entries) {\n const localeKey = e.locale ?? '_default'\n lines.push(` ['${localeKey}', ${e.varName}],`)\n }\n lines.push(' ]),')\n }\n lines.push('}')\n lines.push('')\n lines.push('export function query(model) {')\n lines.push(' const data = _collectionRegistry[model]')\n lines.push(' if (!data) throw new Error(`Unknown collection model: \"${model}\"`)')\n if (relationMetaMap.size > 0 && defaultLocale) {\n lines.push(' return new QueryBuilder(data, _relationMeta[model], _resolveEntry, _defaultLocale)')\n } else if (relationMetaMap.size > 0) {\n lines.push(' return new QueryBuilder(data, _relationMeta[model], _resolveEntry)')\n } else if (defaultLocale) {\n lines.push(' return new QueryBuilder(data, undefined, undefined, _defaultLocale)')\n } else {\n lines.push(' return new QueryBuilder(data)')\n }\n lines.push('}')\n lines.push('')\n }\n\n // singleton() function\n if (singletons.length > 0) {\n lines.push('const _singletonRegistry = {')\n for (const m of singletons) {\n const entries = modelDataMap.get(m.id) ?? []\n lines.push(` '${m.id}': new Map([`)\n for (const e of entries) {\n const localeKey = e.locale ?? '_default'\n lines.push(` ['${localeKey}', ${e.varName}],`)\n }\n lines.push(' ]),')\n }\n lines.push('}')\n lines.push('')\n lines.push('export function singleton(model) {')\n lines.push(' const data = _singletonRegistry[model]')\n lines.push(' if (!data) throw new Error(`Unknown singleton model: \"${model}\"`)')\n if (relationMetaMap.size > 0 && defaultLocale) {\n lines.push(' return new SingletonAccessor(data, _defaultLocale, _relationMeta[model], _resolveEntry)')\n } else if (relationMetaMap.size > 0) {\n lines.push(' return new SingletonAccessor(data, undefined, _relationMeta[model], _resolveEntry)')\n } else if (defaultLocale) {\n lines.push(' return new SingletonAccessor(data, _defaultLocale)')\n } else {\n lines.push(' return new SingletonAccessor(data)')\n }\n lines.push('}')\n lines.push('')\n }\n\n // dictionary() function\n if (dictionaries.length > 0) {\n lines.push('const _dictionaryRegistry = {')\n for (const m of dictionaries) {\n const entries = modelDataMap.get(m.id) ?? []\n lines.push(` '${m.id}': new Map([`)\n for (const e of entries) {\n const localeKey = e.locale ?? '_default'\n lines.push(` ['${localeKey}', ${e.varName}],`)\n }\n lines.push(' ]),')\n }\n lines.push('}')\n lines.push('')\n lines.push('export function dictionary(model) {')\n lines.push(' const data = _dictionaryRegistry[model]')\n lines.push(' if (!data) throw new Error(`Unknown dictionary model: \"${model}\"`)')\n lines.push(defaultLocale ? ' return new DictionaryAccessor(data, _defaultLocale)' : ' return new DictionaryAccessor(data)')\n lines.push('}')\n lines.push('')\n }\n\n // document() function\n if (documents.length > 0) {\n // Group document data modules by model+locale and merge into arrays\n for (const m of documents) {\n const entries = modelDataMap.get(m.id) ?? []\n // Group entries by locale\n const byLocale = new Map<string, string[]>()\n for (const e of entries) {\n const localeKey = e.locale ?? '_default'\n if (!byLocale.has(localeKey)) byLocale.set(localeKey, [])\n byLocale.get(localeKey)!.push(e.varName)\n }\n lines.push(`const _doc_${m.id.replace(/-/g, '_')} = new Map([`)\n for (const [localeKey, varNames] of byLocale) {\n lines.push(` ['${localeKey}', [${varNames.join(', ')}]],`)\n }\n lines.push('])')\n }\n lines.push('')\n lines.push('const _documentRegistry = {')\n for (const m of documents) {\n lines.push(` '${m.id}': _doc_${m.id.replace(/-/g, '_')},`)\n }\n lines.push('}')\n lines.push('')\n lines.push('export function document(model) {')\n lines.push(' const data = _documentRegistry[model]')\n lines.push(' if (!data) throw new Error(`Unknown document model: \"${model}\"`)')\n if (relationMetaMap.size > 0 && defaultLocale) {\n lines.push(' return new DocumentQuery(data, _relationMeta[model], _resolveEntry, _defaultLocale)')\n } else if (relationMetaMap.size > 0) {\n lines.push(' return new DocumentQuery(data, _relationMeta[model], _resolveEntry)')\n } else if (defaultLocale) {\n lines.push(' return new DocumentQuery(data, undefined, undefined, _defaultLocale)')\n } else {\n lines.push(' return new DocumentQuery(data)')\n }\n lines.push('}')\n lines.push('')\n }\n\n // media() resolver — only when a CDN base is configured. Mirrors the rewrite\n // rules of the write path: a stored `media/...` path becomes an absolute\n // delivery URL; external URLs and already-absolute values pass through, so it\n // is safe to call on any field value (idempotent).\n if (cdnBaseUrl) {\n lines.push('// ─── Media ───')\n lines.push('')\n lines.push('export function media(value) {')\n lines.push(' if (typeof value !== \\'string\\' || !value.startsWith(\\'media/\\')) return value')\n lines.push(' return _mediaBase + \\'/\\' + value')\n lines.push('}')\n lines.push('')\n }\n\n return lines.join('\\n') + '\\n'\n}\n\nexport function emitCjsWrapper(models: ModelDefinition[], hasMedia = false): string {\n const exports: string[] = []\n if (models.some(m => m.kind === 'collection')) exports.push('query')\n if (models.some(m => m.kind === 'singleton')) exports.push('singleton')\n if (models.some(m => m.kind === 'dictionary')) exports.push('dictionary')\n if (models.some(m => m.kind === 'document')) exports.push('document')\n if (hasMedia) exports.push('media')\n\n return `/* eslint-disable */\n/* oxlint-disable */\n// Auto-generated CJS proxy — delegates to ESM via dynamic import()\n// The generated client is ESM-first. From CommonJS, await init() once before\n// accessing exports:\n// const client = await require('#contentrain').init()\n// client.query('model')\n// Prefer native ESM (import) where possible.\n'use strict'\nlet _mod = null\nlet _promise = null\n\nmodule.exports.init = function() {\n if (!_promise) _promise = import('./index.mjs').then(function(m) {\n _mod = m\n${exports.map(e => ` module.exports.${e} = m.${e}`).join('\\n')}\n return module.exports\n })\n return _promise\n}\n\n// Eagerly start loading so subsequent sync calls work after first await\n_promise = import('./index.mjs').then(function(m) {\n _mod = m\n${exports.map(e => ` module.exports.${e} = m.${e}`).join('\\n')}\n return module.exports\n}).catch(function() { _promise = null; /* retry on next init() call */ })\n`\n}\n\nfunction buildRelationMetaMap(\n models: ModelDefinition[],\n): Map<string, Record<string, { target: string | string[]; multi: boolean }>> {\n const result = new Map<string, Record<string, { target: string | string[]; multi: boolean }>>()\n\n for (const model of models) {\n if (!model.fields) continue\n const meta: Record<string, { target: string | string[]; multi: boolean }> = {}\n let hasRelations = false\n\n for (const [fieldName, field] of Object.entries(model.fields)) {\n if (field.type === 'relation' && field.model) {\n meta[fieldName] = { target: field.model, multi: false }\n hasRelations = true\n } else if (field.type === 'relations' && field.model) {\n meta[fieldName] = { target: field.model, multi: true }\n hasRelations = true\n }\n }\n\n if (hasRelations) {\n result.set(model.id, meta)\n }\n }\n\n return result\n}\n\nfunction fileNameToVar(fileName: string): string {\n // blog-post.en.mjs → _blogPostEn\n const base = fileName.replace('.mjs', '')\n const parts = base.split(/[-.]/)\n return '_' + parts.map((p, i) => i === 0 ? p : p.charAt(0).toUpperCase() + p.slice(1)).join('')\n}\n\nfunction parseDataFileName(fileName: string): { modelId: string; locale: string | null } {\n const base = fileName.replace('.mjs', '')\n\n // Document files use \"modelId--slug.locale\" or \"modelId--slug\" format\n // Extract modelId from before \"--\", ignore slug part\n let nameForLocale = base\n if (base.includes('--')) {\n nameForLocale = base // locale is still the last dot-segment\n }\n\n // Extract locale from last dot-segment (e.g., \"blog-post.en\" → locale \"en\")\n const parts = nameForLocale.split('.')\n let locale: string | null = null\n let nameWithoutLocale = nameForLocale\n if (parts.length >= 2) {\n const possibleLocale = parts[parts.length - 1]!\n if (possibleLocale.length === 2 || possibleLocale.includes('-')) {\n locale = possibleLocale\n nameWithoutLocale = parts.slice(0, -1).join('.')\n }\n }\n\n // Extract modelId: if \"--\" present, it's the part before \"--\"\n const modelId = nameWithoutLocale.includes('--')\n ? nameWithoutLocale.split('--')[0]!\n : nameWithoutLocale\n\n return { modelId, locale }\n}\n\n// Inlined runtime code — zero dependencies\nconst RUNTIME_CODE = `\n// ─── Runtime Helpers ───\n\nfunction _applyWhere(item, clause) {\n const val = item[clause.field];\n switch (clause.op) {\n case 'eq': return Array.isArray(val) ? val.includes(clause.value) : val === clause.value;\n case 'ne': return Array.isArray(val) ? !val.includes(clause.value) : val !== clause.value;\n case 'gt': return val > clause.value;\n case 'gte': return val >= clause.value;\n case 'lt': return val < clause.value;\n case 'lte': return val <= clause.value;\n case 'in': return Array.isArray(clause.value) && clause.value.includes(val);\n case 'contains': {\n if (typeof val === 'string') return val.includes(clause.value);\n if (Array.isArray(val)) return val.includes(clause.value);\n return false;\n }\n default: return true;\n }\n}\n\n// ─── Runtime Classes ───\n\nclass QueryBuilder {\n constructor(data, relationMeta, resolver, defaultLocale) { this._data = data; this._filters = []; this._sortField = null; this._sortOrder = 'asc'; this._limit = null; this._offset = 0; this._locale = null; this._includes = []; this._relationMeta = relationMeta || {}; this._resolver = resolver || null; this._defaultLocale = defaultLocale || null; }\n locale(lang) { this._locale = lang; return this; }\n where(field, opOrValue, value) { if (value !== undefined) { this._filters.push({ field, op: opOrValue, value }); } else { this._filters.push({ field, op: 'eq', value: opOrValue }); } return this; }\n sort(field, order = 'asc') { this._sortField = field; this._sortOrder = order; return this; }\n limit(n) { this._limit = n; return this; }\n offset(n) { this._offset = n; return this; }\n include(...fields) { this._includes.push(...fields); return this; }\n count() { return this.all().length; }\n all() {\n let items; if (this._locale) { items = [...(this._data.get(this._locale) ?? [])]; } else if (this._defaultLocale && this._data.has(this._defaultLocale)) { items = [...this._data.get(this._defaultLocale)]; } else { items = [...(this._data.get(this._data.keys().next().value) ?? [])]; }\n for (const clause of this._filters) items = items.filter(item => _applyWhere(item, clause));\n if (this._sortField) { const sf = this._sortField; const d = this._sortOrder === 'asc' ? 1 : -1; items.sort((a, b) => { const va = a[sf], vb = b[sf]; if (va == null && vb == null) return 0; if (va == null) return d; if (vb == null) return -d; return va < vb ? -d : va > vb ? d : 0; }); }\n if (this._offset > 0 || this._limit !== null) { const end = this._limit !== null ? this._offset + this._limit : undefined; items = items.slice(this._offset, end); }\n if (this._includes.length > 0 && this._resolver) { items = items.map(item => this._resolveIncludes(item)); }\n return items;\n }\n first() { return this.all()[0]; }\n _resolveIncludes(item) {\n const resolved = { ...item };\n const _loc = this._locale ?? this._defaultLocale;\n for (const field of this._includes) {\n const meta = this._relationMeta[field]; if (!meta) continue;\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target];\n if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) return r; } return id; }); } }\n else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) resolved[field] = r; } }\n }\n return resolved;\n }\n}\n\nclass SingletonAccessor {\n constructor(data, defaultLocale, relationMeta, resolveEntry) { this._data = data; this._locale = null; this._defaultLocale = defaultLocale || null; this._includes = []; this._relationMeta = relationMeta || {}; this._resolver = resolveEntry; }\n locale(lang) { this._locale = lang; return this; }\n include(...fields) { this._includes.push(...fields); return this; }\n get() {\n const locale = this._locale || this._defaultLocale;\n let d = locale ? this._data.get(locale) : undefined;\n if (!d) { const key = this._data.keys().next().value; d = key !== undefined ? this._data.get(key) : undefined; }\n if (!d) throw new Error('No data available');\n if (this._includes.length > 0 && this._resolver) return this._resolveIncludes(d, locale || 'en');\n return d;\n }\n _resolveIncludes(item, locale) {\n const resolved = { ...item };\n for (const field of this._includes) {\n const meta = this._relationMeta[field]; if (!meta) continue;\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target];\n if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, locale); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, locale); if (r) return r; } return id; }); } }\n else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, locale); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, locale); if (r) resolved[field] = r; } }\n }\n return resolved;\n }\n}\n\nclass DictionaryAccessor {\n constructor(data, defaultLocale) { this._data = data; this._locale = null; this._defaultLocale = defaultLocale || null; }\n locale(lang) { this._locale = lang; return this; }\n get(key, params) {\n let dict; if (this._locale) { dict = this._data.get(this._locale) ?? {}; } else if (this._defaultLocale && this._data.has(this._defaultLocale)) { dict = this._data.get(this._defaultLocale); } else { const loc = this._data.keys().next().value; dict = this._data.get(loc) ?? {}; }\n if (key === undefined) return dict;\n const val = dict[key];\n if (val === undefined) return undefined;\n if (params) return val.replace(/\\\\{(\\\\w+)\\\\}/g, (m, k) => { const v = params[k]; return v !== undefined ? String(v) : m; });\n return val;\n }\n}\n\nclass DocumentQuery {\n constructor(data, relationMeta, resolver, defaultLocale) { this._data = data; this._filters = []; this._sortField = null; this._sortOrder = 'asc'; this._locale = null; this._includes = []; this._relationMeta = relationMeta || {}; this._resolver = resolver || null; this._defaultLocale = defaultLocale || null; }\n locale(lang) { this._locale = lang; return this; }\n where(field, opOrValue, value) { if (value !== undefined) { this._filters.push({ field, op: opOrValue, value }); } else { this._filters.push({ field, op: 'eq', value: opOrValue }); } return this; }\n sort(field, order = 'asc') { this._sortField = field; this._sortOrder = order; return this; }\n include(...fields) { this._includes.push(...fields); return this; }\n bySlug(slug) {\n const items = this._resolveData(); const item = items.find(x => x.slug === slug);\n if (item && this._includes.length > 0 && this._resolver) return this._resolveIncludes(item);\n return item;\n }\n count() { return this.all().length; }\n first() { return this.all()[0]; }\n all() { let items = this._resolveData(); for (const clause of this._filters) items = items.filter(item => _applyWhere(item, clause)); if (this._sortField) { const sf = this._sortField; const d = this._sortOrder === 'asc' ? 1 : -1; items.sort((a, b) => { const va = a[sf], vb = b[sf]; if (va == null && vb == null) return 0; if (va == null) return d; if (vb == null) return -d; return va < vb ? -d : va > vb ? d : 0; }); } if (this._includes.length > 0 && this._resolver) { items = items.map(item => this._resolveIncludes(item)); } return items; }\n _resolveData() { let key; if (this._locale) { key = this._locale; } else if (this._defaultLocale && this._data.has(this._defaultLocale)) { key = this._defaultLocale; } else { key = this._data.keys().next().value; } return [...(this._data.get(key) ?? [])]; }\n _resolveIncludes(item) {\n const resolved = { ...item };\n const _loc = this._locale ?? this._defaultLocale;\n for (const field of this._includes) {\n const meta = this._relationMeta[field]; if (!meta) continue;\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target];\n if (meta.multi) { const ids = item[field]; if (Array.isArray(ids)) { resolved[field] = ids.map(id => { if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) return r; } return id; } if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) return r; } return id; }); } }\n else { const id = item[field]; if (typeof id === 'string') { for (const t of targets) { const r = this._resolver(t, id, _loc); if (r) { resolved[field] = r; break; } } } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) { const r = this._resolver(id.model, id.ref, _loc); if (r) resolved[field] = r; } }\n }\n return resolved;\n }\n}\n`.trim()\n","import { join } from 'node:path'\nimport { readJson, writeText } from './utils.js'\n\nconst IMPORTS_CONFIG = {\n '#contentrain': {\n types: './.contentrain/client/index.d.ts',\n import: './.contentrain/client/index.mjs',\n require: './.contentrain/client/index.cjs',\n default: './.contentrain/client/index.mjs',\n },\n '#contentrain/*': {\n types: './.contentrain/client/*.d.ts',\n import: './.contentrain/client/*.mjs',\n require: './.contentrain/client/*.cjs',\n default: './.contentrain/client/*.mjs',\n },\n}\n\nexport async function injectImports(projectRoot: string): Promise<boolean> {\n const pkgPath = join(projectRoot, 'package.json')\n const pkg = await readJson<Record<string, unknown>>(pkgPath)\n if (!pkg) return false\n\n const existing = (pkg['imports'] as Record<string, unknown>) ?? {}\n const updated = { ...existing, ...IMPORTS_CONFIG }\n\n // Check if already matches\n if (JSON.stringify(existing['#contentrain']) === JSON.stringify(IMPORTS_CONFIG['#contentrain']) &&\n JSON.stringify(existing['#contentrain/*']) === JSON.stringify(IMPORTS_CONFIG['#contentrain/*'])) {\n return false // No change needed\n }\n\n pkg['imports'] = updated\n await writeText(pkgPath, JSON.stringify(pkg, null, 2) + '\\n')\n return true\n}\n","import { join } from 'node:path'\nimport { rm } from 'node:fs/promises'\nimport { readProjectManifest } from './config-reader.js'\nimport { emitTypes } from './type-emitter.js'\nimport { emitDataModules } from './data-emitter.js'\nimport { emitRuntimeModule, emitCjsWrapper } from './runtime-emitter.js'\nimport { injectImports } from './package-json.js'\nimport { readDir, writeText } from './utils.js'\n\nexport interface GenerateOptions {\n projectRoot: string\n /**\n * Public media delivery base for resolving relative `media/...` references to\n * absolute URLs. When set (or when `config.cdn.url` is present), the emitted\n * client gains a `media(path)` resolver. The explicit option wins over the\n * config value. Omit for the pure local-file model — media stays a relative\n * path.\n */\n cdnBaseUrl?: string\n}\n\nexport interface GenerateResult {\n generatedFiles: string[]\n typesCount: number\n dataModulesCount: number\n packageJsonUpdated: boolean\n}\n\nexport async function generate(options: GenerateOptions): Promise<GenerateResult> {\n const { projectRoot } = options\n const clientDir = join(projectRoot, '.contentrain', 'client')\n const dataDir = join(clientDir, 'data')\n\n // 1. Read project manifest\n const manifest = await readProjectManifest(projectRoot)\n\n // Media delivery base: explicit option wins over config.cdn.url. When set,\n // the emitted client gains a `media()` resolver.\n const cdnBaseUrl = options.cdnBaseUrl ?? manifest.config.cdn?.url\n const hasMedia = Boolean(cdnBaseUrl)\n\n // 2. Generate data modules (async — reads content files)\n const dataModules = await emitDataModules(manifest.models, manifest.contentFiles)\n\n // 3. Generate all output content (sync — pure string transforms)\n const typesContent = emitTypes(manifest.models, hasMedia)\n const runtimeContent = emitRuntimeModule(manifest.models, dataModules, manifest.config.locales.default, cdnBaseUrl)\n const cjsContent = emitCjsWrapper(manifest.models, hasMedia)\n\n // 4. Clean stale data modules\n const newFileNames = new Set(dataModules.map(dm => dm.fileName))\n try {\n const existing = await readDir(dataDir)\n await Promise.all(\n existing\n .filter(f => !newFileNames.has(f))\n .map(f => rm(join(dataDir, f), { force: true })),\n )\n } catch { /* dataDir may not exist yet */ }\n\n // 5. Write all files in parallel\n const dataFileNames = dataModules.map(dm => `data/${dm.fileName}`)\n await Promise.all([\n writeText(join(clientDir, 'index.d.ts'), typesContent),\n writeText(join(clientDir, 'index.mjs'), runtimeContent),\n writeText(join(clientDir, 'index.cjs'), cjsContent),\n ...dataModules.map(dm => writeText(join(dataDir, dm.fileName), dm.content)),\n ])\n\n // 6. Inject #imports into package.json\n const packageJsonUpdated = await injectImports(projectRoot)\n\n return {\n generatedFiles: ['index.d.ts', ...dataFileNames, 'index.mjs', 'index.cjs'],\n typesCount: manifest.models.length,\n dataModulesCount: dataModules.length,\n packageJsonUpdated,\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_generate = require("../generate-DAaCl3Np.cjs");
2
+ const require_generate = require("../generate-DN3mAbvC.cjs");
3
3
  exports.generate = require_generate.generate;
@@ -1,6 +1,14 @@
1
1
  //#region src/generator/generate.d.ts
2
2
  interface GenerateOptions {
3
3
  projectRoot: string;
4
+ /**
5
+ * Public media delivery base for resolving relative `media/...` references to
6
+ * absolute URLs. When set (or when `config.cdn.url` is present), the emitted
7
+ * client gains a `media(path)` resolver. The explicit option wins over the
8
+ * config value. Omit for the pure local-file model — media stays a relative
9
+ * path.
10
+ */
11
+ cdnBaseUrl?: string;
4
12
  }
5
13
  interface GenerateResult {
6
14
  generatedFiles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.cts","names":[],"sources":["../../src/generator/generate.ts"],"mappings":";UASiB,eAAA;EACf,WAAA;AAAA;AAAA,UAGe,cAAA;EACf,cAAA;EACA,UAAA;EACA,gBAAA;EACA,kBAAA;AAAA;AAAA,iBAGoB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,cAAA"}
1
+ {"version":3,"file":"generate.d.cts","names":[],"sources":["../../src/generator/generate.ts"],"mappings":";UASiB,eAAA;EACf,WAAA;EAD8B;;;;AAYhC;;;EAHE,UAAA;AAAA;AAAA,UAGe,cAAA;EACf,cAAA;EACA,UAAA;EACA,gBAAA;EACA,kBAAA;AAAA;AAAA,iBAGoB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,cAAA"}
@@ -1,6 +1,14 @@
1
1
  //#region src/generator/generate.d.ts
2
2
  interface GenerateOptions {
3
3
  projectRoot: string;
4
+ /**
5
+ * Public media delivery base for resolving relative `media/...` references to
6
+ * absolute URLs. When set (or when `config.cdn.url` is present), the emitted
7
+ * client gains a `media(path)` resolver. The explicit option wins over the
8
+ * config value. Omit for the pure local-file model — media stays a relative
9
+ * path.
10
+ */
11
+ cdnBaseUrl?: string;
4
12
  }
5
13
  interface GenerateResult {
6
14
  generatedFiles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.mts","names":[],"sources":["../../src/generator/generate.ts"],"mappings":";UASiB,eAAA;EACf,WAAA;AAAA;AAAA,UAGe,cAAA;EACf,cAAA;EACA,UAAA;EACA,gBAAA;EACA,kBAAA;AAAA;AAAA,iBAGoB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,cAAA"}
1
+ {"version":3,"file":"generate.d.mts","names":[],"sources":["../../src/generator/generate.ts"],"mappings":";UASiB,eAAA;EACf,WAAA;EAD8B;;;;AAYhC;;;EAHE,UAAA;AAAA;AAAA,UAGe,cAAA;EACf,cAAA;EACA,UAAA;EACA,gBAAA;EACA,kBAAA;AAAA;AAAA,iBAGoB,QAAA,CAAS,OAAA,EAAS,eAAA,GAAkB,OAAA,CAAQ,cAAA"}
@@ -1,2 +1,2 @@
1
- import { t as generate } from "../generate-B5P14n43.mjs";
1
+ import { t as generate } from "../generate-mpKW9Y8v.mjs";
2
2
  export { generate };
@@ -107,9 +107,12 @@ declare class CdnDocumentQuery<T extends object> {
107
107
  private _source;
108
108
  private _locale;
109
109
  private _filters;
110
+ private _sortField;
111
+ private _sortOrder;
110
112
  constructor(source: DocumentDataSource<T>, defaultLocale?: string);
111
113
  locale(lang: string): this;
112
114
  where(field: string, op: WhereOp, value: unknown): this;
115
+ sort(field: string, order?: 'asc' | 'desc'): this;
113
116
  all(): Promise<T[]>;
114
117
  count(): Promise<number>;
115
118
  first(): Promise<T | undefined>;
@@ -282,4 +285,4 @@ declare function createContentrain(config: ContentrainCDNConfig): {
282
285
  };
283
286
  //#endregion
284
287
  export { applyWhere as A, CdnDocumentQuery as C, EntryMeta as D, CdnCollectionQuery as E, SingletonDataSource as F, CollectionDataSource as M, DictionaryDataSource as N, WhereClause as O, DocumentDataSource as P, MediaManifest as S, CdnSingletonAccessor as T, FormsClient as _, ConversationClient as a, MediaAsset as b, ConversationHistory as c, ConversationSendOptions as d, ConversationToolResult as f, FormSubmitResult as g, FormFieldConfig as h, ContentrainError as i, HttpTransport as j, WhereOp as k, ConversationMessage as l, FormConfig as m, ContentrainCDNConfig as n, ConversationClientConfig as o, ConversationUsage as p, createContentrain as r, ConversationContext as s, ContentrainCDNClient as t, ConversationResponse as u, FormsClientConfig as v, CdnDictionaryAccessor as w, MediaAssetMeta as x, MediaAccessor as y };
285
- //# sourceMappingURL=index-BChs94uA.d.cts.map
288
+ //# sourceMappingURL=index-mBPlkuGU.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-mBPlkuGU.d.cts","names":[],"sources":["../src/cdn/data-source.ts","../src/cdn/http-transport.ts","../src/shared/where.ts","../src/cdn/collection-query.ts","../src/cdn/singleton-accessor.ts","../src/cdn/dictionary-accessor.ts","../src/cdn/document-query.ts","../src/cdn/media-accessor.ts","../src/cdn/forms-client.ts","../src/cdn/conversation-client.ts","../src/cdn/errors.ts","../src/cdn/index.ts"],"mappings":"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"}