@contentrain/query 7.4.2 → 7.5.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 +21 -2
- package/dist/cdn/index.cjs +2 -1
- package/dist/cdn/index.d.cts +2 -2
- package/dist/cdn/index.d.mts +2 -2
- package/dist/cdn/index.mjs +2 -2
- package/dist/{cdn-Do8lyms1.mjs → cdn-DlAwl84z.mjs} +33 -9
- package/dist/cdn-DlAwl84z.mjs.map +1 -0
- package/dist/{cdn-s8-GAk7S.cjs → cdn-DuTqMqyX.cjs} +37 -7
- package/dist/{index-D-hSDfue.d.cts → index-CqmcazRu.d.mts} +18 -3
- package/dist/{index-ClftI9li.d.mts.map → index-CqmcazRu.d.mts.map} +1 -1
- package/dist/{index-ClftI9li.d.mts → index-DZOztXQv.d.cts} +18 -3
- package/dist/{index-D-hSDfue.d.cts.map → index-DZOztXQv.d.cts.map} +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/publication-CMrWLPi7.d.mts.map +1 -1
- package/package.json +2 -2
- package/dist/cdn-Do8lyms1.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -359,7 +359,7 @@ const result = await form.submit('contact', {
|
|
|
359
359
|
}, { captchaToken: 'tok_xxx', honeypot: '' })
|
|
360
360
|
// → { success: true, message: 'Thank you!' }
|
|
361
361
|
// → { success: false, errors: [{ field: 'email', message }] } (a verdict, not an exception)
|
|
362
|
-
// 403 / 404 / 429 reject with ContentrainError { status, message }
|
|
362
|
+
// 402 / 403 / 404 / 429 reject with ContentrainError { status, code?, message }
|
|
363
363
|
```
|
|
364
364
|
|
|
365
365
|
### Comments
|
|
@@ -385,9 +385,28 @@ const result = await comments.submit('posts', entryId, {
|
|
|
385
385
|
}, { locale: 'en' })
|
|
386
386
|
// → { success: true, status: 'pending' | 'approved', comment } (pending is only echoed to its author)
|
|
387
387
|
// → { success: false, errors: [{ field: 'author.name' | 'author.email' | 'author.url' | 'body' | 'parentId' | 'captcha', message }] }
|
|
388
|
-
// 403 (thread closed) / 404 / 429 reject with ContentrainError
|
|
388
|
+
// 402 / 403 (thread closed) / 404 / 429 reject with ContentrainError
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
+
When the workspace's subscription is inactive, forms and comments reject with
|
|
392
|
+
`402` and `code: 'payment_required'`. The message is written for the workspace
|
|
393
|
+
owner, not a visitor, and retrying does not help until the owner updates
|
|
394
|
+
billing, so hide the form or thread:
|
|
395
|
+
|
|
396
|
+
```ts
|
|
397
|
+
import { isPaymentRequired } from '@contentrain/query'
|
|
398
|
+
|
|
399
|
+
try {
|
|
400
|
+
await form.submit('contact', values)
|
|
401
|
+
} catch (err) {
|
|
402
|
+
if (isPaymentRequired(err)) hideTheForm() // no retry, no message to the visitor
|
|
403
|
+
else showError(err)
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
`ContentrainError.code` carries the API's machine code (`data.code`) whenever
|
|
408
|
+
the error body has one. Branch on `status` or `code`, never on the message.
|
|
409
|
+
|
|
391
410
|
### Conversation API
|
|
392
411
|
|
|
393
412
|
Send messages to the AI content agent and manage conversation history:
|
package/dist/cdn/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_cdn = require("../cdn-
|
|
2
|
+
const require_cdn = require("../cdn-DuTqMqyX.cjs");
|
|
3
3
|
exports.CdnCollectionQuery = require_cdn.CdnCollectionQuery;
|
|
4
4
|
exports.CdnDictionaryAccessor = require_cdn.CdnDictionaryAccessor;
|
|
5
5
|
exports.CdnDocumentQuery = require_cdn.CdnDocumentQuery;
|
|
@@ -11,3 +11,4 @@ exports.FormsClient = require_cdn.FormsClient;
|
|
|
11
11
|
exports.HttpTransport = require_cdn.HttpTransport;
|
|
12
12
|
exports.MediaAccessor = require_cdn.MediaAccessor;
|
|
13
13
|
exports.createContentrain = require_cdn.createContentrain;
|
|
14
|
+
exports.isPaymentRequired = require_cdn.isPaymentRequired;
|
package/dist/cdn/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CollectionDataSource, CommentAuthor, CommentFieldError, CommentSubmission, CommentSubmitResult, CommentThread, CommentThreadConfig, CommentThreadQuery, CommentType, CommentsClient, CommentsClientConfig, ContentrainCDNClient, ContentrainCDNConfig, ContentrainError, ConversationClient, ConversationClientConfig, ConversationContext, ConversationHistory, ConversationMessage, ConversationResponse, ConversationSendOptions, ConversationToolResult, ConversationUsage, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry, FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClient, FormsClientConfig, HttpTransport, MediaAccessor, MediaAsset, MediaAssetMeta, MediaManifest, PublicComment, SingletonDataSource, TransportConfig, createContentrain };
|
|
1
|
+
import { A as FormSubmitResult, B as CdnCollectionQuery, C as CommentsClient, D as FormFieldConfig, E as FormConfig, F as MediaAssetMeta, G as HttpTransport, I as MediaManifest, J as DictionaryDataSource, K as TransportConfig, L as CdnDocumentQuery, M as FormsClientConfig, N as MediaAccessor, O as FormFieldError, P as MediaAsset, R as CdnDictionaryAccessor, S as CommentType, T as PublicComment, X as DocumentIndexEntry, Y as DocumentDataSource, Z as SingletonDataSource, _ as CommentSubmission, a as isPaymentRequired, b as CommentThreadConfig, c as ConversationContext, d as ConversationResponse, f as ConversationSendOptions, g as CommentFieldError, h as CommentAuthor, i as ContentrainError, j as FormsClient, k as FormSubmitOptions, l as ConversationHistory, m as ConversationUsage, n as ContentrainCDNConfig, o as ConversationClient, p as ConversationToolResult, q as CollectionDataSource, r as createContentrain, s as ConversationClientConfig, t as ContentrainCDNClient, u as ConversationMessage, v as CommentSubmitResult, w as CommentsClientConfig, x as CommentThreadQuery, y as CommentThread, z as CdnSingletonAccessor } from "../index-DZOztXQv.cjs";
|
|
2
|
+
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CollectionDataSource, CommentAuthor, CommentFieldError, CommentSubmission, CommentSubmitResult, CommentThread, CommentThreadConfig, CommentThreadQuery, CommentType, CommentsClient, CommentsClientConfig, ContentrainCDNClient, ContentrainCDNConfig, ContentrainError, ConversationClient, ConversationClientConfig, ConversationContext, ConversationHistory, ConversationMessage, ConversationResponse, ConversationSendOptions, ConversationToolResult, ConversationUsage, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry, FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClient, FormsClientConfig, HttpTransport, MediaAccessor, MediaAsset, MediaAssetMeta, MediaManifest, PublicComment, SingletonDataSource, TransportConfig, createContentrain, isPaymentRequired };
|
package/dist/cdn/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CollectionDataSource, CommentAuthor, CommentFieldError, CommentSubmission, CommentSubmitResult, CommentThread, CommentThreadConfig, CommentThreadQuery, CommentType, CommentsClient, CommentsClientConfig, ContentrainCDNClient, ContentrainCDNConfig, ContentrainError, ConversationClient, ConversationClientConfig, ConversationContext, ConversationHistory, ConversationMessage, ConversationResponse, ConversationSendOptions, ConversationToolResult, ConversationUsage, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry, FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClient, FormsClientConfig, HttpTransport, MediaAccessor, MediaAsset, MediaAssetMeta, MediaManifest, PublicComment, SingletonDataSource, TransportConfig, createContentrain };
|
|
1
|
+
import { A as FormSubmitResult, B as CdnCollectionQuery, C as CommentsClient, D as FormFieldConfig, E as FormConfig, F as MediaAssetMeta, G as HttpTransport, I as MediaManifest, J as DictionaryDataSource, K as TransportConfig, L as CdnDocumentQuery, M as FormsClientConfig, N as MediaAccessor, O as FormFieldError, P as MediaAsset, R as CdnDictionaryAccessor, S as CommentType, T as PublicComment, X as DocumentIndexEntry, Y as DocumentDataSource, Z as SingletonDataSource, _ as CommentSubmission, a as isPaymentRequired, b as CommentThreadConfig, c as ConversationContext, d as ConversationResponse, f as ConversationSendOptions, g as CommentFieldError, h as CommentAuthor, i as ContentrainError, j as FormsClient, k as FormSubmitOptions, l as ConversationHistory, m as ConversationUsage, n as ContentrainCDNConfig, o as ConversationClient, p as ConversationToolResult, q as CollectionDataSource, r as createContentrain, s as ConversationClientConfig, t as ContentrainCDNClient, u as ConversationMessage, v as CommentSubmitResult, w as CommentsClientConfig, x as CommentThreadQuery, y as CommentThread, z as CdnSingletonAccessor } from "../index-CqmcazRu.mjs";
|
|
2
|
+
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CollectionDataSource, CommentAuthor, CommentFieldError, CommentSubmission, CommentSubmitResult, CommentThread, CommentThreadConfig, CommentThreadQuery, CommentType, CommentsClient, CommentsClientConfig, ContentrainCDNClient, ContentrainCDNConfig, ContentrainError, ConversationClient, ConversationClientConfig, ConversationContext, ConversationHistory, ConversationMessage, ConversationResponse, ConversationSendOptions, ConversationToolResult, ConversationUsage, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry, FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClient, FormsClientConfig, HttpTransport, MediaAccessor, MediaAsset, MediaAssetMeta, MediaManifest, PublicComment, SingletonDataSource, TransportConfig, createContentrain, isPaymentRequired };
|
package/dist/cdn/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as MediaAccessor, c as CdnSingletonAccessor, d as ContentrainError, i as FormsClient, l as CdnCollectionQuery, n as ConversationClient, o as CdnDocumentQuery, r as CommentsClient, s as CdnDictionaryAccessor, t as createContentrain, u as HttpTransport } from "../cdn-
|
|
2
|
-
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CommentsClient, ContentrainError, ConversationClient, FormsClient, HttpTransport, MediaAccessor, createContentrain };
|
|
1
|
+
import { a as MediaAccessor, c as CdnSingletonAccessor, d as ContentrainError, f as isPaymentRequired, i as FormsClient, l as CdnCollectionQuery, n as ConversationClient, o as CdnDocumentQuery, r as CommentsClient, s as CdnDictionaryAccessor, t as createContentrain, u as HttpTransport } from "../cdn-DlAwl84z.mjs";
|
|
2
|
+
export { CdnCollectionQuery, CdnDictionaryAccessor, CdnDocumentQuery, CdnSingletonAccessor, CommentsClient, ContentrainError, ConversationClient, FormsClient, HttpTransport, MediaAccessor, createContentrain, isPaymentRequired };
|
|
@@ -23,12 +23,32 @@ function applyWhere(item, clause) {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region src/cdn/errors.ts
|
|
25
25
|
var ContentrainError = class extends Error {
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* The API's machine code, when the error body carries one (`data.code`,
|
|
28
|
+
* e.g. `payment_required`). Branch on it or on `status`, never on the
|
|
29
|
+
* message: that is display text, and some is written for the workspace
|
|
30
|
+
* owner rather than a visitor.
|
|
31
|
+
*/
|
|
32
|
+
code;
|
|
33
|
+
constructor(status, message, code) {
|
|
27
34
|
super(message);
|
|
28
35
|
this.status = status;
|
|
29
36
|
this.name = "ContentrainError";
|
|
37
|
+
if (code) this.code = code;
|
|
30
38
|
}
|
|
31
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* The workspace's subscription is inactive: Studio answers `402` with
|
|
42
|
+
* `data.code: 'payment_required'` on the public forms and comments endpoints
|
|
43
|
+
* while billing is locked. Not transient — no retry helps until the owner
|
|
44
|
+
* updates billing — and its message addresses the owner, so a site hides the
|
|
45
|
+
* form or thread instead of showing it to a visitor.
|
|
46
|
+
*/
|
|
47
|
+
function isPaymentRequired(error) {
|
|
48
|
+
if (!error || typeof error !== "object") return false;
|
|
49
|
+
const e = error;
|
|
50
|
+
return e.name === "ContentrainError" && (e.status === 402 || e.code === "payment_required");
|
|
51
|
+
}
|
|
32
52
|
//#endregion
|
|
33
53
|
//#region src/cdn/http-transport.ts
|
|
34
54
|
/** Paths eligible for bundle serving — everything else (manifests, models/*) has no locale segment. */
|
|
@@ -429,18 +449,22 @@ var MediaAccessor = class {
|
|
|
429
449
|
};
|
|
430
450
|
//#endregion
|
|
431
451
|
//#region src/cdn/public-request.ts
|
|
432
|
-
|
|
452
|
+
/** The h3 error body's message and machine code (`data.code`), or the raw text. */
|
|
453
|
+
async function errorOf(res, fallback) {
|
|
433
454
|
const text = await res.text().catch(() => "");
|
|
455
|
+
let message = text || fallback;
|
|
456
|
+
let code;
|
|
434
457
|
try {
|
|
435
458
|
const parsed = JSON.parse(text);
|
|
436
|
-
const
|
|
437
|
-
if (typeof
|
|
459
|
+
const m = parsed.message ?? parsed.statusMessage;
|
|
460
|
+
if (typeof m === "string" && m) message = m;
|
|
461
|
+
if (typeof parsed.data?.code === "string") code = parsed.data.code;
|
|
438
462
|
} catch {}
|
|
439
|
-
return
|
|
463
|
+
return new ContentrainError(res.status, message, code);
|
|
440
464
|
}
|
|
441
465
|
async function publicGet(url) {
|
|
442
466
|
const res = await globalThis.fetch(url);
|
|
443
|
-
if (!res.ok) throw
|
|
467
|
+
if (!res.ok) throw await errorOf(res, "Request failed");
|
|
444
468
|
return await res.json();
|
|
445
469
|
}
|
|
446
470
|
async function publicPost(url, body) {
|
|
@@ -449,7 +473,7 @@ async function publicPost(url, body) {
|
|
|
449
473
|
headers: { "Content-Type": "application/json" },
|
|
450
474
|
body: JSON.stringify(body)
|
|
451
475
|
});
|
|
452
|
-
if (!res.ok) throw
|
|
476
|
+
if (!res.ok) throw await errorOf(res, "Request failed");
|
|
453
477
|
return await res.json();
|
|
454
478
|
}
|
|
455
479
|
/** `baseUrl` without a trailing slash, path segments URL-encoded. */
|
|
@@ -607,6 +631,6 @@ function createContentrain(config) {
|
|
|
607
631
|
};
|
|
608
632
|
}
|
|
609
633
|
//#endregion
|
|
610
|
-
export { MediaAccessor as a, CdnSingletonAccessor as c, ContentrainError as d,
|
|
634
|
+
export { MediaAccessor as a, CdnSingletonAccessor as c, ContentrainError as d, isPaymentRequired as f, FormsClient as i, CdnCollectionQuery as l, ConversationClient as n, CdnDocumentQuery as o, applyWhere as p, CommentsClient as r, CdnDictionaryAccessor as s, createContentrain as t, HttpTransport as u };
|
|
611
635
|
|
|
612
|
-
//# sourceMappingURL=cdn-
|
|
636
|
+
//# sourceMappingURL=cdn-DlAwl84z.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn-DlAwl84z.mjs","names":[],"sources":["../src/shared/where.ts","../src/cdn/errors.ts","../src/cdn/http-transport.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/public-request.ts","../src/cdn/forms-client.ts","../src/cdn/comments-client.ts","../src/cdn/conversation-client.ts","../src/cdn/index.ts"],"sourcesContent":["export type WhereOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains'\n\nexport interface WhereClause {\n field: string\n op: WhereOp\n value: unknown\n}\n\nexport function applyWhere<T>(item: T, clause: WhereClause): boolean {\n const val = (item as Record<string, unknown>)[clause.field]\n switch (clause.op) {\n case 'eq': {\n if (Array.isArray(val)) return val.includes(clause.value)\n return val === clause.value\n }\n case 'ne': {\n if (Array.isArray(val)) return !val.includes(clause.value)\n return val !== clause.value\n }\n case 'gt': return (val as number) > (clause.value as number)\n case 'gte': return (val as number) >= (clause.value as number)\n case 'lt': return (val as number) < (clause.value as number)\n case 'lte': return (val as number) <= (clause.value as number)\n case 'in': return Array.isArray(clause.value) && (clause.value as unknown[]).includes(val)\n case 'contains': {\n if (typeof val === 'string') return val.includes(clause.value as string)\n if (Array.isArray(val)) return val.includes(clause.value)\n return false\n }\n default: return true\n }\n}\n","export class ContentrainError extends Error {\n /**\n * The API's machine code, when the error body carries one (`data.code`,\n * e.g. `payment_required`). Branch on it or on `status`, never on the\n * message: that is display text, and some is written for the workspace\n * owner rather than a visitor.\n */\n code?: string\n\n constructor(\n public status: number,\n message: string,\n code?: string,\n ) {\n super(message)\n this.name = 'ContentrainError'\n if (code) this.code = code\n }\n}\n\n/**\n * The workspace's subscription is inactive: Studio answers `402` with\n * `data.code: 'payment_required'` on the public forms and comments endpoints\n * while billing is locked. Not transient — no retry helps until the owner\n * updates billing — and its message addresses the owner, so a site hides the\n * form or thread instead of showing it to a visitor.\n */\nexport function isPaymentRequired(error: unknown): boolean {\n // By shape, not instanceof: a page can bundle two copies of the SDK (ESM\n // and CJS, or a duplicate install), and an error from one is not an\n // instance of the other's class.\n if (!error || typeof error !== 'object') return false\n const e = error as { name?: unknown; status?: unknown; code?: unknown }\n return e.name === 'ContentrainError' && (e.status === 402 || e.code === 'payment_required')\n}\n","import { ContentrainError } from './errors.js'\nimport type { CollectionDataSource, SingletonDataSource, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry } from './data-source.js'\n\ninterface CacheEntry {\n data: unknown\n etag: string\n}\n\nexport interface TransportConfig {\n baseUrl: string\n projectId: string\n apiKey: string\n /** Bundle preload mode. `true` → `{ revalidateMs: 60_000 }` */\n bundle?: boolean | { revalidateMs?: number }\n defaultLocale?: string\n}\n\ninterface BundleState {\n fetchedAt: number\n paths: Set<string>\n missing: boolean\n inflight: Promise<void> | null\n}\n\ninterface BundlePayload {\n version?: string\n paths?: Record<string, unknown>\n}\n\n/** Paths eligible for bundle serving — everything else (manifests, models/*) has no locale segment. */\nconst BUNDLE_SCOPE = /^(content|documents|meta)\\//\n\nexport class HttpTransport {\n private _baseUrl: string\n private _projectId: string\n private _apiKey: string\n private _cache = new Map<string, CacheEntry>()\n private _bundleMode: boolean\n private _revalidateMs: number\n private _defaultLocale: string\n private _primed = new Map<string, unknown>()\n private _bundles = new Map<string, BundleState>()\n\n constructor(config: TransportConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n this._apiKey = config.apiKey\n const b = config.bundle\n this._bundleMode = !!b\n this._revalidateMs = typeof b === 'object' && typeof b.revalidateMs === 'number' ? b.revalidateMs : 60_000\n this._defaultLocale = config.defaultLocale ?? 'en'\n }\n\n buildUrl(path: string): string {\n return `${this._baseUrl}/${this._projectId}/${path}`\n }\n\n /** Eager warmup (e.g. SSR boot). Resolves `true` when a bundle was found and primed. */\n async preload(locale?: string): Promise<boolean> {\n if (!this._bundleMode) return false\n const l = locale ?? this._defaultLocale\n await this._ensureBundle(l)\n return !this._bundles.get(l)?.missing\n }\n\n async fetch<T>(path: string): Promise<T> {\n if (this._bundleMode && BUNDLE_SCOPE.test(path)) {\n await this._ensureBundle(this._localeOf(path))\n if (this._primed.has(path)) return this._primed.get(path) as T\n // out-of-scope path (doc body, meta, ...) → regular per-path fetch\n }\n return this._networkFetch<T>(path)\n }\n\n /** Locale from a path's last segment (sans `.json`). `data` (non-i18n) → defaultLocale bundle. */\n private _localeOf(path: string): string {\n const last = path.slice(path.lastIndexOf('/') + 1).replace(/\\.json$/, '')\n return last === 'data' ? this._defaultLocale : last\n }\n\n private _ensureBundle(locale: string): Promise<void> | void {\n const state = this._bundles.get(locale)\n if (state?.inflight) return state.inflight\n if (state && Date.now() - state.fetchedAt < this._revalidateMs) return\n\n const next: BundleState = state ?? { fetchedAt: 0, paths: new Set(), missing: false, inflight: null }\n this._bundles.set(locale, next)\n next.inflight = (async () => {\n try {\n // _networkFetch is conditional: unchanged bundle → 304 → cached payload (cheap)\n const bundle = await this._networkFetch<BundlePayload>(`_bundle/${locale}.json`)\n if (bundle?.version !== '1' || !bundle.paths || typeof bundle.paths !== 'object') {\n next.missing = true\n return\n }\n // Evict primed paths absent from the fresh bundle (deleted models must not serve stale)\n const fresh = new Set(Object.keys(bundle.paths))\n for (const p of next.paths) {\n if (!fresh.has(p)) this._primed.delete(p)\n }\n for (const [p, body] of Object.entries(bundle.paths)) this._primed.set(p, body)\n next.paths = fresh\n next.missing = false\n }\n catch {\n // 404 (bundle not built yet) or network error → per-path fallback until next revalidate\n next.missing = true\n }\n finally {\n next.fetchedAt = Date.now()\n next.inflight = null\n }\n })()\n return next.inflight\n }\n\n private async _networkFetch<T>(path: string): Promise<T> {\n const url = `${this._baseUrl}/${this._projectId}/${path}`\n const cached = this._cache.get(path)\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this._apiKey}`,\n }\n if (cached?.etag) {\n headers['If-None-Match'] = cached.etag\n }\n\n const res = await globalThis.fetch(url, { headers })\n\n if (res.status === 304 && cached) return cached.data as T\n if (!res.ok) throw new ContentrainError(res.status, await res.text())\n\n const data = (await res.json()) as T\n const etag = res.headers.get('etag') ?? ''\n if (etag) {\n this._cache.set(path, { data, etag })\n }\n return data\n }\n\n collection<T>(modelId: string): CollectionDataSource<T> {\n return {\n getAll: async (locale) => {\n const map = await this.fetch<Record<string, T>>(`content/${modelId}/${locale}.json`)\n return Object.entries(map).map(([id, entry]) => Object.assign({ id }, entry as object) as T)\n },\n getOne: async (id, locale) => {\n const map = await this.fetch<Record<string, T>>(`content/${modelId}/${locale}.json`)\n const entry = map[id]\n return entry ? { id, ...entry as object } as T : null\n },\n }\n }\n\n singleton<T>(modelId: string): SingletonDataSource<T> {\n return {\n get: (locale) => this.fetch<T>(`content/${modelId}/${locale}.json`),\n }\n }\n\n dictionary(modelId: string): DictionaryDataSource {\n return {\n get: (locale) => this.fetch<Record<string, string>>(`content/${modelId}/${locale}.json`),\n }\n }\n\n document<T>(modelId: string): DocumentDataSource<T> {\n return {\n // `_index` carries frontmatter only — the body is in the per-slug document.\n getIndex: (locale) => this.fetch<DocumentIndexEntry<T>[]>(`documents/${modelId}/_index/${locale}.json`),\n getBySlug: (slug, locale) => this.fetch(`documents/${modelId}/${slug}/${locale}.json`),\n }\n }\n}\n","import type { CollectionDataSource } from './data-source.js'\nimport type { HttpTransport } from './http-transport.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport interface EntryMeta {\n status?: string\n publish_at?: string\n expire_at?: string\n updated_by?: string\n approved_by?: string\n [key: string]: unknown\n}\n\nexport class CdnCollectionQuery<T extends object> {\n private _transport: HttpTransport\n private _source: CollectionDataSource<T>\n private _modelId: string\n private _locale: string = 'en'\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _limit: number | null = null\n private _offset = 0\n private _includes: string[] = []\n private _withMeta = false\n\n constructor(transport: HttpTransport, modelId: string, defaultLocale?: string) {\n this._transport = transport\n this._source = transport.collection<T>(modelId)\n this._modelId = modelId\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where(field: string, op: WhereOp, value: unknown): this {\n this._filters.push({ field, op, value })\n return this\n }\n\n sort(field: string, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n limit(n: number): this {\n this._limit = n\n return this\n }\n\n offset(n: number): this {\n this._offset = n\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n withMeta(): this {\n this._withMeta = true\n return this\n }\n\n async all(): Promise<T[]> {\n let items = await this._source.getAll(this._locale)\n\n // Filter\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n // Sort\n if (this._sortField) {\n const field = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[field]\n const vb = (b as Record<string, unknown>)[field]\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n if (va < vb) return -dir\n if (va > vb) return dir\n return 0\n })\n }\n\n // Pagination\n if (this._offset > 0 || this._limit !== null) {\n const end = this._limit !== null ? this._offset + this._limit : undefined\n items = items.slice(this._offset, end)\n }\n\n // Resolve relations\n if (this._includes.length > 0) {\n items = await this._resolveIncludes(items)\n }\n\n // Enrich with entry metadata\n if (this._withMeta) {\n items = await this._enrichMeta(items)\n }\n\n return items\n }\n\n async count(): Promise<number> {\n const items = await this.all()\n return items.length\n }\n\n async first(): Promise<T | undefined> {\n const items = await this.all()\n return items[0]\n }\n\n private async _resolveIncludes(items: T[]): Promise<T[]> {\n // Prefetch related collections to avoid N+1\n const cache = new Map<string, Map<string, Record<string, unknown>>>()\n\n for (const field of this._includes) {\n // Collect all IDs for this field\n for (const item of items) {\n const val = (item as Record<string, unknown>)[field]\n const ids = Array.isArray(val) ? val : val ? [val] : []\n for (const id of ids) {\n if (typeof id !== 'string') continue\n // We don't know the target model from here, so we use field name as hint\n // In production, model metadata would provide this mapping\n if (!cache.has(field)) {\n try {\n const related = await this._transport.fetch<Record<string, unknown>>(`content/${field}/${this._locale}.json`)\n const map = new Map<string, Record<string, unknown>>()\n for (const [entryId, entry] of Object.entries(related)) {\n map.set(entryId, { id: entryId, ...entry as object })\n }\n cache.set(field, map)\n } catch {\n cache.set(field, new Map())\n }\n break\n }\n }\n }\n }\n\n return items.map(item => {\n const resolved = { ...item }\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const related = cache.get(field)\n if (!related) continue\n const val = (item as Record<string, unknown>)[field]\n if (Array.isArray(val)) {\n dst[field] = val.map(id => typeof id === 'string' ? (related.get(id) ?? id) : id)\n } else if (typeof val === 'string') {\n dst[field] = related.get(val) ?? val\n }\n }\n return resolved\n })\n }\n\n private async _enrichMeta(items: T[]): Promise<T[]> {\n let metaMap: Record<string, EntryMeta> = {}\n try {\n metaMap = await this._transport.fetch<Record<string, EntryMeta>>(`meta/${this._modelId}/${this._locale}.json`)\n } catch {\n // No meta available — return items unchanged\n return items\n }\n return items.map(item => {\n const id = (item as Record<string, unknown>).id as string\n const meta = id ? metaMap[id] : undefined\n if (meta) {\n return { ...item, _meta: meta }\n }\n return item\n })\n }\n}\n\n","import type { SingletonDataSource } from './data-source.js'\n\nexport class CdnSingletonAccessor<T extends Record<string, unknown>> {\n private _source: SingletonDataSource<T>\n private _locale: string = 'en'\n\n constructor(source: SingletonDataSource<T>, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n async get(): Promise<T> {\n return this._source.get(this._locale)\n }\n}\n","import type { DictionaryDataSource } from './data-source.js'\n\nexport class CdnDictionaryAccessor {\n private _source: DictionaryDataSource\n private _locale: string = 'en'\n\n constructor(source: DictionaryDataSource, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n async get(): Promise<Record<string, string>>\n async get(key: string): Promise<string | undefined>\n async get(key: string, params: Record<string, string | number>): Promise<string>\n async get(key?: string, params?: Record<string, string | number>): Promise<Record<string, string> | string | undefined> {\n const dict = await this._source.get(this._locale)\n if (key === undefined) return dict\n const value = dict[key]\n if (value === undefined) return undefined\n if (params) return interpolate(value, params)\n return value\n }\n}\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const val = params[key]\n return val !== undefined ? String(val) : match\n })\n}\n","import type { DocumentDataSource, DocumentIndexEntry } from './data-source.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport class CdnDocumentQuery<T extends object> {\n private _source: DocumentDataSource<T>\n private _locale: string = 'en'\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n\n constructor(source: DocumentDataSource<T>, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where(field: string, op: WhereOp, value: unknown): this {\n this._filters.push({ field, op, value })\n return this\n }\n\n sort(field: string, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n /**\n * Every entry's frontmatter, from the model's `_index`.\n *\n * Bodies are not included — fetch one with {@link bySlug}. See\n * {@link DocumentIndexEntry}.\n */\n async all(): Promise<DocumentIndexEntry<T>[]> {\n let items = await this._source.getIndex(this._locale)\n\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n if (this._sortField) {\n const sf = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[sf] as number | string | null | undefined\n const vb = (b as Record<string, unknown>)[sf] as number | string | null | undefined\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n return va < vb ? -dir : va > vb ? dir : 0\n })\n }\n\n return items\n }\n\n async count(): Promise<number> {\n const items = await this.all()\n return items.length\n }\n\n async first(): Promise<DocumentIndexEntry<T> | undefined> {\n const items = await this.all()\n return items[0]\n }\n\n /** The full document: frontmatter plus its rendered body. */\n async bySlug(slug: string): Promise<{ frontmatter: T; body: string; html: string } | null> {\n return this._source.getBySlug(slug, this._locale)\n }\n}\n","import type { HttpTransport } from './http-transport.js'\n\nexport interface MediaAssetMeta {\n width?: number\n height?: number\n format?: string\n size?: number\n blurhash?: string | null\n alt?: string | null\n}\n\nexport interface MediaAsset {\n original: string\n variants: Record<string, string>\n meta: MediaAssetMeta\n}\n\nexport interface MediaManifest {\n version: string\n assets: Record<string, MediaAsset>\n}\n\nexport class MediaAccessor {\n private _transport: HttpTransport\n private _manifest: MediaManifest | null = null\n\n constructor(transport: HttpTransport) {\n this._transport = transport\n }\n\n async manifest(): Promise<MediaManifest> {\n if (!this._manifest) {\n this._manifest = await this._transport.fetch<MediaManifest>('_media_manifest.json')\n }\n return this._manifest\n }\n\n async assets(): Promise<Record<string, MediaAsset>> {\n const m = await this.manifest()\n return m.assets\n }\n\n async asset(path: string): Promise<MediaAsset | null> {\n const all = await this.assets()\n return all[path] ?? null\n }\n\n async list(): Promise<Array<{ path: string } & MediaAsset>> {\n const all = await this.assets()\n return Object.entries(all).map(([path, asset]) =>\n Object.assign({ path }, asset),\n )\n }\n\n resolve(asset: MediaAsset, variant?: string): string {\n if (variant && asset.variants[variant]) {\n return asset.variants[variant]\n }\n return asset.original\n }\n\n url(asset: MediaAsset, variant?: string): string {\n const path = this.resolve(asset, variant)\n return this._transport.buildUrl(path)\n }\n}\n","// Shared transport for the PUBLIC embed endpoints (forms, comments).\n//\n// These are called from a visitor's browser on someone else's site: no\n// session, no API key — a page cannot keep a secret, and Studio's CORS for\n// these routes allows only `Content-Type`, so an `Authorization` header would\n// fail the preflight before the request is even sent. Errors come back as\n// h3 error bodies (`{ statusCode, message, data? }`) or plain text; both become a\n// `ContentrainError` carrying the HTTP status and, when the body has one, its\n// machine code (`data.code`).\n\nimport { ContentrainError } from './errors.js'\n\n/** The h3 error body's message and machine code (`data.code`), or the raw text. */\nasync function errorOf(res: Response, fallback: string): Promise<ContentrainError> {\n const text = await res.text().catch(() => '')\n let message = text || fallback\n let code: string | undefined\n try {\n const parsed = JSON.parse(text) as { message?: unknown; statusMessage?: unknown; data?: { code?: unknown } }\n const m = parsed.message ?? parsed.statusMessage\n if (typeof m === 'string' && m) message = m\n if (typeof parsed.data?.code === 'string') code = parsed.data.code\n } catch {\n // not JSON — the raw text is the message\n }\n return new ContentrainError(res.status, message, code)\n}\n\nexport async function publicGet<T>(url: string): Promise<T> {\n const res = await globalThis.fetch(url)\n if (!res.ok) throw await errorOf(res, 'Request failed')\n return (await res.json()) as T\n}\n\nexport async function publicPost<T>(url: string, body: unknown): Promise<T> {\n const res = await globalThis.fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!res.ok) throw await errorOf(res, 'Request failed')\n return (await res.json()) as T\n}\n\n/** `baseUrl` without a trailing slash, path segments URL-encoded. */\nexport function publicUrl(baseUrl: string, segments: string[], query?: Record<string, string | number | undefined>): string {\n const path = segments.map((s) => encodeURIComponent(s)).join('/')\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query ?? {})) {\n if (value !== undefined) params.set(key, String(value))\n }\n const qs = params.toString()\n return `${baseUrl.replace(/\\/+$/, '')}/${path}${qs ? `?${qs}` : ''}`\n}\n","// Public forms client — the browser side of Studio's `/api/forms/v1`.\n//\n// Contract (Studio docs/FORMS.md):\n// GET {base}/{projectId}/{modelId}/config → FormConfig\n// POST {base}/{projectId}/{modelId}/submit { data, captchaToken?, _hp? } → FormSubmitResult\n//\n// `fields` is a map keyed by field id (the model's own FieldDef shape), not a\n// list; the captcha comes back as `captcha` + `captchaSiteKey`; the honeypot\n// input's name is `honeypotField`. Submissions wrap the values in `data` so\n// the control fields (`captchaToken`, `_hp`) can never collide with a model\n// field. No credential is sent: the endpoints are public by design.\n\nimport type { FieldDef } from '@contentrain/types'\nimport { publicGet, publicPost, publicUrl } from './public-request.js'\n\n/** One exposed field, as the model defines it. */\nexport type FormFieldConfig = FieldDef\n\nexport interface FormConfig {\n modelId: string\n /** The project's default locale — what a submission is validated against and written to. */\n locale: string\n /** Exposed fields only, keyed by field id. */\n fields: Record<string, FormFieldConfig>\n captcha: 'turnstile' | null\n /** Turnstile widget key, when `captcha` is set and the operator configured one. */\n captchaSiteKey: string | null\n successMessage?: string\n /** Name of the hidden honeypot input to render (and leave empty), or null. */\n honeypotField: string | null\n}\n\nexport interface FormFieldError {\n field: string\n message: string\n}\n\nexport interface FormSubmitResult {\n success: boolean\n /** The model's `successMessage` on success. */\n message?: string\n /** Validation errors against the exposed fields, or `captcha`. */\n errors?: FormFieldError[]\n}\n\nexport interface FormSubmitOptions {\n /** Turnstile token, when the config's `captcha` is set. */\n captchaToken?: string\n /** Value of the honeypot input. A human leaves it empty; a filled one is silently dropped server-side. */\n honeypot?: string\n}\n\nexport interface FormsClientConfig {\n /** Public API root — `https://studio.contentrain.io/api/forms/v1`. */\n baseUrl: string\n projectId: string\n}\n\nexport class FormsClient {\n private _baseUrl: string\n private _projectId: string\n\n constructor(config: FormsClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n }\n\n config(modelId: string): Promise<FormConfig> {\n return publicGet<FormConfig>(publicUrl(this._baseUrl, [this._projectId, modelId, 'config']))\n }\n\n /**\n * Resolves with the server's verdict for 2xx responses — including\n * `{ success: false, errors }` for validation failures, which are not\n * exceptions. Rejects with `ContentrainError` on 403/404/429/5xx.\n */\n submit(modelId: string, data: Record<string, unknown>, options?: FormSubmitOptions): Promise<FormSubmitResult> {\n const body: { data: Record<string, unknown>; captchaToken?: string; _hp?: string } = { data }\n if (options?.captchaToken) body.captchaToken = options.captchaToken\n if (options?.honeypot !== undefined) body._hp = options.honeypot\n return publicPost<FormSubmitResult>(publicUrl(this._baseUrl, [this._projectId, modelId, 'submit']), body)\n }\n}\n","// Public comments client — the browser side of Studio's `/api/comments/v1`.\n//\n// Contract (Studio docs/COMMENTS.md):\n// GET {base}/{projectId}/{modelId}/{entryId}?locale&page&limit&sort → CommentThread\n// POST {base}/{projectId}/{modelId}/{entryId}?locale\n// { author: { name, email?, url? }, body, parentId?, captchaToken?, _hp? } → CommentSubmitResult\n//\n// Only approved comments come back, nested under their roots; email, IP,\n// user agent and referrer never leave the server. `body` is plain text —\n// render it escaped. No credential is sent: the endpoints are public.\n\nimport { publicGet, publicPost, publicUrl } from './public-request.js'\n\nexport type CommentType = 'comment' | 'pingback' | 'trackback'\n\nexport interface CommentAuthor {\n name: string\n url: string | null\n /** Written from Studio by a workspace member. */\n isModerator: boolean\n}\n\nexport interface PublicComment {\n id: string\n parentId: string | null\n depth: number\n author: CommentAuthor\n /** Plain text. */\n body: string\n type: CommentType\n /** ISO 8601. */\n createdAt: string\n replies: PublicComment[]\n}\n\nexport interface CommentThreadConfig {\n /** Thread closed → render the comments, hide the form. */\n closed: boolean\n requireApproval: boolean\n requireEmail: boolean\n /** Reply nesting cap for new submissions (0 = flat). */\n maxDepth: number\n maxBodyLength: number\n captcha: 'turnstile' | null\n captchaSiteKey: string | null\n honeypotField: string | null\n}\n\nexport interface CommentThread {\n entry: { modelId: string; entryId: string; locale: string }\n config: CommentThreadConfig\n /** Root comments of this page, replies nested. */\n comments: PublicComment[]\n /** Root comments in total. */\n total: number\n page: number\n limit: number\n}\n\nexport interface CommentThreadQuery {\n locale?: string\n page?: number\n limit?: number\n sort?: 'oldest' | 'newest'\n}\n\nexport interface CommentSubmission {\n author: { name: string; email?: string; url?: string }\n body: string\n /** Reply target — an approved comment's id; omitted or null for a root comment. */\n parentId?: string | null\n captchaToken?: string\n /** Value of the honeypot input (`config.honeypotField`); a human leaves it empty. */\n honeypot?: string\n}\n\nexport interface CommentFieldError {\n /** `author.name` · `author.email` · `author.url` · `body` · `parentId` · `captcha` */\n field: string\n message: string\n}\n\nexport interface CommentSubmitResult {\n success: boolean\n /** `approved` renders now; `pending` is only echoed back to its author. */\n status?: 'pending' | 'approved'\n /** The stored comment, in the public shape. Absent when the honeypot swallowed the post. */\n comment?: PublicComment\n errors?: CommentFieldError[]\n}\n\nexport interface CommentsClientConfig {\n /** Public API root — `https://studio.contentrain.io/api/comments/v1`. */\n baseUrl: string\n projectId: string\n}\n\nexport class CommentsClient {\n private _baseUrl: string\n private _projectId: string\n\n constructor(config: CommentsClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n }\n\n thread(modelId: string, entryId: string, query?: CommentThreadQuery): Promise<CommentThread> {\n const url = publicUrl(this._baseUrl, [this._projectId, modelId, entryId], {\n locale: query?.locale,\n page: query?.page,\n limit: query?.limit,\n sort: query?.sort,\n })\n return publicGet<CommentThread>(url)\n }\n\n /**\n * Resolves with the server's verdict for 2xx responses — including\n * `{ success: false, errors }`. Rejects with `ContentrainError` on\n * 403 (thread closed / plan), 404, 429 and 5xx.\n */\n submit(\n modelId: string,\n entryId: string,\n submission: CommentSubmission,\n options?: { locale?: string },\n ): Promise<CommentSubmitResult> {\n const url = publicUrl(this._baseUrl, [this._projectId, modelId, entryId], { locale: options?.locale })\n // `parentId: null` is a root comment — sent explicitly, as Studio's own fixture does.\n const body: Record<string, unknown> = { author: submission.author, body: submission.body, parentId: submission.parentId ?? null }\n if (submission.captchaToken) body.captchaToken = submission.captchaToken\n if (submission.honeypot !== undefined) body._hp = submission.honeypot\n return publicPost<CommentSubmitResult>(url, body)\n }\n}\n","import { ContentrainError } from './errors.js'\n\nexport interface ConversationContext {\n activeModelId?: string | null\n activeLocale?: string\n activeEntryId?: string | null\n panelState?: string\n activeBranch?: string | null\n}\n\nexport interface ConversationSendOptions {\n conversationId?: string\n context?: ConversationContext\n}\n\nexport interface ConversationToolResult {\n id: string\n name: string\n result: unknown\n}\n\nexport interface ConversationUsage {\n inputTokens: number\n outputTokens: number\n}\n\nexport interface ConversationResponse {\n conversationId: string\n message: string\n toolResults?: ConversationToolResult[]\n usage: ConversationUsage\n}\n\nexport interface ConversationMessage {\n id: string\n role: 'user' | 'assistant'\n content: string | unknown[]\n toolCalls?: unknown[]\n model?: string\n usage?: ConversationUsage\n createdAt: string\n}\n\nexport interface ConversationHistory {\n conversationId: string\n messages: ConversationMessage[]\n}\n\nexport interface ConversationClientConfig {\n baseUrl: string\n projectId: string\n apiKey: string\n}\n\nexport class ConversationClient {\n private _baseUrl: string\n private _projectId: string\n private _apiKey: string\n\n constructor(config: ConversationClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n this._apiKey = config.apiKey\n }\n\n async send(message: string, options?: ConversationSendOptions): Promise<ConversationResponse> {\n const url = `${this._baseUrl}/${this._projectId}/message`\n\n const body: Record<string, unknown> = { message }\n if (options?.conversationId) body.conversationId = options.conversationId\n if (options?.context) body.context = options.context\n\n const res = await globalThis.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this._apiKey}`,\n },\n body: JSON.stringify(body),\n })\n\n if (!res.ok) {\n throw new ContentrainError(res.status, await res.text())\n }\n\n return (await res.json()) as ConversationResponse\n }\n\n async history(conversationId: string, options?: { limit?: number }): Promise<ConversationHistory> {\n const params = new URLSearchParams({ conversationId })\n if (options?.limit) params.set('limit', String(options.limit))\n\n const url = `${this._baseUrl}/${this._projectId}/history?${params}`\n\n const res = await globalThis.fetch(url, {\n headers: {\n 'Authorization': `Bearer ${this._apiKey}`,\n },\n })\n\n if (!res.ok) {\n throw new ContentrainError(res.status, await res.text())\n }\n\n return (await res.json()) as ConversationHistory\n }\n}\n","import { HttpTransport } from './http-transport.js'\nimport { CdnCollectionQuery } from './collection-query.js'\nimport { CdnSingletonAccessor } from './singleton-accessor.js'\nimport { CdnDictionaryAccessor } from './dictionary-accessor.js'\nimport { CdnDocumentQuery } from './document-query.js'\nimport { MediaAccessor } from './media-accessor.js'\nimport { FormsClient } from './forms-client.js'\nimport { CommentsClient } from './comments-client.js'\nimport { ConversationClient } from './conversation-client.js'\n\nexport interface ContentrainCDNConfig {\n projectId: string\n apiKey: string\n baseUrl?: string\n defaultLocale?: string\n /** Bundle preload mode. `true` → `{ revalidateMs: 60_000 }` */\n bundle?: boolean | { revalidateMs?: number }\n}\n\nexport type ContentrainCDNClient = ReturnType<typeof createContentrain>\n\nexport function createContentrain(config: ContentrainCDNConfig) {\n const transport = new HttpTransport({\n baseUrl: config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1',\n projectId: config.projectId,\n apiKey: config.apiKey,\n bundle: config.bundle,\n defaultLocale: config.defaultLocale,\n })\n const defaultLocale = config.defaultLocale\n\n return {\n collection: <T extends object = Record<string, unknown>>(modelId: string) =>\n new CdnCollectionQuery<T>(transport, modelId, defaultLocale),\n\n singleton: <T extends Record<string, unknown> = Record<string, unknown>>(modelId: string) =>\n new CdnSingletonAccessor<T>(transport.singleton<T>(modelId), defaultLocale),\n\n dictionary: (modelId: string) =>\n new CdnDictionaryAccessor(transport.dictionary(modelId), defaultLocale),\n\n document: <T extends object = Record<string, unknown>>(modelId: string) =>\n new CdnDocumentQuery<T>(transport.document<T>(modelId), defaultLocale),\n\n media: () => new MediaAccessor(transport),\n\n // Public embed surfaces: no API key travels with them — a visitor's\n // browser cannot keep a secret, and the endpoints are unauthenticated by design.\n form: () => new FormsClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/forms/v1'),\n projectId: config.projectId,\n }),\n\n comments: () => new CommentsClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/comments/v1'),\n projectId: config.projectId,\n }),\n\n conversation: () => new ConversationClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/conversation/v1'),\n projectId: config.projectId,\n apiKey: config.apiKey,\n }),\n\n manifest: () => transport.fetch<unknown>('_manifest.json'),\n models: () => transport.fetch<unknown[]>('models/_index.json'),\n model: (id: string) => transport.fetch<unknown>(`models/${id}.json`),\n\n preload: (locale?: string) => transport.preload(locale),\n }\n}\n\n// Re-exports\nexport { ContentrainError, isPaymentRequired } from './errors.js'\nexport type { CollectionDataSource, SingletonDataSource, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry } from './data-source.js'\nexport { HttpTransport } from './http-transport.js'\nexport type { TransportConfig } from './http-transport.js'\nexport { CdnCollectionQuery } from './collection-query.js'\nexport { CdnSingletonAccessor } from './singleton-accessor.js'\nexport { CdnDictionaryAccessor } from './dictionary-accessor.js'\nexport { CdnDocumentQuery } from './document-query.js'\nexport { MediaAccessor } from './media-accessor.js'\nexport type { MediaAsset, MediaAssetMeta, MediaManifest } from './media-accessor.js'\nexport { FormsClient } from './forms-client.js'\nexport type {\n FormConfig,\n FormFieldConfig,\n FormFieldError,\n FormSubmitOptions,\n FormSubmitResult,\n FormsClientConfig,\n} from './forms-client.js'\nexport { CommentsClient } from './comments-client.js'\nexport type {\n CommentAuthor,\n CommentFieldError,\n CommentSubmission,\n CommentSubmitResult,\n CommentThread,\n CommentThreadConfig,\n CommentThreadQuery,\n CommentType,\n CommentsClientConfig,\n PublicComment,\n} from './comments-client.js'\nexport { ConversationClient } from './conversation-client.js'\nexport type {\n ConversationClientConfig,\n ConversationContext,\n ConversationSendOptions,\n ConversationResponse,\n ConversationToolResult,\n ConversationUsage,\n ConversationMessage,\n ConversationHistory,\n} from './conversation-client.js'\n"],"mappings":"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"}
|
|
@@ -23,12 +23,32 @@ function applyWhere(item, clause) {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region src/cdn/errors.ts
|
|
25
25
|
var ContentrainError = class extends Error {
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* The API's machine code, when the error body carries one (`data.code`,
|
|
28
|
+
* e.g. `payment_required`). Branch on it or on `status`, never on the
|
|
29
|
+
* message: that is display text, and some is written for the workspace
|
|
30
|
+
* owner rather than a visitor.
|
|
31
|
+
*/
|
|
32
|
+
code;
|
|
33
|
+
constructor(status, message, code) {
|
|
27
34
|
super(message);
|
|
28
35
|
this.status = status;
|
|
29
36
|
this.name = "ContentrainError";
|
|
37
|
+
if (code) this.code = code;
|
|
30
38
|
}
|
|
31
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* The workspace's subscription is inactive: Studio answers `402` with
|
|
42
|
+
* `data.code: 'payment_required'` on the public forms and comments endpoints
|
|
43
|
+
* while billing is locked. Not transient — no retry helps until the owner
|
|
44
|
+
* updates billing — and its message addresses the owner, so a site hides the
|
|
45
|
+
* form or thread instead of showing it to a visitor.
|
|
46
|
+
*/
|
|
47
|
+
function isPaymentRequired(error) {
|
|
48
|
+
if (!error || typeof error !== "object") return false;
|
|
49
|
+
const e = error;
|
|
50
|
+
return e.name === "ContentrainError" && (e.status === 402 || e.code === "payment_required");
|
|
51
|
+
}
|
|
32
52
|
//#endregion
|
|
33
53
|
//#region src/cdn/http-transport.ts
|
|
34
54
|
/** Paths eligible for bundle serving — everything else (manifests, models/*) has no locale segment. */
|
|
@@ -429,18 +449,22 @@ var MediaAccessor = class {
|
|
|
429
449
|
};
|
|
430
450
|
//#endregion
|
|
431
451
|
//#region src/cdn/public-request.ts
|
|
432
|
-
|
|
452
|
+
/** The h3 error body's message and machine code (`data.code`), or the raw text. */
|
|
453
|
+
async function errorOf(res, fallback) {
|
|
433
454
|
const text = await res.text().catch(() => "");
|
|
455
|
+
let message = text || fallback;
|
|
456
|
+
let code;
|
|
434
457
|
try {
|
|
435
458
|
const parsed = JSON.parse(text);
|
|
436
|
-
const
|
|
437
|
-
if (typeof
|
|
459
|
+
const m = parsed.message ?? parsed.statusMessage;
|
|
460
|
+
if (typeof m === "string" && m) message = m;
|
|
461
|
+
if (typeof parsed.data?.code === "string") code = parsed.data.code;
|
|
438
462
|
} catch {}
|
|
439
|
-
return
|
|
463
|
+
return new ContentrainError(res.status, message, code);
|
|
440
464
|
}
|
|
441
465
|
async function publicGet(url) {
|
|
442
466
|
const res = await globalThis.fetch(url);
|
|
443
|
-
if (!res.ok) throw
|
|
467
|
+
if (!res.ok) throw await errorOf(res, "Request failed");
|
|
444
468
|
return await res.json();
|
|
445
469
|
}
|
|
446
470
|
async function publicPost(url, body) {
|
|
@@ -449,7 +473,7 @@ async function publicPost(url, body) {
|
|
|
449
473
|
headers: { "Content-Type": "application/json" },
|
|
450
474
|
body: JSON.stringify(body)
|
|
451
475
|
});
|
|
452
|
-
if (!res.ok) throw
|
|
476
|
+
if (!res.ok) throw await errorOf(res, "Request failed");
|
|
453
477
|
return await res.json();
|
|
454
478
|
}
|
|
455
479
|
/** `baseUrl` without a trailing slash, path segments URL-encoded. */
|
|
@@ -679,3 +703,9 @@ Object.defineProperty(exports, "createContentrain", {
|
|
|
679
703
|
return createContentrain;
|
|
680
704
|
}
|
|
681
705
|
});
|
|
706
|
+
Object.defineProperty(exports, "isPaymentRequired", {
|
|
707
|
+
enumerable: true,
|
|
708
|
+
get: function() {
|
|
709
|
+
return isPaymentRequired;
|
|
710
|
+
}
|
|
711
|
+
});
|
|
@@ -403,8 +403,23 @@ declare class ConversationClient {
|
|
|
403
403
|
//#region src/cdn/errors.d.ts
|
|
404
404
|
declare class ContentrainError extends Error {
|
|
405
405
|
status: number;
|
|
406
|
-
|
|
406
|
+
/**
|
|
407
|
+
* The API's machine code, when the error body carries one (`data.code`,
|
|
408
|
+
* e.g. `payment_required`). Branch on it or on `status`, never on the
|
|
409
|
+
* message: that is display text, and some is written for the workspace
|
|
410
|
+
* owner rather than a visitor.
|
|
411
|
+
*/
|
|
412
|
+
code?: string;
|
|
413
|
+
constructor(status: number, message: string, code?: string);
|
|
407
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* The workspace's subscription is inactive: Studio answers `402` with
|
|
417
|
+
* `data.code: 'payment_required'` on the public forms and comments endpoints
|
|
418
|
+
* while billing is locked. Not transient — no retry helps until the owner
|
|
419
|
+
* updates billing — and its message addresses the owner, so a site hides the
|
|
420
|
+
* form or thread instead of showing it to a visitor.
|
|
421
|
+
*/
|
|
422
|
+
declare function isPaymentRequired(error: unknown): boolean;
|
|
408
423
|
//#endregion
|
|
409
424
|
//#region src/cdn/index.d.ts
|
|
410
425
|
interface ContentrainCDNConfig {
|
|
@@ -433,5 +448,5 @@ declare function createContentrain(config: ContentrainCDNConfig): {
|
|
|
433
448
|
preload: (locale?: string) => Promise<boolean>;
|
|
434
449
|
};
|
|
435
450
|
//#endregion
|
|
436
|
-
export {
|
|
437
|
-
//# sourceMappingURL=index-
|
|
451
|
+
export { FormSubmitResult as A, CdnCollectionQuery as B, CommentsClient as C, FormFieldConfig as D, FormConfig as E, MediaAssetMeta as F, HttpTransport as G, WhereClause as H, MediaManifest as I, DictionaryDataSource as J, TransportConfig as K, CdnDocumentQuery as L, FormsClientConfig as M, MediaAccessor as N, FormFieldError as O, MediaAsset as P, CdnDictionaryAccessor as R, CommentType as S, PublicComment as T, WhereOp as U, EntryMeta as V, applyWhere as W, DocumentIndexEntry as X, DocumentDataSource as Y, SingletonDataSource as Z, CommentSubmission as _, isPaymentRequired as a, CommentThreadConfig as b, ConversationContext as c, ConversationResponse as d, ConversationSendOptions as f, CommentFieldError as g, CommentAuthor as h, ContentrainError as i, FormsClient as j, FormSubmitOptions as k, ConversationHistory as l, ConversationUsage as m, ContentrainCDNConfig as n, ConversationClient as o, ConversationToolResult as p, CollectionDataSource as q, createContentrain as r, ConversationClientConfig as s, ContentrainCDNClient as t, ConversationMessage as u, CommentSubmitResult as v, CommentsClientConfig as w, CommentThreadQuery as x, CommentThread as y, CdnSingletonAccessor as z };
|
|
452
|
+
//# sourceMappingURL=index-CqmcazRu.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-CqmcazRu.d.mts","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/comments-client.ts","../src/cdn/conversation-client.ts","../src/cdn/errors.ts","../src/cdn/index.ts"],"mappings":"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"}
|
|
@@ -403,8 +403,23 @@ declare class ConversationClient {
|
|
|
403
403
|
//#region src/cdn/errors.d.ts
|
|
404
404
|
declare class ContentrainError extends Error {
|
|
405
405
|
status: number;
|
|
406
|
-
|
|
406
|
+
/**
|
|
407
|
+
* The API's machine code, when the error body carries one (`data.code`,
|
|
408
|
+
* e.g. `payment_required`). Branch on it or on `status`, never on the
|
|
409
|
+
* message: that is display text, and some is written for the workspace
|
|
410
|
+
* owner rather than a visitor.
|
|
411
|
+
*/
|
|
412
|
+
code?: string;
|
|
413
|
+
constructor(status: number, message: string, code?: string);
|
|
407
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* The workspace's subscription is inactive: Studio answers `402` with
|
|
417
|
+
* `data.code: 'payment_required'` on the public forms and comments endpoints
|
|
418
|
+
* while billing is locked. Not transient — no retry helps until the owner
|
|
419
|
+
* updates billing — and its message addresses the owner, so a site hides the
|
|
420
|
+
* form or thread instead of showing it to a visitor.
|
|
421
|
+
*/
|
|
422
|
+
declare function isPaymentRequired(error: unknown): boolean;
|
|
408
423
|
//#endregion
|
|
409
424
|
//#region src/cdn/index.d.ts
|
|
410
425
|
interface ContentrainCDNConfig {
|
|
@@ -433,5 +448,5 @@ declare function createContentrain(config: ContentrainCDNConfig): {
|
|
|
433
448
|
preload: (locale?: string) => Promise<boolean>;
|
|
434
449
|
};
|
|
435
450
|
//#endregion
|
|
436
|
-
export {
|
|
437
|
-
//# sourceMappingURL=index-
|
|
451
|
+
export { FormSubmitResult as A, CdnCollectionQuery as B, CommentsClient as C, FormFieldConfig as D, FormConfig as E, MediaAssetMeta as F, HttpTransport as G, WhereClause as H, MediaManifest as I, DictionaryDataSource as J, TransportConfig as K, CdnDocumentQuery as L, FormsClientConfig as M, MediaAccessor as N, FormFieldError as O, MediaAsset as P, CdnDictionaryAccessor as R, CommentType as S, PublicComment as T, WhereOp as U, EntryMeta as V, applyWhere as W, DocumentIndexEntry as X, DocumentDataSource as Y, SingletonDataSource as Z, CommentSubmission as _, isPaymentRequired as a, CommentThreadConfig as b, ConversationContext as c, ConversationResponse as d, ConversationSendOptions as f, CommentFieldError as g, CommentAuthor as h, ContentrainError as i, FormsClient as j, FormSubmitOptions as k, ConversationHistory as l, ConversationUsage as m, ContentrainCDNConfig as n, ConversationClient as o, ConversationToolResult as p, CollectionDataSource as q, createContentrain as r, ConversationClientConfig as s, ContentrainCDNClient as t, ConversationMessage as u, CommentSubmitResult as v, CommentsClientConfig as w, CommentThreadQuery as x, CommentThread as y, CdnSingletonAccessor as z };
|
|
452
|
+
//# sourceMappingURL=index-DZOztXQv.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-DZOztXQv.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/comments-client.ts","../src/cdn/conversation-client.ts","../src/cdn/errors.ts","../src/cdn/index.ts"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_cdn = require("./cdn-
|
|
5
|
+
const require_cdn = require("./cdn-DuTqMqyX.cjs");
|
|
6
6
|
const require_media = require("./media-o6KezVYy.cjs");
|
|
7
7
|
//#region src/runtime/query.ts
|
|
8
8
|
var QueryBuilder = class {
|
|
@@ -404,5 +404,6 @@ exports.applyWhere = require_cdn.applyWhere;
|
|
|
404
404
|
exports.createContentrain = require_cdn.createContentrain;
|
|
405
405
|
exports.createContentrainClient = createContentrainClient;
|
|
406
406
|
exports.default = createContentrainClient;
|
|
407
|
+
exports.isPaymentRequired = require_cdn.isPaymentRequired;
|
|
407
408
|
exports.resolveMediaRefsInBody = require_media.resolveMediaRefsInBody;
|
|
408
409
|
exports.resolveMediaUrl = require_media.resolveMediaUrl;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as FormSubmitResult, C as CommentsClient, D as FormFieldConfig, E as FormConfig, F as MediaAssetMeta, H as WhereClause, I as MediaManifest, M as FormsClientConfig, N as MediaAccessor, O as FormFieldError, P as MediaAsset, T as PublicComment, U as WhereOp, V as EntryMeta, W as applyWhere, X as DocumentIndexEntry, _ as CommentSubmission, a as isPaymentRequired, b as CommentThreadConfig, d as ConversationResponse, g as CommentFieldError, h as CommentAuthor, i as ContentrainError, j as FormsClient, k as FormSubmitOptions, l as ConversationHistory, n as ContentrainCDNConfig, o as ConversationClient, r as createContentrain, s as ConversationClientConfig, t as ContentrainCDNClient, u as ConversationMessage, v as CommentSubmitResult, w as CommentsClientConfig, x as CommentThreadQuery, y as CommentThread } from "./index-DZOztXQv.cjs";
|
|
2
2
|
import { ContentStatus, ContentrainConfig, FieldDef, FieldType, ModelDefinition, ModelKind } from "@contentrain/types";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/query.d.ts
|
|
@@ -129,5 +129,5 @@ declare function createContentrainClient(projectRoot?: string): Promise<{
|
|
|
129
129
|
document: (model: string) => DocumentQuery<Record<string, unknown>>;
|
|
130
130
|
}>;
|
|
131
131
|
//#endregion
|
|
132
|
-
export { type CommentAuthor, type CommentFieldError, type CommentSubmission, type CommentSubmitResult, type CommentThread, type CommentThreadConfig, type CommentThreadQuery, CommentsClient, type CommentsClientConfig, type ContentStatus, type ContentrainCDNClient, type ContentrainCDNConfig, type ContentrainConfig, ContentrainError, ConversationClient, type ConversationClientConfig, type ConversationHistory, type ConversationMessage, type ConversationResponse, DictionaryAccessor, type DocumentIndexEntry, DocumentQuery, type EntryMeta, type FieldDef, type FieldType, type FormConfig, type FormFieldConfig, type FormFieldError, type FormSubmitOptions, type FormSubmitResult, FormsClient, type FormsClientConfig, MediaAccessor, type MediaAsset, type MediaAssetMeta, type MediaManifest, type ModelDefinition, type ModelKind, type PublicComment, QueryBuilder, type RelationMeta, type RelationResolver, SingletonAccessor, type WhereClause, type WhereOp, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, resolveMediaRefsInBody, resolveMediaUrl };
|
|
132
|
+
export { type CommentAuthor, type CommentFieldError, type CommentSubmission, type CommentSubmitResult, type CommentThread, type CommentThreadConfig, type CommentThreadQuery, CommentsClient, type CommentsClientConfig, type ContentStatus, type ContentrainCDNClient, type ContentrainCDNConfig, type ContentrainConfig, ContentrainError, ConversationClient, type ConversationClientConfig, type ConversationHistory, type ConversationMessage, type ConversationResponse, DictionaryAccessor, type DocumentIndexEntry, DocumentQuery, type EntryMeta, type FieldDef, type FieldType, type FormConfig, type FormFieldConfig, type FormFieldError, type FormSubmitOptions, type FormSubmitResult, FormsClient, type FormsClientConfig, MediaAccessor, type MediaAsset, type MediaAssetMeta, type MediaManifest, type ModelDefinition, type ModelKind, type PublicComment, QueryBuilder, type RelationMeta, type RelationResolver, SingletonAccessor, type WhereClause, type WhereOp, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, isPaymentRequired, resolveMediaRefsInBody, resolveMediaUrl };
|
|
133
133
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as FormSubmitResult, C as CommentsClient, D as FormFieldConfig, E as FormConfig, F as MediaAssetMeta, H as WhereClause, I as MediaManifest, M as FormsClientConfig, N as MediaAccessor, O as FormFieldError, P as MediaAsset, T as PublicComment, U as WhereOp, V as EntryMeta, W as applyWhere, X as DocumentIndexEntry, _ as CommentSubmission, a as isPaymentRequired, b as CommentThreadConfig, d as ConversationResponse, g as CommentFieldError, h as CommentAuthor, i as ContentrainError, j as FormsClient, k as FormSubmitOptions, l as ConversationHistory, n as ContentrainCDNConfig, o as ConversationClient, r as createContentrain, s as ConversationClientConfig, t as ContentrainCDNClient, u as ConversationMessage, v as CommentSubmitResult, w as CommentsClientConfig, x as CommentThreadQuery, y as CommentThread } from "./index-CqmcazRu.mjs";
|
|
2
2
|
import { ContentStatus, ContentrainConfig, FieldDef, FieldType, ModelDefinition, ModelKind } from "@contentrain/types";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/query.d.ts
|
|
@@ -129,5 +129,5 @@ declare function createContentrainClient(projectRoot?: string): Promise<{
|
|
|
129
129
|
document: (model: string) => DocumentQuery<Record<string, unknown>>;
|
|
130
130
|
}>;
|
|
131
131
|
//#endregion
|
|
132
|
-
export { type CommentAuthor, type CommentFieldError, type CommentSubmission, type CommentSubmitResult, type CommentThread, type CommentThreadConfig, type CommentThreadQuery, CommentsClient, type CommentsClientConfig, type ContentStatus, type ContentrainCDNClient, type ContentrainCDNConfig, type ContentrainConfig, ContentrainError, ConversationClient, type ConversationClientConfig, type ConversationHistory, type ConversationMessage, type ConversationResponse, DictionaryAccessor, type DocumentIndexEntry, DocumentQuery, type EntryMeta, type FieldDef, type FieldType, type FormConfig, type FormFieldConfig, type FormFieldError, type FormSubmitOptions, type FormSubmitResult, FormsClient, type FormsClientConfig, MediaAccessor, type MediaAsset, type MediaAssetMeta, type MediaManifest, type ModelDefinition, type ModelKind, type PublicComment, QueryBuilder, type RelationMeta, type RelationResolver, SingletonAccessor, type WhereClause, type WhereOp, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, resolveMediaRefsInBody, resolveMediaUrl };
|
|
132
|
+
export { type CommentAuthor, type CommentFieldError, type CommentSubmission, type CommentSubmitResult, type CommentThread, type CommentThreadConfig, type CommentThreadQuery, CommentsClient, type CommentsClientConfig, type ContentStatus, type ContentrainCDNClient, type ContentrainCDNConfig, type ContentrainConfig, ContentrainError, ConversationClient, type ConversationClientConfig, type ConversationHistory, type ConversationMessage, type ConversationResponse, DictionaryAccessor, type DocumentIndexEntry, DocumentQuery, type EntryMeta, type FieldDef, type FieldType, type FormConfig, type FormFieldConfig, type FormFieldError, type FormSubmitOptions, type FormSubmitResult, FormsClient, type FormsClientConfig, MediaAccessor, type MediaAsset, type MediaAssetMeta, type MediaManifest, type ModelDefinition, type ModelKind, type PublicComment, QueryBuilder, type RelationMeta, type RelationResolver, SingletonAccessor, type WhereClause, type WhereOp, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, isPaymentRequired, resolveMediaRefsInBody, resolveMediaUrl };
|
|
133
133
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as MediaAccessor, d as ContentrainError, f as
|
|
1
|
+
import { a as MediaAccessor, d as ContentrainError, f as isPaymentRequired, i as FormsClient, n as ConversationClient, p as applyWhere, r as CommentsClient, t as createContentrain } from "./cdn-DlAwl84z.mjs";
|
|
2
2
|
import { n as resolveMediaUrl, t as resolveMediaRefsInBody } from "./media-HEEDdrFS.mjs";
|
|
3
3
|
//#region src/runtime/query.ts
|
|
4
4
|
var QueryBuilder = class {
|
|
@@ -387,6 +387,6 @@ async function createContentrainClient(projectRoot) {
|
|
|
387
387
|
return await import(pathToFileURL(resolve(projectRoot ?? process.cwd(), ".contentrain", "client", "index.mjs")).href);
|
|
388
388
|
}
|
|
389
389
|
//#endregion
|
|
390
|
-
export { CommentsClient, ContentrainError, ConversationClient, DictionaryAccessor, DocumentQuery, FormsClient, MediaAccessor, QueryBuilder, SingletonAccessor, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, resolveMediaRefsInBody, resolveMediaUrl };
|
|
390
|
+
export { CommentsClient, ContentrainError, ConversationClient, DictionaryAccessor, DocumentQuery, FormsClient, MediaAccessor, QueryBuilder, SingletonAccessor, applyWhere, createContentrain, createContentrainClient, createContentrainClient as default, isPaymentRequired, resolveMediaRefsInBody, resolveMediaUrl };
|
|
391
391
|
|
|
392
392
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/runtime/query.ts","../src/runtime/singleton.ts","../src/runtime/dictionary.ts","../src/runtime/document.ts","../src/index.ts"],"sourcesContent":["import type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport type { WhereOp }\n\nexport interface RelationMeta {\n target: string | string[]\n multi: boolean\n}\n\nexport type RelationResolver = (model: string, id: string, locale: string | null) => Record<string, unknown> | undefined\n\nexport class QueryBuilder<T extends object> {\n private _data: Map<string, T[]>\n private _locale: string | null = null\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _limit: number | null = null\n private _offset = 0\n private _includes: string[] = []\n private _relationMeta: Record<string, RelationMeta>\n private _resolver: RelationResolver | null\n private _defaultLocale: string | null\n\n constructor(\n data: Map<string, T[]>,\n relationMeta?: Record<string, RelationMeta>,\n resolver?: RelationResolver,\n defaultLocale?: string,\n ) {\n this._data = data\n this._relationMeta = relationMeta ?? {}\n this._resolver = resolver ?? null\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where<K extends string & keyof T>(field: K, value: T[K]): this\n where<K extends string & keyof T>(field: K, op: WhereOp, value: unknown): this\n where<K extends string & keyof T>(field: K, opOrValue: WhereOp | T[K], value?: unknown): this {\n if (value !== undefined) {\n this._filters.push({ field, op: opOrValue as WhereOp, value })\n } else {\n this._filters.push({ field, op: 'eq', value: opOrValue })\n }\n return this\n }\n\n sort<K extends string & keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n limit(n: number): this {\n this._limit = n\n return this\n }\n\n offset(n: number): this {\n this._offset = n\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n count(): number {\n return this.all().length\n }\n\n all(): T[] {\n let items = this._resolveData()\n\n // Filter\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n // Sort\n if (this._sortField) {\n const field = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items.sort((a, b) => {\n const va = (a as Record<string, unknown>)[field]\n const vb = (b as Record<string, unknown>)[field]\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n if (va < vb) return -dir\n if (va > vb) return dir\n return 0\n })\n }\n\n // Pagination\n if (this._offset > 0 || this._limit !== null) {\n const end = this._limit !== null ? this._offset + this._limit : undefined\n items = items.slice(this._offset, end)\n }\n\n // Resolve relations (after pagination for efficiency)\n if (this._includes.length > 0 && this._resolver) {\n items = items.map(item => this._resolveIncludes(item))\n }\n\n return items\n }\n\n first(): T | undefined {\n return this.all()[0]\n }\n\n private _resolveData(): T[] {\n if (this._locale) {\n return [...(this._data.get(this._locale) ?? [])]\n }\n if (this._defaultLocale) {\n const defaultData = this._data.get(this._defaultLocale)\n if (defaultData) return [...defaultData]\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return [...(this._data.get(firstKey) ?? [])]\n }\n return []\n }\n\n private _resolveIncludes(item: T): T {\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n }\n }\n return resolved\n }\n\n private _resolveId(targets: string[], id: string): Record<string, unknown> | undefined {\n const loc = this._locale ?? this._defaultLocale\n for (const target of targets) {\n const result = this._resolver!(target, id, loc)\n if (result) return result\n }\n return undefined\n }\n}\n","export class SingletonAccessor<T extends Record<string, unknown>> {\n private _data: Map<string, T>\n private _locale: string | null = null\n private _defaultLocale: string | null\n private _includes: string[] = []\n private _relationMeta: Record<string, { target: string | string[]; multi: boolean }> = {}\n private _resolveEntry?: (model: string, id: string, locale: string) => unknown\n\n constructor(\n data: Map<string, T>,\n defaultLocale?: string,\n relationMeta?: Record<string, { target: string | string[]; multi: boolean }>,\n resolveEntry?: (model: string, id: string, locale: string) => unknown,\n ) {\n this._data = data\n this._defaultLocale = defaultLocale ?? null\n if (relationMeta) this._relationMeta = relationMeta\n this._resolveEntry = resolveEntry\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n get(): T {\n if (this._locale) {\n const d = this._data.get(this._locale)\n if (!d) throw new Error(`No data for locale \"${this._locale}\"`)\n if (this._includes.length > 0) return this._resolveIncludes(d, this._locale)\n return d\n }\n\n const locale = this._defaultLocale ?? undefined\n let data: T | undefined\n\n if (locale) {\n data = this._data.get(locale)\n }\n if (!data) {\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n data = this._data.get(firstKey)\n }\n }\n if (!data) throw new Error('No data available')\n\n if (this._includes.length > 0) {\n return this._resolveIncludes(data, locale ?? 'en')\n }\n return data\n }\n\n private _resolveIncludes(item: T, locale: string): T {\n if (!this._resolveEntry || this._includes.length === 0) return item\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id, locale) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref, locale) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id, locale) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref, locale) ?? id\n }\n }\n }\n\n return resolved\n }\n\n private _resolveId(targets: string[], id: string, locale: string): unknown {\n if (!this._resolveEntry) return undefined\n for (const model of targets) {\n const result = this._resolveEntry(model, id, locale)\n if (result) return result\n }\n return undefined\n }\n}\n","export class DictionaryAccessor {\n private _data: Map<string, Record<string, string>>\n private _locale: string | null = null\n private _defaultLocale: string | null\n\n constructor(data: Map<string, Record<string, string>>, defaultLocale?: string) {\n this._data = data\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n get(): Record<string, string>\n get(key: string): string | undefined\n get(key: string, params: Record<string, string | number>): string\n get(key?: string, params?: Record<string, string | number>): Record<string, string> | string | undefined {\n const dict = this._resolveData()\n if (key === undefined) return dict\n const value = dict[key]\n if (value === undefined) return undefined\n if (params) return interpolate(value, params)\n return value\n }\n\n private _resolveData(): Record<string, string> {\n if (this._locale) {\n return this._data.get(this._locale) ?? {}\n }\n if (this._defaultLocale) {\n const d = this._data.get(this._defaultLocale)\n if (d) return d\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return this._data.get(firstKey) ?? {}\n }\n return {}\n }\n}\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const val = params[key]\n return val !== undefined ? String(val) : match\n })\n}\n","import type { RelationMeta, RelationResolver } from './query.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport class DocumentQuery<T extends object> {\n private _data: Map<string, T[]>\n private _locale: string | null = null\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _includes: string[] = []\n private _relationMeta: Record<string, RelationMeta>\n private _resolver: RelationResolver | null\n private _defaultLocale: string | null\n\n constructor(\n data: Map<string, T[]>,\n relationMeta?: Record<string, RelationMeta>,\n resolver?: RelationResolver,\n defaultLocale?: string,\n ) {\n this._data = data\n this._relationMeta = relationMeta ?? {}\n this._resolver = resolver ?? null\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where<K extends string & keyof T>(field: K, value: T[K]): this\n where<K extends string & keyof T>(field: K, op: WhereOp, value: unknown): this\n where<K extends string & keyof T>(field: K, opOrValue: WhereOp | T[K], value?: unknown): this {\n if (value !== undefined) {\n this._filters.push({ field, op: opOrValue as WhereOp, value })\n } else {\n this._filters.push({ field, op: 'eq', value: opOrValue })\n }\n return this\n }\n\n sort<K extends string & keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n bySlug(slug: string): T | undefined {\n const items = this._resolveData()\n const item = items.find(i => (i as Record<string, unknown>)['slug'] === slug)\n if (item && this._includes.length > 0 && this._resolver) {\n return this._resolveIncludes(item)\n }\n return item\n }\n\n count(): number {\n return this.all().length\n }\n\n all(): T[] {\n let items = this._resolveData()\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n if (this._sortField) {\n const sf = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[sf] as number | string | null | undefined\n const vb = (b as Record<string, unknown>)[sf] as number | string | null | undefined\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n return va < vb ? -dir : va > vb ? dir : 0\n })\n }\n if (this._includes.length > 0 && this._resolver) {\n items = items.map(item => this._resolveIncludes(item))\n }\n return items\n }\n\n first(): T | undefined {\n return this.all()[0]\n }\n\n private _resolveData(): T[] {\n if (this._locale) {\n return [...(this._data.get(this._locale) ?? [])]\n }\n if (this._defaultLocale) {\n const defaultData = this._data.get(this._defaultLocale)\n if (defaultData) return [...defaultData]\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return [...(this._data.get(firstKey) ?? [])]\n }\n return []\n }\n\n private _resolveIncludes(item: T): T {\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n }\n }\n return resolved\n }\n\n private _resolveId(targets: string[], id: string): Record<string, unknown> | undefined {\n const loc = this._locale ?? this._defaultLocale\n for (const target of targets) {\n const result = this._resolver!(target, id, loc)\n if (result) return result\n }\n return undefined\n }\n}\n","// Runtime exports — used by framework SDK authors and generated client\nexport { QueryBuilder } from './runtime/query.js'\nexport type { RelationMeta, RelationResolver, WhereOp } from './runtime/query.js'\nexport { SingletonAccessor } from './runtime/singleton.js'\nexport { DictionaryAccessor } from './runtime/dictionary.js'\nexport { DocumentQuery } from './runtime/document.js'\n\n// Shared utilities\nexport type { WhereClause } from './shared/where.js'\nexport { applyWhere } from './shared/where.js'\nexport { resolveMediaUrl, resolveMediaRefsInBody } from './shared/media.js'\n\n// Re-export types from @contentrain/types that SDK consumers need\nexport type {\n FieldType,\n ModelKind,\n ContentStatus,\n FieldDef,\n ModelDefinition,\n ContentrainConfig,\n} from '@contentrain/types'\n\n/**\n * Factory for framework SDK authors.\n * Returns the generated client module loaded from .contentrain/client/.\n *\n * Usage (Nuxt composable):\n * ```ts\n * import { createContentrainClient } from '@contentrain/query'\n * const client = createContentrainClient()\n * const posts = client.query('blog-post').locale('en').all()\n * ```\n */\nexport async function createContentrainClient(\n projectRoot?: string,\n): Promise<{\n query: (model: string) => import('./runtime/query.js').QueryBuilder<Record<string, unknown>>\n singleton: (model: string) => import('./runtime/singleton.js').SingletonAccessor<Record<string, unknown>>\n dictionary: (model: string) => import('./runtime/dictionary.js').DictionaryAccessor\n document: (model: string) => import('./runtime/document.js').DocumentQuery<Record<string, unknown>>\n}> {\n const { resolve } = await import('node:path')\n const { pathToFileURL } = await import('node:url')\n const root = projectRoot ?? process.cwd()\n const clientPath = resolve(root, '.contentrain', 'client', 'index.mjs')\n const client = await import(pathToFileURL(clientPath).href)\n return client\n}\n\n// CDN client factory — async, HTTP-based\nexport { createContentrain } from './cdn/index.js'\nexport type { ContentrainCDNConfig, ContentrainCDNClient } from './cdn/index.js'\nexport type { DocumentIndexEntry } from './cdn/data-source.js'\nexport { ContentrainError } from './cdn/errors.js'\n\n// CDN module re-exports — media, forms, comments, metadata\nexport { MediaAccessor } from './cdn/media-accessor.js'\nexport type { MediaAsset, MediaAssetMeta, MediaManifest } from './cdn/media-accessor.js'\nexport { FormsClient } from './cdn/forms-client.js'\nexport type { FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClientConfig } from './cdn/forms-client.js'\nexport { CommentsClient } from './cdn/comments-client.js'\nexport type {\n CommentAuthor,\n CommentFieldError,\n CommentSubmission,\n CommentSubmitResult,\n CommentThread,\n CommentThreadConfig,\n CommentThreadQuery,\n CommentsClientConfig,\n PublicComment,\n} from './cdn/comments-client.js'\nexport type { EntryMeta } from './cdn/collection-query.js'\nexport { ConversationClient } from './cdn/conversation-client.js'\nexport type {\n ConversationClientConfig,\n ConversationResponse,\n ConversationMessage,\n ConversationHistory,\n} from './cdn/conversation-client.js'\n\n// Sync factory for CJS — requires generated client to be pre-loaded\nexport { createContentrainClient as default }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/runtime/query.ts","../src/runtime/singleton.ts","../src/runtime/dictionary.ts","../src/runtime/document.ts","../src/index.ts"],"sourcesContent":["import type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport type { WhereOp }\n\nexport interface RelationMeta {\n target: string | string[]\n multi: boolean\n}\n\nexport type RelationResolver = (model: string, id: string, locale: string | null) => Record<string, unknown> | undefined\n\nexport class QueryBuilder<T extends object> {\n private _data: Map<string, T[]>\n private _locale: string | null = null\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _limit: number | null = null\n private _offset = 0\n private _includes: string[] = []\n private _relationMeta: Record<string, RelationMeta>\n private _resolver: RelationResolver | null\n private _defaultLocale: string | null\n\n constructor(\n data: Map<string, T[]>,\n relationMeta?: Record<string, RelationMeta>,\n resolver?: RelationResolver,\n defaultLocale?: string,\n ) {\n this._data = data\n this._relationMeta = relationMeta ?? {}\n this._resolver = resolver ?? null\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where<K extends string & keyof T>(field: K, value: T[K]): this\n where<K extends string & keyof T>(field: K, op: WhereOp, value: unknown): this\n where<K extends string & keyof T>(field: K, opOrValue: WhereOp | T[K], value?: unknown): this {\n if (value !== undefined) {\n this._filters.push({ field, op: opOrValue as WhereOp, value })\n } else {\n this._filters.push({ field, op: 'eq', value: opOrValue })\n }\n return this\n }\n\n sort<K extends string & keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n limit(n: number): this {\n this._limit = n\n return this\n }\n\n offset(n: number): this {\n this._offset = n\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n count(): number {\n return this.all().length\n }\n\n all(): T[] {\n let items = this._resolveData()\n\n // Filter\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n // Sort\n if (this._sortField) {\n const field = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items.sort((a, b) => {\n const va = (a as Record<string, unknown>)[field]\n const vb = (b as Record<string, unknown>)[field]\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n if (va < vb) return -dir\n if (va > vb) return dir\n return 0\n })\n }\n\n // Pagination\n if (this._offset > 0 || this._limit !== null) {\n const end = this._limit !== null ? this._offset + this._limit : undefined\n items = items.slice(this._offset, end)\n }\n\n // Resolve relations (after pagination for efficiency)\n if (this._includes.length > 0 && this._resolver) {\n items = items.map(item => this._resolveIncludes(item))\n }\n\n return items\n }\n\n first(): T | undefined {\n return this.all()[0]\n }\n\n private _resolveData(): T[] {\n if (this._locale) {\n return [...(this._data.get(this._locale) ?? [])]\n }\n if (this._defaultLocale) {\n const defaultData = this._data.get(this._defaultLocale)\n if (defaultData) return [...defaultData]\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return [...(this._data.get(firstKey) ?? [])]\n }\n return []\n }\n\n private _resolveIncludes(item: T): T {\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n }\n }\n return resolved\n }\n\n private _resolveId(targets: string[], id: string): Record<string, unknown> | undefined {\n const loc = this._locale ?? this._defaultLocale\n for (const target of targets) {\n const result = this._resolver!(target, id, loc)\n if (result) return result\n }\n return undefined\n }\n}\n","export class SingletonAccessor<T extends Record<string, unknown>> {\n private _data: Map<string, T>\n private _locale: string | null = null\n private _defaultLocale: string | null\n private _includes: string[] = []\n private _relationMeta: Record<string, { target: string | string[]; multi: boolean }> = {}\n private _resolveEntry?: (model: string, id: string, locale: string) => unknown\n\n constructor(\n data: Map<string, T>,\n defaultLocale?: string,\n relationMeta?: Record<string, { target: string | string[]; multi: boolean }>,\n resolveEntry?: (model: string, id: string, locale: string) => unknown,\n ) {\n this._data = data\n this._defaultLocale = defaultLocale ?? null\n if (relationMeta) this._relationMeta = relationMeta\n this._resolveEntry = resolveEntry\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n get(): T {\n if (this._locale) {\n const d = this._data.get(this._locale)\n if (!d) throw new Error(`No data for locale \"${this._locale}\"`)\n if (this._includes.length > 0) return this._resolveIncludes(d, this._locale)\n return d\n }\n\n const locale = this._defaultLocale ?? undefined\n let data: T | undefined\n\n if (locale) {\n data = this._data.get(locale)\n }\n if (!data) {\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n data = this._data.get(firstKey)\n }\n }\n if (!data) throw new Error('No data available')\n\n if (this._includes.length > 0) {\n return this._resolveIncludes(data, locale ?? 'en')\n }\n return data\n }\n\n private _resolveIncludes(item: T, locale: string): T {\n if (!this._resolveEntry || this._includes.length === 0) return item\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id, locale) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref, locale) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id, locale) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref, locale) ?? id\n }\n }\n }\n\n return resolved\n }\n\n private _resolveId(targets: string[], id: string, locale: string): unknown {\n if (!this._resolveEntry) return undefined\n for (const model of targets) {\n const result = this._resolveEntry(model, id, locale)\n if (result) return result\n }\n return undefined\n }\n}\n","export class DictionaryAccessor {\n private _data: Map<string, Record<string, string>>\n private _locale: string | null = null\n private _defaultLocale: string | null\n\n constructor(data: Map<string, Record<string, string>>, defaultLocale?: string) {\n this._data = data\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n get(): Record<string, string>\n get(key: string): string | undefined\n get(key: string, params: Record<string, string | number>): string\n get(key?: string, params?: Record<string, string | number>): Record<string, string> | string | undefined {\n const dict = this._resolveData()\n if (key === undefined) return dict\n const value = dict[key]\n if (value === undefined) return undefined\n if (params) return interpolate(value, params)\n return value\n }\n\n private _resolveData(): Record<string, string> {\n if (this._locale) {\n return this._data.get(this._locale) ?? {}\n }\n if (this._defaultLocale) {\n const d = this._data.get(this._defaultLocale)\n if (d) return d\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return this._data.get(firstKey) ?? {}\n }\n return {}\n }\n}\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const val = params[key]\n return val !== undefined ? String(val) : match\n })\n}\n","import type { RelationMeta, RelationResolver } from './query.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport class DocumentQuery<T extends object> {\n private _data: Map<string, T[]>\n private _locale: string | null = null\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _includes: string[] = []\n private _relationMeta: Record<string, RelationMeta>\n private _resolver: RelationResolver | null\n private _defaultLocale: string | null\n\n constructor(\n data: Map<string, T[]>,\n relationMeta?: Record<string, RelationMeta>,\n resolver?: RelationResolver,\n defaultLocale?: string,\n ) {\n this._data = data\n this._relationMeta = relationMeta ?? {}\n this._resolver = resolver ?? null\n this._defaultLocale = defaultLocale ?? null\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where<K extends string & keyof T>(field: K, value: T[K]): this\n where<K extends string & keyof T>(field: K, op: WhereOp, value: unknown): this\n where<K extends string & keyof T>(field: K, opOrValue: WhereOp | T[K], value?: unknown): this {\n if (value !== undefined) {\n this._filters.push({ field, op: opOrValue as WhereOp, value })\n } else {\n this._filters.push({ field, op: 'eq', value: opOrValue })\n }\n return this\n }\n\n sort<K extends string & keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n bySlug(slug: string): T | undefined {\n const items = this._resolveData()\n const item = items.find(i => (i as Record<string, unknown>)['slug'] === slug)\n if (item && this._includes.length > 0 && this._resolver) {\n return this._resolveIncludes(item)\n }\n return item\n }\n\n count(): number {\n return this.all().length\n }\n\n all(): T[] {\n let items = this._resolveData()\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n if (this._sortField) {\n const sf = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[sf] as number | string | null | undefined\n const vb = (b as Record<string, unknown>)[sf] as number | string | null | undefined\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n return va < vb ? -dir : va > vb ? dir : 0\n })\n }\n if (this._includes.length > 0 && this._resolver) {\n items = items.map(item => this._resolveIncludes(item))\n }\n return items\n }\n\n first(): T | undefined {\n return this.all()[0]\n }\n\n private _resolveData(): T[] {\n if (this._locale) {\n return [...(this._data.get(this._locale) ?? [])]\n }\n if (this._defaultLocale) {\n const defaultData = this._data.get(this._defaultLocale)\n if (defaultData) return [...defaultData]\n }\n const firstKey = this._data.keys().next().value\n if (firstKey !== undefined) {\n return [...(this._data.get(firstKey) ?? [])]\n }\n return []\n }\n\n private _resolveIncludes(item: T): T {\n const resolved = { ...item }\n const src = item as Record<string, unknown>\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const meta = this._relationMeta[field]\n if (!meta) continue\n const targets = Array.isArray(meta.target) ? meta.target : [meta.target]\n\n if (meta.multi) {\n const ids = src[field]\n if (Array.isArray(ids)) {\n dst[field] = ids.map((id) => {\n if (typeof id === 'string') {\n return this._resolveId(targets, id) ?? id\n }\n if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n return this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n return id\n })\n }\n } else {\n const id = src[field]\n if (typeof id === 'string') {\n dst[field] = this._resolveId(targets, id) ?? id\n } else if (typeof id === 'object' && id !== null && 'model' in id && 'ref' in id) {\n const polyObj = id as { model: string; ref: string }\n dst[field] = this._resolveId([polyObj.model], polyObj.ref) ?? id\n }\n }\n }\n return resolved\n }\n\n private _resolveId(targets: string[], id: string): Record<string, unknown> | undefined {\n const loc = this._locale ?? this._defaultLocale\n for (const target of targets) {\n const result = this._resolver!(target, id, loc)\n if (result) return result\n }\n return undefined\n }\n}\n","// Runtime exports — used by framework SDK authors and generated client\nexport { QueryBuilder } from './runtime/query.js'\nexport type { RelationMeta, RelationResolver, WhereOp } from './runtime/query.js'\nexport { SingletonAccessor } from './runtime/singleton.js'\nexport { DictionaryAccessor } from './runtime/dictionary.js'\nexport { DocumentQuery } from './runtime/document.js'\n\n// Shared utilities\nexport type { WhereClause } from './shared/where.js'\nexport { applyWhere } from './shared/where.js'\nexport { resolveMediaUrl, resolveMediaRefsInBody } from './shared/media.js'\n\n// Re-export types from @contentrain/types that SDK consumers need\nexport type {\n FieldType,\n ModelKind,\n ContentStatus,\n FieldDef,\n ModelDefinition,\n ContentrainConfig,\n} from '@contentrain/types'\n\n/**\n * Factory for framework SDK authors.\n * Returns the generated client module loaded from .contentrain/client/.\n *\n * Usage (Nuxt composable):\n * ```ts\n * import { createContentrainClient } from '@contentrain/query'\n * const client = createContentrainClient()\n * const posts = client.query('blog-post').locale('en').all()\n * ```\n */\nexport async function createContentrainClient(\n projectRoot?: string,\n): Promise<{\n query: (model: string) => import('./runtime/query.js').QueryBuilder<Record<string, unknown>>\n singleton: (model: string) => import('./runtime/singleton.js').SingletonAccessor<Record<string, unknown>>\n dictionary: (model: string) => import('./runtime/dictionary.js').DictionaryAccessor\n document: (model: string) => import('./runtime/document.js').DocumentQuery<Record<string, unknown>>\n}> {\n const { resolve } = await import('node:path')\n const { pathToFileURL } = await import('node:url')\n const root = projectRoot ?? process.cwd()\n const clientPath = resolve(root, '.contentrain', 'client', 'index.mjs')\n const client = await import(pathToFileURL(clientPath).href)\n return client\n}\n\n// CDN client factory — async, HTTP-based\nexport { createContentrain } from './cdn/index.js'\nexport type { ContentrainCDNConfig, ContentrainCDNClient } from './cdn/index.js'\nexport type { DocumentIndexEntry } from './cdn/data-source.js'\nexport { ContentrainError, isPaymentRequired } from './cdn/errors.js'\n\n// CDN module re-exports — media, forms, comments, metadata\nexport { MediaAccessor } from './cdn/media-accessor.js'\nexport type { MediaAsset, MediaAssetMeta, MediaManifest } from './cdn/media-accessor.js'\nexport { FormsClient } from './cdn/forms-client.js'\nexport type { FormConfig, FormFieldConfig, FormFieldError, FormSubmitOptions, FormSubmitResult, FormsClientConfig } from './cdn/forms-client.js'\nexport { CommentsClient } from './cdn/comments-client.js'\nexport type {\n CommentAuthor,\n CommentFieldError,\n CommentSubmission,\n CommentSubmitResult,\n CommentThread,\n CommentThreadConfig,\n CommentThreadQuery,\n CommentsClientConfig,\n PublicComment,\n} from './cdn/comments-client.js'\nexport type { EntryMeta } from './cdn/collection-query.js'\nexport { ConversationClient } from './cdn/conversation-client.js'\nexport type {\n ConversationClientConfig,\n ConversationResponse,\n ConversationMessage,\n ConversationHistory,\n} from './cdn/conversation-client.js'\n\n// Sync factory for CJS — requires generated client to be pre-loaded\nexport { createContentrainClient as default }\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publication-CMrWLPi7.d.mts","names":[],"sources":["../src/generator/publication.ts"],"mappings":";UAKiB,kBAAA
|
|
1
|
+
{"version":3,"file":"publication-CMrWLPi7.d.mts","names":[],"sources":["../src/generator/publication.ts"],"mappings":";UAKiB,kBAAA;EAAA;EAEf,aAAA;;EAEA,EAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrain/query",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Optional type-safe query SDK for Contentrain — generated TypeScript client for platform-independent JSON content",
|
|
6
6
|
"type": "module",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"skills"
|
|
90
90
|
],
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@contentrain/types": "1.
|
|
92
|
+
"@contentrain/types": "1.21.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/node": "^22.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cdn-Do8lyms1.mjs","names":[],"sources":["../src/shared/where.ts","../src/cdn/errors.ts","../src/cdn/http-transport.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/public-request.ts","../src/cdn/forms-client.ts","../src/cdn/comments-client.ts","../src/cdn/conversation-client.ts","../src/cdn/index.ts"],"sourcesContent":["export type WhereOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains'\n\nexport interface WhereClause {\n field: string\n op: WhereOp\n value: unknown\n}\n\nexport function applyWhere<T>(item: T, clause: WhereClause): boolean {\n const val = (item as Record<string, unknown>)[clause.field]\n switch (clause.op) {\n case 'eq': {\n if (Array.isArray(val)) return val.includes(clause.value)\n return val === clause.value\n }\n case 'ne': {\n if (Array.isArray(val)) return !val.includes(clause.value)\n return val !== clause.value\n }\n case 'gt': return (val as number) > (clause.value as number)\n case 'gte': return (val as number) >= (clause.value as number)\n case 'lt': return (val as number) < (clause.value as number)\n case 'lte': return (val as number) <= (clause.value as number)\n case 'in': return Array.isArray(clause.value) && (clause.value as unknown[]).includes(val)\n case 'contains': {\n if (typeof val === 'string') return val.includes(clause.value as string)\n if (Array.isArray(val)) return val.includes(clause.value)\n return false\n }\n default: return true\n }\n}\n","export class ContentrainError extends Error {\n constructor(\n public status: number,\n message: string,\n ) {\n super(message)\n this.name = 'ContentrainError'\n }\n}\n","import { ContentrainError } from './errors.js'\nimport type { CollectionDataSource, SingletonDataSource, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry } from './data-source.js'\n\ninterface CacheEntry {\n data: unknown\n etag: string\n}\n\nexport interface TransportConfig {\n baseUrl: string\n projectId: string\n apiKey: string\n /** Bundle preload mode. `true` → `{ revalidateMs: 60_000 }` */\n bundle?: boolean | { revalidateMs?: number }\n defaultLocale?: string\n}\n\ninterface BundleState {\n fetchedAt: number\n paths: Set<string>\n missing: boolean\n inflight: Promise<void> | null\n}\n\ninterface BundlePayload {\n version?: string\n paths?: Record<string, unknown>\n}\n\n/** Paths eligible for bundle serving — everything else (manifests, models/*) has no locale segment. */\nconst BUNDLE_SCOPE = /^(content|documents|meta)\\//\n\nexport class HttpTransport {\n private _baseUrl: string\n private _projectId: string\n private _apiKey: string\n private _cache = new Map<string, CacheEntry>()\n private _bundleMode: boolean\n private _revalidateMs: number\n private _defaultLocale: string\n private _primed = new Map<string, unknown>()\n private _bundles = new Map<string, BundleState>()\n\n constructor(config: TransportConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n this._apiKey = config.apiKey\n const b = config.bundle\n this._bundleMode = !!b\n this._revalidateMs = typeof b === 'object' && typeof b.revalidateMs === 'number' ? b.revalidateMs : 60_000\n this._defaultLocale = config.defaultLocale ?? 'en'\n }\n\n buildUrl(path: string): string {\n return `${this._baseUrl}/${this._projectId}/${path}`\n }\n\n /** Eager warmup (e.g. SSR boot). Resolves `true` when a bundle was found and primed. */\n async preload(locale?: string): Promise<boolean> {\n if (!this._bundleMode) return false\n const l = locale ?? this._defaultLocale\n await this._ensureBundle(l)\n return !this._bundles.get(l)?.missing\n }\n\n async fetch<T>(path: string): Promise<T> {\n if (this._bundleMode && BUNDLE_SCOPE.test(path)) {\n await this._ensureBundle(this._localeOf(path))\n if (this._primed.has(path)) return this._primed.get(path) as T\n // out-of-scope path (doc body, meta, ...) → regular per-path fetch\n }\n return this._networkFetch<T>(path)\n }\n\n /** Locale from a path's last segment (sans `.json`). `data` (non-i18n) → defaultLocale bundle. */\n private _localeOf(path: string): string {\n const last = path.slice(path.lastIndexOf('/') + 1).replace(/\\.json$/, '')\n return last === 'data' ? this._defaultLocale : last\n }\n\n private _ensureBundle(locale: string): Promise<void> | void {\n const state = this._bundles.get(locale)\n if (state?.inflight) return state.inflight\n if (state && Date.now() - state.fetchedAt < this._revalidateMs) return\n\n const next: BundleState = state ?? { fetchedAt: 0, paths: new Set(), missing: false, inflight: null }\n this._bundles.set(locale, next)\n next.inflight = (async () => {\n try {\n // _networkFetch is conditional: unchanged bundle → 304 → cached payload (cheap)\n const bundle = await this._networkFetch<BundlePayload>(`_bundle/${locale}.json`)\n if (bundle?.version !== '1' || !bundle.paths || typeof bundle.paths !== 'object') {\n next.missing = true\n return\n }\n // Evict primed paths absent from the fresh bundle (deleted models must not serve stale)\n const fresh = new Set(Object.keys(bundle.paths))\n for (const p of next.paths) {\n if (!fresh.has(p)) this._primed.delete(p)\n }\n for (const [p, body] of Object.entries(bundle.paths)) this._primed.set(p, body)\n next.paths = fresh\n next.missing = false\n }\n catch {\n // 404 (bundle not built yet) or network error → per-path fallback until next revalidate\n next.missing = true\n }\n finally {\n next.fetchedAt = Date.now()\n next.inflight = null\n }\n })()\n return next.inflight\n }\n\n private async _networkFetch<T>(path: string): Promise<T> {\n const url = `${this._baseUrl}/${this._projectId}/${path}`\n const cached = this._cache.get(path)\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this._apiKey}`,\n }\n if (cached?.etag) {\n headers['If-None-Match'] = cached.etag\n }\n\n const res = await globalThis.fetch(url, { headers })\n\n if (res.status === 304 && cached) return cached.data as T\n if (!res.ok) throw new ContentrainError(res.status, await res.text())\n\n const data = (await res.json()) as T\n const etag = res.headers.get('etag') ?? ''\n if (etag) {\n this._cache.set(path, { data, etag })\n }\n return data\n }\n\n collection<T>(modelId: string): CollectionDataSource<T> {\n return {\n getAll: async (locale) => {\n const map = await this.fetch<Record<string, T>>(`content/${modelId}/${locale}.json`)\n return Object.entries(map).map(([id, entry]) => Object.assign({ id }, entry as object) as T)\n },\n getOne: async (id, locale) => {\n const map = await this.fetch<Record<string, T>>(`content/${modelId}/${locale}.json`)\n const entry = map[id]\n return entry ? { id, ...entry as object } as T : null\n },\n }\n }\n\n singleton<T>(modelId: string): SingletonDataSource<T> {\n return {\n get: (locale) => this.fetch<T>(`content/${modelId}/${locale}.json`),\n }\n }\n\n dictionary(modelId: string): DictionaryDataSource {\n return {\n get: (locale) => this.fetch<Record<string, string>>(`content/${modelId}/${locale}.json`),\n }\n }\n\n document<T>(modelId: string): DocumentDataSource<T> {\n return {\n // `_index` carries frontmatter only — the body is in the per-slug document.\n getIndex: (locale) => this.fetch<DocumentIndexEntry<T>[]>(`documents/${modelId}/_index/${locale}.json`),\n getBySlug: (slug, locale) => this.fetch(`documents/${modelId}/${slug}/${locale}.json`),\n }\n }\n}\n","import type { CollectionDataSource } from './data-source.js'\nimport type { HttpTransport } from './http-transport.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport interface EntryMeta {\n status?: string\n publish_at?: string\n expire_at?: string\n updated_by?: string\n approved_by?: string\n [key: string]: unknown\n}\n\nexport class CdnCollectionQuery<T extends object> {\n private _transport: HttpTransport\n private _source: CollectionDataSource<T>\n private _modelId: string\n private _locale: string = 'en'\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n private _limit: number | null = null\n private _offset = 0\n private _includes: string[] = []\n private _withMeta = false\n\n constructor(transport: HttpTransport, modelId: string, defaultLocale?: string) {\n this._transport = transport\n this._source = transport.collection<T>(modelId)\n this._modelId = modelId\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where(field: string, op: WhereOp, value: unknown): this {\n this._filters.push({ field, op, value })\n return this\n }\n\n sort(field: string, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n limit(n: number): this {\n this._limit = n\n return this\n }\n\n offset(n: number): this {\n this._offset = n\n return this\n }\n\n include(...fields: string[]): this {\n this._includes.push(...fields)\n return this\n }\n\n withMeta(): this {\n this._withMeta = true\n return this\n }\n\n async all(): Promise<T[]> {\n let items = await this._source.getAll(this._locale)\n\n // Filter\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n // Sort\n if (this._sortField) {\n const field = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[field]\n const vb = (b as Record<string, unknown>)[field]\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n if (va < vb) return -dir\n if (va > vb) return dir\n return 0\n })\n }\n\n // Pagination\n if (this._offset > 0 || this._limit !== null) {\n const end = this._limit !== null ? this._offset + this._limit : undefined\n items = items.slice(this._offset, end)\n }\n\n // Resolve relations\n if (this._includes.length > 0) {\n items = await this._resolveIncludes(items)\n }\n\n // Enrich with entry metadata\n if (this._withMeta) {\n items = await this._enrichMeta(items)\n }\n\n return items\n }\n\n async count(): Promise<number> {\n const items = await this.all()\n return items.length\n }\n\n async first(): Promise<T | undefined> {\n const items = await this.all()\n return items[0]\n }\n\n private async _resolveIncludes(items: T[]): Promise<T[]> {\n // Prefetch related collections to avoid N+1\n const cache = new Map<string, Map<string, Record<string, unknown>>>()\n\n for (const field of this._includes) {\n // Collect all IDs for this field\n for (const item of items) {\n const val = (item as Record<string, unknown>)[field]\n const ids = Array.isArray(val) ? val : val ? [val] : []\n for (const id of ids) {\n if (typeof id !== 'string') continue\n // We don't know the target model from here, so we use field name as hint\n // In production, model metadata would provide this mapping\n if (!cache.has(field)) {\n try {\n const related = await this._transport.fetch<Record<string, unknown>>(`content/${field}/${this._locale}.json`)\n const map = new Map<string, Record<string, unknown>>()\n for (const [entryId, entry] of Object.entries(related)) {\n map.set(entryId, { id: entryId, ...entry as object })\n }\n cache.set(field, map)\n } catch {\n cache.set(field, new Map())\n }\n break\n }\n }\n }\n }\n\n return items.map(item => {\n const resolved = { ...item }\n const dst = resolved as Record<string, unknown>\n for (const field of this._includes) {\n const related = cache.get(field)\n if (!related) continue\n const val = (item as Record<string, unknown>)[field]\n if (Array.isArray(val)) {\n dst[field] = val.map(id => typeof id === 'string' ? (related.get(id) ?? id) : id)\n } else if (typeof val === 'string') {\n dst[field] = related.get(val) ?? val\n }\n }\n return resolved\n })\n }\n\n private async _enrichMeta(items: T[]): Promise<T[]> {\n let metaMap: Record<string, EntryMeta> = {}\n try {\n metaMap = await this._transport.fetch<Record<string, EntryMeta>>(`meta/${this._modelId}/${this._locale}.json`)\n } catch {\n // No meta available — return items unchanged\n return items\n }\n return items.map(item => {\n const id = (item as Record<string, unknown>).id as string\n const meta = id ? metaMap[id] : undefined\n if (meta) {\n return { ...item, _meta: meta }\n }\n return item\n })\n }\n}\n\n","import type { SingletonDataSource } from './data-source.js'\n\nexport class CdnSingletonAccessor<T extends Record<string, unknown>> {\n private _source: SingletonDataSource<T>\n private _locale: string = 'en'\n\n constructor(source: SingletonDataSource<T>, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n async get(): Promise<T> {\n return this._source.get(this._locale)\n }\n}\n","import type { DictionaryDataSource } from './data-source.js'\n\nexport class CdnDictionaryAccessor {\n private _source: DictionaryDataSource\n private _locale: string = 'en'\n\n constructor(source: DictionaryDataSource, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n async get(): Promise<Record<string, string>>\n async get(key: string): Promise<string | undefined>\n async get(key: string, params: Record<string, string | number>): Promise<string>\n async get(key?: string, params?: Record<string, string | number>): Promise<Record<string, string> | string | undefined> {\n const dict = await this._source.get(this._locale)\n if (key === undefined) return dict\n const value = dict[key]\n if (value === undefined) return undefined\n if (params) return interpolate(value, params)\n return value\n }\n}\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) => {\n const val = params[key]\n return val !== undefined ? String(val) : match\n })\n}\n","import type { DocumentDataSource, DocumentIndexEntry } from './data-source.js'\nimport type { WhereOp, WhereClause } from '../shared/where.js'\nimport { applyWhere } from '../shared/where.js'\n\nexport class CdnDocumentQuery<T extends object> {\n private _source: DocumentDataSource<T>\n private _locale: string = 'en'\n private _filters: WhereClause[] = []\n private _sortField: string | null = null\n private _sortOrder: 'asc' | 'desc' = 'asc'\n\n constructor(source: DocumentDataSource<T>, defaultLocale?: string) {\n this._source = source\n if (defaultLocale) this._locale = defaultLocale\n }\n\n locale(lang: string): this {\n this._locale = lang\n return this\n }\n\n where(field: string, op: WhereOp, value: unknown): this {\n this._filters.push({ field, op, value })\n return this\n }\n\n sort(field: string, order: 'asc' | 'desc' = 'asc'): this {\n this._sortField = field\n this._sortOrder = order\n return this\n }\n\n /**\n * Every entry's frontmatter, from the model's `_index`.\n *\n * Bodies are not included — fetch one with {@link bySlug}. See\n * {@link DocumentIndexEntry}.\n */\n async all(): Promise<DocumentIndexEntry<T>[]> {\n let items = await this._source.getIndex(this._locale)\n\n for (const clause of this._filters) {\n items = items.filter(item => applyWhere(item, clause))\n }\n\n if (this._sortField) {\n const sf = this._sortField\n const dir = this._sortOrder === 'asc' ? 1 : -1\n items = items.toSorted((a, b) => {\n const va = (a as Record<string, unknown>)[sf] as number | string | null | undefined\n const vb = (b as Record<string, unknown>)[sf] as number | string | null | undefined\n if (va == null && vb == null) return 0\n if (va == null) return dir\n if (vb == null) return -dir\n return va < vb ? -dir : va > vb ? dir : 0\n })\n }\n\n return items\n }\n\n async count(): Promise<number> {\n const items = await this.all()\n return items.length\n }\n\n async first(): Promise<DocumentIndexEntry<T> | undefined> {\n const items = await this.all()\n return items[0]\n }\n\n /** The full document: frontmatter plus its rendered body. */\n async bySlug(slug: string): Promise<{ frontmatter: T; body: string; html: string } | null> {\n return this._source.getBySlug(slug, this._locale)\n }\n}\n","import type { HttpTransport } from './http-transport.js'\n\nexport interface MediaAssetMeta {\n width?: number\n height?: number\n format?: string\n size?: number\n blurhash?: string | null\n alt?: string | null\n}\n\nexport interface MediaAsset {\n original: string\n variants: Record<string, string>\n meta: MediaAssetMeta\n}\n\nexport interface MediaManifest {\n version: string\n assets: Record<string, MediaAsset>\n}\n\nexport class MediaAccessor {\n private _transport: HttpTransport\n private _manifest: MediaManifest | null = null\n\n constructor(transport: HttpTransport) {\n this._transport = transport\n }\n\n async manifest(): Promise<MediaManifest> {\n if (!this._manifest) {\n this._manifest = await this._transport.fetch<MediaManifest>('_media_manifest.json')\n }\n return this._manifest\n }\n\n async assets(): Promise<Record<string, MediaAsset>> {\n const m = await this.manifest()\n return m.assets\n }\n\n async asset(path: string): Promise<MediaAsset | null> {\n const all = await this.assets()\n return all[path] ?? null\n }\n\n async list(): Promise<Array<{ path: string } & MediaAsset>> {\n const all = await this.assets()\n return Object.entries(all).map(([path, asset]) =>\n Object.assign({ path }, asset),\n )\n }\n\n resolve(asset: MediaAsset, variant?: string): string {\n if (variant && asset.variants[variant]) {\n return asset.variants[variant]\n }\n return asset.original\n }\n\n url(asset: MediaAsset, variant?: string): string {\n const path = this.resolve(asset, variant)\n return this._transport.buildUrl(path)\n }\n}\n","// Shared transport for the PUBLIC embed endpoints (forms, comments).\n//\n// These are called from a visitor's browser on someone else's site: no\n// session, no API key — a page cannot keep a secret, and Studio's CORS for\n// these routes allows only `Content-Type`, so an `Authorization` header would\n// fail the preflight before the request is even sent. Errors come back as\n// h3 error bodies (`{ statusCode, message }`) or plain text; both become a\n// `ContentrainError` carrying the HTTP status.\n\nimport { ContentrainError } from './errors.js'\n\nasync function errorMessage(res: Response, fallback: string): Promise<string> {\n const text = await res.text().catch(() => '')\n try {\n const parsed = JSON.parse(text) as { message?: unknown; statusMessage?: unknown }\n const message = parsed.message ?? parsed.statusMessage\n if (typeof message === 'string' && message) return message\n } catch {\n // not JSON — fall through to the raw text\n }\n return text || fallback\n}\n\nexport async function publicGet<T>(url: string): Promise<T> {\n const res = await globalThis.fetch(url)\n if (!res.ok) throw new ContentrainError(res.status, await errorMessage(res, 'Request failed'))\n return (await res.json()) as T\n}\n\nexport async function publicPost<T>(url: string, body: unknown): Promise<T> {\n const res = await globalThis.fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!res.ok) throw new ContentrainError(res.status, await errorMessage(res, 'Request failed'))\n return (await res.json()) as T\n}\n\n/** `baseUrl` without a trailing slash, path segments URL-encoded. */\nexport function publicUrl(baseUrl: string, segments: string[], query?: Record<string, string | number | undefined>): string {\n const path = segments.map((s) => encodeURIComponent(s)).join('/')\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query ?? {})) {\n if (value !== undefined) params.set(key, String(value))\n }\n const qs = params.toString()\n return `${baseUrl.replace(/\\/+$/, '')}/${path}${qs ? `?${qs}` : ''}`\n}\n","// Public forms client — the browser side of Studio's `/api/forms/v1`.\n//\n// Contract (Studio docs/FORMS.md):\n// GET {base}/{projectId}/{modelId}/config → FormConfig\n// POST {base}/{projectId}/{modelId}/submit { data, captchaToken?, _hp? } → FormSubmitResult\n//\n// `fields` is a map keyed by field id (the model's own FieldDef shape), not a\n// list; the captcha comes back as `captcha` + `captchaSiteKey`; the honeypot\n// input's name is `honeypotField`. Submissions wrap the values in `data` so\n// the control fields (`captchaToken`, `_hp`) can never collide with a model\n// field. No credential is sent: the endpoints are public by design.\n\nimport type { FieldDef } from '@contentrain/types'\nimport { publicGet, publicPost, publicUrl } from './public-request.js'\n\n/** One exposed field, as the model defines it. */\nexport type FormFieldConfig = FieldDef\n\nexport interface FormConfig {\n modelId: string\n /** The project's default locale — what a submission is validated against and written to. */\n locale: string\n /** Exposed fields only, keyed by field id. */\n fields: Record<string, FormFieldConfig>\n captcha: 'turnstile' | null\n /** Turnstile widget key, when `captcha` is set and the operator configured one. */\n captchaSiteKey: string | null\n successMessage?: string\n /** Name of the hidden honeypot input to render (and leave empty), or null. */\n honeypotField: string | null\n}\n\nexport interface FormFieldError {\n field: string\n message: string\n}\n\nexport interface FormSubmitResult {\n success: boolean\n /** The model's `successMessage` on success. */\n message?: string\n /** Validation errors against the exposed fields, or `captcha`. */\n errors?: FormFieldError[]\n}\n\nexport interface FormSubmitOptions {\n /** Turnstile token, when the config's `captcha` is set. */\n captchaToken?: string\n /** Value of the honeypot input. A human leaves it empty; a filled one is silently dropped server-side. */\n honeypot?: string\n}\n\nexport interface FormsClientConfig {\n /** Public API root — `https://studio.contentrain.io/api/forms/v1`. */\n baseUrl: string\n projectId: string\n}\n\nexport class FormsClient {\n private _baseUrl: string\n private _projectId: string\n\n constructor(config: FormsClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n }\n\n config(modelId: string): Promise<FormConfig> {\n return publicGet<FormConfig>(publicUrl(this._baseUrl, [this._projectId, modelId, 'config']))\n }\n\n /**\n * Resolves with the server's verdict for 2xx responses — including\n * `{ success: false, errors }` for validation failures, which are not\n * exceptions. Rejects with `ContentrainError` on 403/404/429/5xx.\n */\n submit(modelId: string, data: Record<string, unknown>, options?: FormSubmitOptions): Promise<FormSubmitResult> {\n const body: { data: Record<string, unknown>; captchaToken?: string; _hp?: string } = { data }\n if (options?.captchaToken) body.captchaToken = options.captchaToken\n if (options?.honeypot !== undefined) body._hp = options.honeypot\n return publicPost<FormSubmitResult>(publicUrl(this._baseUrl, [this._projectId, modelId, 'submit']), body)\n }\n}\n","// Public comments client — the browser side of Studio's `/api/comments/v1`.\n//\n// Contract (Studio docs/COMMENTS.md):\n// GET {base}/{projectId}/{modelId}/{entryId}?locale&page&limit&sort → CommentThread\n// POST {base}/{projectId}/{modelId}/{entryId}?locale\n// { author: { name, email?, url? }, body, parentId?, captchaToken?, _hp? } → CommentSubmitResult\n//\n// Only approved comments come back, nested under their roots; email, IP,\n// user agent and referrer never leave the server. `body` is plain text —\n// render it escaped. No credential is sent: the endpoints are public.\n\nimport { publicGet, publicPost, publicUrl } from './public-request.js'\n\nexport type CommentType = 'comment' | 'pingback' | 'trackback'\n\nexport interface CommentAuthor {\n name: string\n url: string | null\n /** Written from Studio by a workspace member. */\n isModerator: boolean\n}\n\nexport interface PublicComment {\n id: string\n parentId: string | null\n depth: number\n author: CommentAuthor\n /** Plain text. */\n body: string\n type: CommentType\n /** ISO 8601. */\n createdAt: string\n replies: PublicComment[]\n}\n\nexport interface CommentThreadConfig {\n /** Thread closed → render the comments, hide the form. */\n closed: boolean\n requireApproval: boolean\n requireEmail: boolean\n /** Reply nesting cap for new submissions (0 = flat). */\n maxDepth: number\n maxBodyLength: number\n captcha: 'turnstile' | null\n captchaSiteKey: string | null\n honeypotField: string | null\n}\n\nexport interface CommentThread {\n entry: { modelId: string; entryId: string; locale: string }\n config: CommentThreadConfig\n /** Root comments of this page, replies nested. */\n comments: PublicComment[]\n /** Root comments in total. */\n total: number\n page: number\n limit: number\n}\n\nexport interface CommentThreadQuery {\n locale?: string\n page?: number\n limit?: number\n sort?: 'oldest' | 'newest'\n}\n\nexport interface CommentSubmission {\n author: { name: string; email?: string; url?: string }\n body: string\n /** Reply target — an approved comment's id; omitted or null for a root comment. */\n parentId?: string | null\n captchaToken?: string\n /** Value of the honeypot input (`config.honeypotField`); a human leaves it empty. */\n honeypot?: string\n}\n\nexport interface CommentFieldError {\n /** `author.name` · `author.email` · `author.url` · `body` · `parentId` · `captcha` */\n field: string\n message: string\n}\n\nexport interface CommentSubmitResult {\n success: boolean\n /** `approved` renders now; `pending` is only echoed back to its author. */\n status?: 'pending' | 'approved'\n /** The stored comment, in the public shape. Absent when the honeypot swallowed the post. */\n comment?: PublicComment\n errors?: CommentFieldError[]\n}\n\nexport interface CommentsClientConfig {\n /** Public API root — `https://studio.contentrain.io/api/comments/v1`. */\n baseUrl: string\n projectId: string\n}\n\nexport class CommentsClient {\n private _baseUrl: string\n private _projectId: string\n\n constructor(config: CommentsClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n }\n\n thread(modelId: string, entryId: string, query?: CommentThreadQuery): Promise<CommentThread> {\n const url = publicUrl(this._baseUrl, [this._projectId, modelId, entryId], {\n locale: query?.locale,\n page: query?.page,\n limit: query?.limit,\n sort: query?.sort,\n })\n return publicGet<CommentThread>(url)\n }\n\n /**\n * Resolves with the server's verdict for 2xx responses — including\n * `{ success: false, errors }`. Rejects with `ContentrainError` on\n * 403 (thread closed / plan), 404, 429 and 5xx.\n */\n submit(\n modelId: string,\n entryId: string,\n submission: CommentSubmission,\n options?: { locale?: string },\n ): Promise<CommentSubmitResult> {\n const url = publicUrl(this._baseUrl, [this._projectId, modelId, entryId], { locale: options?.locale })\n // `parentId: null` is a root comment — sent explicitly, as Studio's own fixture does.\n const body: Record<string, unknown> = { author: submission.author, body: submission.body, parentId: submission.parentId ?? null }\n if (submission.captchaToken) body.captchaToken = submission.captchaToken\n if (submission.honeypot !== undefined) body._hp = submission.honeypot\n return publicPost<CommentSubmitResult>(url, body)\n }\n}\n","import { ContentrainError } from './errors.js'\n\nexport interface ConversationContext {\n activeModelId?: string | null\n activeLocale?: string\n activeEntryId?: string | null\n panelState?: string\n activeBranch?: string | null\n}\n\nexport interface ConversationSendOptions {\n conversationId?: string\n context?: ConversationContext\n}\n\nexport interface ConversationToolResult {\n id: string\n name: string\n result: unknown\n}\n\nexport interface ConversationUsage {\n inputTokens: number\n outputTokens: number\n}\n\nexport interface ConversationResponse {\n conversationId: string\n message: string\n toolResults?: ConversationToolResult[]\n usage: ConversationUsage\n}\n\nexport interface ConversationMessage {\n id: string\n role: 'user' | 'assistant'\n content: string | unknown[]\n toolCalls?: unknown[]\n model?: string\n usage?: ConversationUsage\n createdAt: string\n}\n\nexport interface ConversationHistory {\n conversationId: string\n messages: ConversationMessage[]\n}\n\nexport interface ConversationClientConfig {\n baseUrl: string\n projectId: string\n apiKey: string\n}\n\nexport class ConversationClient {\n private _baseUrl: string\n private _projectId: string\n private _apiKey: string\n\n constructor(config: ConversationClientConfig) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this._projectId = config.projectId\n this._apiKey = config.apiKey\n }\n\n async send(message: string, options?: ConversationSendOptions): Promise<ConversationResponse> {\n const url = `${this._baseUrl}/${this._projectId}/message`\n\n const body: Record<string, unknown> = { message }\n if (options?.conversationId) body.conversationId = options.conversationId\n if (options?.context) body.context = options.context\n\n const res = await globalThis.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this._apiKey}`,\n },\n body: JSON.stringify(body),\n })\n\n if (!res.ok) {\n throw new ContentrainError(res.status, await res.text())\n }\n\n return (await res.json()) as ConversationResponse\n }\n\n async history(conversationId: string, options?: { limit?: number }): Promise<ConversationHistory> {\n const params = new URLSearchParams({ conversationId })\n if (options?.limit) params.set('limit', String(options.limit))\n\n const url = `${this._baseUrl}/${this._projectId}/history?${params}`\n\n const res = await globalThis.fetch(url, {\n headers: {\n 'Authorization': `Bearer ${this._apiKey}`,\n },\n })\n\n if (!res.ok) {\n throw new ContentrainError(res.status, await res.text())\n }\n\n return (await res.json()) as ConversationHistory\n }\n}\n","import { HttpTransport } from './http-transport.js'\nimport { CdnCollectionQuery } from './collection-query.js'\nimport { CdnSingletonAccessor } from './singleton-accessor.js'\nimport { CdnDictionaryAccessor } from './dictionary-accessor.js'\nimport { CdnDocumentQuery } from './document-query.js'\nimport { MediaAccessor } from './media-accessor.js'\nimport { FormsClient } from './forms-client.js'\nimport { CommentsClient } from './comments-client.js'\nimport { ConversationClient } from './conversation-client.js'\n\nexport interface ContentrainCDNConfig {\n projectId: string\n apiKey: string\n baseUrl?: string\n defaultLocale?: string\n /** Bundle preload mode. `true` → `{ revalidateMs: 60_000 }` */\n bundle?: boolean | { revalidateMs?: number }\n}\n\nexport type ContentrainCDNClient = ReturnType<typeof createContentrain>\n\nexport function createContentrain(config: ContentrainCDNConfig) {\n const transport = new HttpTransport({\n baseUrl: config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1',\n projectId: config.projectId,\n apiKey: config.apiKey,\n bundle: config.bundle,\n defaultLocale: config.defaultLocale,\n })\n const defaultLocale = config.defaultLocale\n\n return {\n collection: <T extends object = Record<string, unknown>>(modelId: string) =>\n new CdnCollectionQuery<T>(transport, modelId, defaultLocale),\n\n singleton: <T extends Record<string, unknown> = Record<string, unknown>>(modelId: string) =>\n new CdnSingletonAccessor<T>(transport.singleton<T>(modelId), defaultLocale),\n\n dictionary: (modelId: string) =>\n new CdnDictionaryAccessor(transport.dictionary(modelId), defaultLocale),\n\n document: <T extends object = Record<string, unknown>>(modelId: string) =>\n new CdnDocumentQuery<T>(transport.document<T>(modelId), defaultLocale),\n\n media: () => new MediaAccessor(transport),\n\n // Public embed surfaces: no API key travels with them — a visitor's\n // browser cannot keep a secret, and the endpoints are unauthenticated by design.\n form: () => new FormsClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/forms/v1'),\n projectId: config.projectId,\n }),\n\n comments: () => new CommentsClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/comments/v1'),\n projectId: config.projectId,\n }),\n\n conversation: () => new ConversationClient({\n baseUrl: (config.baseUrl ?? 'https://studio.contentrain.io/api/cdn/v1').replace('/cdn/v1', '/conversation/v1'),\n projectId: config.projectId,\n apiKey: config.apiKey,\n }),\n\n manifest: () => transport.fetch<unknown>('_manifest.json'),\n models: () => transport.fetch<unknown[]>('models/_index.json'),\n model: (id: string) => transport.fetch<unknown>(`models/${id}.json`),\n\n preload: (locale?: string) => transport.preload(locale),\n }\n}\n\n// Re-exports\nexport { ContentrainError } from './errors.js'\nexport type { CollectionDataSource, SingletonDataSource, DictionaryDataSource, DocumentDataSource, DocumentIndexEntry } from './data-source.js'\nexport { HttpTransport } from './http-transport.js'\nexport type { TransportConfig } from './http-transport.js'\nexport { CdnCollectionQuery } from './collection-query.js'\nexport { CdnSingletonAccessor } from './singleton-accessor.js'\nexport { CdnDictionaryAccessor } from './dictionary-accessor.js'\nexport { CdnDocumentQuery } from './document-query.js'\nexport { MediaAccessor } from './media-accessor.js'\nexport type { MediaAsset, MediaAssetMeta, MediaManifest } from './media-accessor.js'\nexport { FormsClient } from './forms-client.js'\nexport type {\n FormConfig,\n FormFieldConfig,\n FormFieldError,\n FormSubmitOptions,\n FormSubmitResult,\n FormsClientConfig,\n} from './forms-client.js'\nexport { CommentsClient } from './comments-client.js'\nexport type {\n CommentAuthor,\n CommentFieldError,\n CommentSubmission,\n CommentSubmitResult,\n CommentThread,\n CommentThreadConfig,\n CommentThreadQuery,\n CommentType,\n CommentsClientConfig,\n PublicComment,\n} from './comments-client.js'\nexport { ConversationClient } from './conversation-client.js'\nexport type {\n ConversationClientConfig,\n ConversationContext,\n ConversationSendOptions,\n ConversationResponse,\n ConversationToolResult,\n ConversationUsage,\n ConversationMessage,\n ConversationHistory,\n} from './conversation-client.js'\n"],"mappings":"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"}
|