includio-cms 0.16.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/DOCS.md +1 -1
  3. package/README.md +62 -0
  4. package/dist/admin/api/rest/routes/collections.js +1 -1
  5. package/dist/admin/api/rest/routes/entries.js +1 -1
  6. package/dist/admin/api/rest/routes/singletons.js +1 -1
  7. package/dist/admin/remote/entry.remote.js +20 -3
  8. package/dist/admin/remote/invite.d.ts +1 -1
  9. package/dist/admin/remote/preview.remote.js +10 -2
  10. package/dist/admin/remote/reorder.js +1 -1
  11. package/dist/admin/remote/shop.remote.d.ts +18 -18
  12. package/dist/ai-claude/index.d.ts +9 -0
  13. package/dist/ai-claude/index.js +23 -7
  14. package/dist/ai-openai/index.d.ts +9 -0
  15. package/dist/ai-openai/index.js +28 -9
  16. package/dist/cms/runtime/api.d.ts +10 -6
  17. package/dist/cms/runtime/api.js +7 -7
  18. package/dist/components/ui/accordion/accordion.svelte.d.ts +1 -1
  19. package/dist/components/ui/calendar/calendar.svelte.d.ts +1 -1
  20. package/dist/components/ui/command/command-dialog.svelte.d.ts +1 -1
  21. package/dist/components/ui/command/command-input.svelte.d.ts +1 -1
  22. package/dist/components/ui/command/command.svelte.d.ts +1 -1
  23. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +1 -1
  24. package/dist/components/ui/input/input.svelte.d.ts +1 -1
  25. package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
  26. package/dist/components/ui/input-group/input-group-textarea.svelte.d.ts +1 -1
  27. package/dist/components/ui/radio-group/radio-group.svelte.d.ts +1 -1
  28. package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
  29. package/dist/components/ui/tabs/tabs.svelte.d.ts +1 -1
  30. package/dist/components/ui/textarea/textarea.svelte.d.ts +1 -1
  31. package/dist/components/ui/toggle-group/toggle-group-item.svelte.d.ts +1 -1
  32. package/dist/components/ui/toggle-group/toggle-group.svelte.d.ts +1 -1
  33. package/dist/core/server/entries/operations/create.js +1 -1
  34. package/dist/core/server/entries/operations/get.d.ts +20 -16
  35. package/dist/core/server/entries/operations/get.js +45 -214
  36. package/dist/core/server/entries/operations/resolveEntry.d.ts +94 -0
  37. package/dist/core/server/entries/operations/resolveEntry.js +210 -0
  38. package/dist/core/server/entries/operations/update.js +1 -1
  39. package/dist/core/server/fields/populateEntry.d.ts +9 -1
  40. package/dist/core/server/fields/populateEntry.js +22 -18
  41. package/dist/core/server/fields/resolveRelationFields.d.ts +2 -1
  42. package/dist/core/server/fields/resolveRelationFields.js +140 -34
  43. package/dist/core/server/fields/resolveRichtextLinks.d.ts +2 -1
  44. package/dist/core/server/fields/resolveRichtextLinks.js +2 -1
  45. package/dist/core/server/fields/resolveUrlFields.d.ts +2 -1
  46. package/dist/core/server/fields/resolveUrlFields.js +6 -5
  47. package/dist/core/server/generator/generator.js +17 -14
  48. package/dist/db-postgres/index.d.ts +4 -0
  49. package/dist/db-postgres/index.js +4 -0
  50. package/dist/email-nodemailer/index.d.ts +9 -0
  51. package/dist/email-nodemailer/index.js +28 -6
  52. package/dist/entity/index.js +1 -1
  53. package/dist/files-local/index.d.ts +4 -0
  54. package/dist/files-local/index.js +4 -0
  55. package/dist/paraglide/messages/_index.d.ts +3 -36
  56. package/dist/paraglide/messages/_index.js +3 -71
  57. package/dist/paraglide/messages/hello_world.d.ts +5 -0
  58. package/dist/paraglide/messages/hello_world.js +33 -0
  59. package/dist/paraglide/messages/login_hello.d.ts +16 -0
  60. package/dist/paraglide/messages/login_hello.js +34 -0
  61. package/dist/paraglide/messages/login_please_login.d.ts +16 -0
  62. package/dist/paraglide/messages/login_please_login.js +34 -0
  63. package/dist/shop/server/populate.d.ts +2 -1
  64. package/dist/shop/server/populate.js +2 -1
  65. package/dist/sveltekit/server/index.d.ts +1 -1
  66. package/dist/sveltekit/server/index.js +1 -1
  67. package/dist/types/adapters/ai.d.ts +8 -0
  68. package/dist/types/adapters/db.d.ts +9 -0
  69. package/dist/types/adapters/email.d.ts +6 -0
  70. package/dist/types/adapters/files.d.ts +5 -0
  71. package/dist/types/plugins.d.ts +6 -2
  72. package/dist/updates/0.18.0/index.d.ts +2 -0
  73. package/dist/updates/0.18.0/index.js +78 -0
  74. package/dist/updates/0.19.0/index.d.ts +2 -0
  75. package/dist/updates/0.19.0/index.js +40 -0
  76. package/dist/updates/index.js +3 -1
  77. package/package.json +14 -5
  78. package/dist/paraglide/messages/en.d.ts +0 -5
  79. package/dist/paraglide/messages/en.js +0 -14
  80. package/dist/paraglide/messages/pl.d.ts +0 -5
  81. package/dist/paraglide/messages/pl.js +0 -14
package/CHANGELOG.md CHANGED
@@ -3,6 +3,128 @@
3
3
  All notable changes to includio-cms are documented here.
4
4
  Generated from `src/lib/updates/` — do not edit manually.
5
5
 
6
+ ## 0.19.0 — 2026-04-29
7
+
8
+ Adapter contracts final + 3rd-party SDKs (`@anthropic-ai/sdk`, `openai`, `nodemailer`) przeniesione do `peerDependenciesMeta` jako optional. Adapter typy + factory oznaczone `@public` JSDoc. README sekcja "Writing your own adapter".
9
+
10
+ ### Added
11
+ - Adapter typy (`DatabaseAdapter`, `FilesAdapter`, `EmailAdapter`, `AIAdapter`) finalne, oznaczone `@public` JSDoc — stabilna powierzchnia kontraktu, TypeScript egzekwuje surface.
12
+ - Factory funkcje adapterów (`pg`, `local`, `nodemailerAdapter`, `openAIAdapter`, `claudeAdapter`) oznaczone `@public`.
13
+ - README sekcja "Writing your own adapter" + przykład bazujący na `db-postgres` + tabela optional peer dependencies.
14
+ - Lazy import 3 SDK (`@anthropic-ai/sdk`, `openai`, `nodemailer`) w factory adapterach — SDK nie ładuje się dopóki adapter nie jest faktycznie użyty.
15
+
16
+ ### Fixed
17
+ - Bundle slim — instalacja `includio-cms` w czystym projekcie nie ciąga już ~7-9MB SDK (anthropic + openai + nodemailer). Zostają w peer optional, doinstalowane tylko gdy faktycznie potrzebne.
18
+
19
+ ### Breaking
20
+ - **`@anthropic-ai/sdk`, `openai`, `nodemailer` przeniesione z `dependencies` do `peerDependenciesMeta` jako optional**. Userland używający `email-nodemailer`/`ai-openai`/`ai-claude` musi sam doinstalować odpowiedni SDK: `pnpm add nodemailer`, `pnpm add openai`, `pnpm add @anthropic-ai/sdk`. Brak peer = throw przy pierwszym użyciu adaptera (`generateAltText`/`sendMail`) z czytelnym komunikatem co doinstalować.
21
+ - **`runed` przeniesione z `peerDependenciesMeta.optional` do required peer**. `runed` jest hard-importowane w admin UI (PersistedState), więc opcjonalność była fikcyjna — userland uruchamiający admin BEZ `runed` dostawał crash przy bootcie. Teraz peer wymaga jawnej instalacji (lub pozostaje pulled przez SvelteKit projektu).
22
+
23
+ ### Notes
24
+
25
+ Migracja:
26
+
27
+ 1. Dodaj wymagane peer SDK do swojego `package.json`:
28
+
29
+ ```bash
30
+ # Jeśli używasz nodemailerAdapter:
31
+ pnpm add nodemailer
32
+
33
+ # Jeśli używasz openAIAdapter:
34
+ pnpm add openai
35
+
36
+ # Jeśli używasz claudeAdapter:
37
+ pnpm add @anthropic-ai/sdk
38
+ ```
39
+
40
+ 2. `runed` był już peer wcześniej, ale teraz nie jest optional — upewnij się że jest zainstalowane (zwykle pulled przez SvelteKit). Jeśli `pnpm install` zgłasza missing peer, dodaj jawnie: `pnpm add runed`.
41
+
42
+ Brak SQL migration. Zmiana czysto package-level.
43
+
44
+ Pisanie własnych adapterów:
45
+
46
+ Wszystkie 4 typy adapterów (`DatabaseAdapter`, `FilesAdapter`, `EmailAdapter`, `AIAdapter`) mają teraz `@public` kontrakty. Patrz README sekcja "Writing your own adapter" + przykład bazujący na `db-postgres`.
47
+
48
+ ## 0.18.0 — 2026-04-29
49
+
50
+ Konsolidacja entry resolverów — kanoniczny `resolveEntry()` / `resolveEntries()` / `countEntries()` w jednym public API. Locale strict, cycle detection, populate config per-field opt-out + maxDepth. Hard remove starych funkcji (getEntry, getEntries, getRawEntry/ies, getDbEntry/ies, populateEntryData) z public surface — przeniesione do internal lub całkowicie usunięte.
51
+
52
+ ### Added
53
+ - `resolveEntry({ id?, collection?, locale?, status?, populate? })` — kanoniczny resolver pojedynczego entry; `id` lub `collection` wymagane. Default locale = `cms.languages[0]`, default status = `published`. Zwraca null gdy locale/status nie ma versionu (strict, brak fallback).
54
+ - `resolveEntries({ collection, locale?, status?, ids?, filter?, orderBy?, limit?, offset?, populate? })` — kanoniczny lister; pokrywa wszystkie use case starego `getEntries`.
55
+ - `countEntries({ collection, locale?, status?, ids?, filter? })` — zlicza entries pasujące do kryteriów (per locale, per status). Bez populate (tani DB count).
56
+ - `PopulateConfig` — typ public: `{ maxDepth?: number; fields?: Record<string, false> }`. Per-field opt-out (`{ author: false }` → raw ID). Default maxDepth = 5 (soft cap).
57
+ - Cycle detection w nested populate — A → B → A nie wybucha; powtórzony entryId zachowuje raw ID zamiast dalszej rekurencji.
58
+ - Status cascade — draft entry z `status: "draft"` populuje draft relations (jeśli istnieją w tym samym locale). Published cascade do published nested.
59
+ - `status: "scheduled"` — dostępne w resolverze. Use case: strona z odliczaniem (countdown) do launchu produktu/postu. `entry._publishedAt` daje datę przyszłej publikacji.
60
+
61
+ ### Fixed
62
+ - Locale spójny w całym call chain — żaden field-level resolver nie hardcoduje już lokalizacji ani nie używa innego defaultu niż top-level resolver. Stara fragmentacja (`resolveRelationFields` defaultowało do `getEntries` published-only) usunięta.
63
+ - Recursion guard — głęboka kolekcja relacji (≥ 6 poziomów) nie wybucha już stackiem. Soft maxDepth=5 + cycle detection.
64
+ - Strict locale — brak ukrytego fallbacku do `cms.languages[0]` w nested resolverach (był różnie w każdym field-resolverze).
65
+
66
+ ### Breaking
67
+ - **REMOVED z public API**: `getEntry`, `getEntries`, `getEntryOrThrow`, `getRawEntry`, `getRawEntries`, `getRawEntryOrThrow`, `getDbEntry`, `getDbEntries`, `populateEntryData`. Wszystkie te funkcje były dotąd re-exportowane przez `includio-cms/server` i `includio-cms`. **Zamień na `resolveEntry`/`resolveEntries`/`countEntries`** zgodnie z migration table niżej. Nie ma deprecated wrappera — hard remove zgodnie z polityką lean-v1 (wszystkie breakingy PRZED v1.0).
68
+ - **Rename arg `language` → `locale`** w `resolveEntry`/`resolveEntries`/`countEntries`. Stare API używało `language`, nowe `locale` (semantycznie bardziej precyzyjne; wartość bez zmian — `cms.languages[N]`).
69
+ - **Rename arg `slug` → `collection`** w resolverach. Stare API używało `slug` (co konfundowało z slugiem entry). Nowe: `collection: "posts"`. Singletons też używają `collection: "settings"` (cms.getBySlug obejmuje obie typy).
70
+ - **`status` enum zwężony** z `"published" | "draft" | "scheduled" | "archived"` do `"published" | "draft" | "scheduled"`. `archived` nie jest już dostępny w resolverze (to filter listy, nie fetch by id) — admin używa internal `_getRawEntries` envelope.
71
+ - **Plugin `populateResolver` 3-arg signature** — custom field plugin `populateResolver(value, field)` ma teraz 3-ci arg `ctx: PopulateCtx` (locale, status, depth, visited, populate, entryId). Plugin API jest `@experimental`, więc breaking dopuszczalne. Migracja: zaktualizuj sygnaturę. Stary 2-arg call zostaje wywołany ale ignoruje cascade — najlepiej dodać 3-ci arg.
72
+ - **`PopulateConfig`** wymagany dla opt-out — wcześniej populate był all-or-nothing.
73
+ - **`populatePreviewData` (admin remote)** używa teraz internal `_populate` zamiast `populateEntryData`. Public API niezmienione, ale jeśli importowałeś `populateEntryData` jako helper — usuń.
74
+ - **Internal renames** — `_getRawEntry/ies`, `_getDbEntry/ies`, `_getRawEntryOrThrow`. Funkcje pozostają dostępne dla admin REST i remote, ale **NIE** są re-exportowane przez `includio-cms/server`. Userland code MUSI przejść na `resolveEntry`/`resolveEntries`.
75
+
76
+ ### Notes
77
+
78
+ Migration table:
79
+
80
+ | Old | New |
81
+ |---|---|
82
+ | `getEntry({ slug, id, language, status })` | `resolveEntry({ collection: slug, id, locale: language, status })` |
83
+ | `getEntry({ slug, language })` (singleton) | `resolveEntry({ collection: slug, locale: language })` |
84
+ | `getEntries({ slug, language, status, ids?, limit?, offset? })` | `resolveEntries({ collection: slug, locale: language, status, ids?, limit?, offset? })` |
85
+ | `getEntryOrThrow(opts)` | `const e = await resolveEntry(opts); if (!e) throw new Error('Entry not found');` |
86
+ | `getRawEntry/ies(...)` | INTERNAL — niedostępne. Jeśli potrzebujesz envelope z per-language draft/published versions, zbuduj custom REST endpoint po stronie aplikacji. |
87
+ | `getDbEntry/ies(...)` | INTERNAL — niedostępne. Userland NIE powinien używać raw DB queries; przejdź na `resolveEntry/ies`. |
88
+ | `populateEntryData(data, fields, language, entryId?)` | INTERNAL — admin preview używa wewnątrz. |
89
+
90
+ Before/after:
91
+
92
+ ```ts
93
+ // PRZED (0.16):
94
+ import { getEntry, getEntries } from 'includio-cms/server';
95
+ const post = await getEntry({ slug: 'posts', id: postId, language: 'pl' });
96
+ const all = await getEntries({ slug: 'posts', language: 'pl', limit: 10 });
97
+
98
+ // PO (0.17):
99
+ import { resolveEntry, resolveEntries } from 'includio-cms/server';
100
+ const post = await resolveEntry({ collection: 'posts', id: postId, locale: 'pl' });
101
+ const all = await resolveEntries({ collection: 'posts', locale: 'pl', limit: 10 });
102
+ ```
103
+
104
+ Populate opt-out:
105
+
106
+ ```ts
107
+ // Pomiń populate dla pojedynczego pola (zwróć raw ID zamiast Entry):
108
+ const post = await resolveEntry({
109
+ collection: 'posts',
110
+ id: postId,
111
+ locale: 'pl',
112
+ populate: { fields: { author: false } }
113
+ });
114
+ console.log(post.author); // 'a1' (string, nie Entry)
115
+
116
+ // Ogranicz głębokość rekursji:
117
+ const post = await resolveEntry({
118
+ collection: 'posts',
119
+ id: postId,
120
+ locale: 'pl',
121
+ populate: { maxDepth: 1 }
122
+ });
123
+ // post.author = pełen Entry, post.author.featuredPost = raw ID (depth 2)
124
+ ```
125
+
126
+ Brak SQL migration. Stary code używający usuniętych funkcji rzuci ImportError przy `pnpm i && pnpm build` — wszystko w userland kodzie wyłapie się TS-em od razu.
127
+
6
128
  ## 0.16.0 — 2026-04-29
7
129
 
8
130
  Hard reset martwego kodu — start drogi do v1.0.0. Wycięte: prototyp inline-edit, demo seed, demo routes. Zostają: cmp/ (backend działa), mockups/ (designy), isomorphic-dompurify (Faza 5), tippy.js (slash-command).
package/DOCS.md CHANGED
@@ -1,4 +1,4 @@
1
- # Includio CMS Documentation (v0.16.0)
1
+ # Includio CMS Documentation (v0.19.0)
2
2
 
3
3
  > This file is auto-generated from the docs site. For the latest version, update the package.
4
4
 
package/README.md CHANGED
@@ -38,6 +38,68 @@ export default defineConfig({
38
38
 
39
39
  See the [full documentation](/docs) for installation, configuration, and usage.
40
40
 
41
+ ## Writing your own adapter
42
+
43
+ `includio-cms` ships with default adapters (`db-postgres`, `files-local`, `email-nodemailer`, `ai-openai`, `ai-claude`). Each is a factory returning an object that implements a `@public` contract from `includio-cms/types`. Build your own by implementing the same interface — TypeScript will enforce the surface.
44
+
45
+ Four adapter contracts:
46
+
47
+ - `DatabaseAdapter` — entries, versions, media, tags, form submissions, consent logs.
48
+ - `FilesAdapter` — file upload/download/list, optional private files (e.g. shop receipts).
49
+ - `EmailAdapter` — `sendMail`, default from address/name.
50
+ - `AIAdapter` — currently `generateAltText(fileId)`.
51
+
52
+ Source of truth: [`src/lib/types/adapters/`](src/lib/types/adapters/).
53
+
54
+ ### Minimal custom DB adapter (sketch)
55
+
56
+ ```ts
57
+ import type { DatabaseAdapter } from 'includio-cms/types';
58
+
59
+ export function myDbAdapter(config: { connection: string }): DatabaseAdapter {
60
+ // ...connect, prepare your client...
61
+ return {
62
+ createEntry: async (data) => { /* ... */ },
63
+ getEntries: async (opts) => { /* ... */ },
64
+ countEntries: async (opts) => { /* ... */ },
65
+ updateEntry: async (data) => { /* ... */ },
66
+ archiveEntry: async (data) => { /* ... */ },
67
+ deleteEntry: async (data) => { /* ... */ },
68
+ createEntryVersion: async (data) => { /* ... */ },
69
+ updateEntryVersion: async (data) => { /* ... */ },
70
+ getEntryVersions: async (data) => { /* ... */ },
71
+ deleteEntryVersion: async (data) => { /* ... */ },
72
+ // ...form submissions, media files, image/video styles, tags, consent logs...
73
+ };
74
+ }
75
+ ```
76
+
77
+ Wire it in `cms.config.ts`:
78
+
79
+ ```ts
80
+ import { defineConfig } from 'includio-cms/sveltekit';
81
+ import { myDbAdapter } from './my-adapter.js';
82
+
83
+ export default defineConfig({
84
+ db: myDbAdapter({ connection: process.env.MY_DB_URL! }),
85
+ // ...
86
+ });
87
+ ```
88
+
89
+ Reference implementation: [`src/lib/db-postgres/index.ts`](src/lib/db-postgres/index.ts) (drizzle + `postgres`).
90
+
91
+ ### Optional peer dependencies
92
+
93
+ The default email + AI adapters depend on third-party SDKs that **are not installed by default**. If you use them, install the peer:
94
+
95
+ | Adapter | Required peer | Install |
96
+ | ------------------------- | ------------------------ | -------------------------------------- |
97
+ | `email-nodemailer` | `nodemailer` | `pnpm add nodemailer` |
98
+ | `ai-openai` | `openai` | `pnpm add openai` |
99
+ | `ai-claude` | `@anthropic-ai/sdk` | `pnpm add @anthropic-ai/sdk` |
100
+
101
+ Each SDK is loaded lazily on first call. Missing peer throws a clear error at runtime — install it and the adapter wakes up.
102
+
41
103
  ## Links
42
104
 
43
105
  - [Full Documentation](DOCS.md)
@@ -1,6 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { getCMS } from '../../../../core/cms.js';
3
- import { getRawEntries, getRawEntry, countRawEntries } from '../../../../core/server/entries/operations/get.js';
3
+ import { _getRawEntries as getRawEntries, _getRawEntry as getRawEntry, _countRawEntries as countRawEntries } from '../../../../core/server/entries/operations/get.js';
4
4
  import { createEntry } from '../../../../core/server/entries/operations/create.js';
5
5
  import { upsertDraftVersion, updateEntry, updateEntryVersion } from '../../../../core/server/entries/operations/update.js';
6
6
  import { deleteEntry } from '../../../../core/server/entries/operations/delete.js';
@@ -1,6 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { getCMS } from '../../../../core/cms.js';
3
- import { getRawEntryOrThrow } from '../../../../core/server/entries/operations/get.js';
3
+ import { _getRawEntryOrThrow as getRawEntryOrThrow } from '../../../../core/server/entries/operations/get.js';
4
4
  import { updateEntry, updateEntryVersion, unpublishEntryLang } from '../../../../core/server/entries/operations/update.js';
5
5
  export async function POST(event, id, action) {
6
6
  const user = event.locals.user;
@@ -1,6 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { getCMS } from '../../../../core/cms.js';
3
- import { getRawEntries } from '../../../../core/server/entries/operations/get.js';
3
+ import { _getRawEntries as getRawEntries } from '../../../../core/server/entries/operations/get.js';
4
4
  import { createEntry } from '../../../../core/server/entries/operations/create.js';
5
5
  import { upsertDraftVersion } from '../../../../core/server/entries/operations/update.js';
6
6
  export async function GET(event, slug) {
@@ -1,7 +1,8 @@
1
1
  import { command, query } from '$app/server';
2
2
  import { getAtPath } from '../utils/objectPath.js';
3
3
  import { createEntry as createEntryOperation, createEntrySchema, createEntryVersion } from '../../core/server/entries/operations/create.js';
4
- import { getRawEntries as getRawEntriesOperation, countRawEntries as countRawEntriesOperation, getRawEntry as getRawEntryOperation, getRawEntryOrThrow, getDbEntry, getDbEntryOrThrow, getEntries as getEntriesOperation, getEntry as getEntryOperation, getEntryVersion as getEntryVersionOperation, getEntryLabels as getEntryLabelsOperation } from '../../core/server/entries/operations/get.js';
4
+ import { _getRawEntries as getRawEntriesOperation, _countRawEntries as countRawEntriesOperation, _getRawEntry as getRawEntryOperation, _getRawEntryOrThrow as getRawEntryOrThrow, _getDbEntry as getDbEntry, getEntryVersion as getEntryVersionOperation, getEntryLabels as getEntryLabelsOperation } from '../../core/server/entries/operations/get.js';
5
+ import { resolveEntries, resolveEntry } from '../../core/server/entries/operations/resolveEntry.js';
5
6
  import { getCMS } from '../../core/cms.js';
6
7
  import { pruneOldDraftVersions, unpublishEntryLang, upsertDraftVersion, updateEntry, updateEntrySchema, updateEntryVersionCommandTypes } from '../../core/server/entries/operations/update.js';
7
8
  import z from 'zod';
@@ -42,7 +43,17 @@ export const getEntries = query(z.object({
42
43
  })
43
44
  .optional()
44
45
  }), async (input) => {
45
- return getEntriesOperation(input);
46
+ if (!input.slug)
47
+ return [];
48
+ const status = input.status === 'draft' || input.status === 'scheduled' ? input.status : 'published';
49
+ return resolveEntries({
50
+ collection: input.slug,
51
+ ids: input.ids,
52
+ locale: input.language,
53
+ status,
54
+ filter: { dataValues: input.dataValues, dataLike: input.dataLike },
55
+ orderBy: input.orderBy
56
+ });
46
57
  });
47
58
  export const getEntryLabels = query(z.object({
48
59
  slug: z.string(),
@@ -61,7 +72,13 @@ export const getEntry = query(z.object({
61
72
  status: z.enum(entryStatuses).optional(),
62
73
  slug: z.string().optional()
63
74
  }), async (input) => {
64
- return getEntryOperation(input);
75
+ const status = input.status === 'draft' || input.status === 'scheduled' ? input.status : 'published';
76
+ return resolveEntry({
77
+ id: input.id,
78
+ collection: input.slug,
79
+ locale: input.language,
80
+ status
81
+ });
65
82
  });
66
83
  export const createEntry = command(createEntrySchema, async (input) => {
67
84
  requireAuth();
@@ -5,8 +5,8 @@ export declare function createInvitation(email: string, role: UserRole, createdB
5
5
  createdAt: Date;
6
6
  email: string;
7
7
  expiresAt: Date;
8
- token: string;
9
8
  createdBy: string;
9
+ token: string;
10
10
  usedAt: Date | null;
11
11
  }>;
12
12
  export declare function getInvitationByToken(token: string): Promise<{
@@ -1,6 +1,6 @@
1
1
  import { command } from '$app/server';
2
2
  import { getCMS } from '../../core/cms.js';
3
- import { populateEntryData } from '../../core/server/fields/populateEntry.js';
3
+ import { _populate } from '../../core/server/fields/populateEntry.js';
4
4
  import { getFieldsFromConfig } from '../../core/fields/layoutUtils.js';
5
5
  import z from 'zod';
6
6
  const schema = z.object({
@@ -11,6 +11,14 @@ const schema = z.object({
11
11
  export const populatePreviewData = command(schema, async ({ data, slug, language }) => {
12
12
  const config = getCMS().getBySlug(slug);
13
13
  const fields = getFieldsFromConfig(config);
14
- const populated = await populateEntryData(data, fields, language);
14
+ const populated = await _populate(data, fields, {
15
+ locale: language,
16
+ status: 'draft',
17
+ depth: 0,
18
+ maxDepth: 5,
19
+ visited: new Set(),
20
+ populate: {},
21
+ entryId: ''
22
+ });
15
23
  return populated;
16
24
  });
@@ -1,4 +1,4 @@
1
- import { getDbEntries } from '../../core/server/entries/operations/get.js';
1
+ import { _getDbEntries as getDbEntries } from '../../core/server/entries/operations/get.js';
2
2
  import { updateEntry } from '../../core/server/entries/operations/update.js';
3
3
  export async function stableSlotReorder(orderedIds, collectionSlug) {
4
4
  if (orderedIds.length === 0)
@@ -88,12 +88,6 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
88
88
  createdAt: Date;
89
89
  updatedAt: Date;
90
90
  language: string | null;
91
- accessToken: string;
92
- consents: {
93
- id: string;
94
- accepted: boolean;
95
- label: string;
96
- }[] | null;
97
91
  carrierType: string | null;
98
92
  currency: string;
99
93
  customerEmail: string;
@@ -113,7 +107,13 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
113
107
  shipmentCreatedAt: Date | null;
114
108
  paymentMethod: string | null;
115
109
  paymentProviderRef: string | null;
110
+ consents: {
111
+ id: string;
112
+ accepted: boolean;
113
+ label: string;
114
+ }[] | null;
116
115
  notes: string | null;
116
+ accessToken: string;
117
117
  }[]>;
118
118
  export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
119
119
  order: {
@@ -123,12 +123,6 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
123
123
  createdAt: Date;
124
124
  updatedAt: Date;
125
125
  language: string | null;
126
- accessToken: string;
127
- consents: {
128
- id: string;
129
- accepted: boolean;
130
- label: string;
131
- }[] | null;
132
126
  carrierType: string | null;
133
127
  currency: string;
134
128
  customerEmail: string;
@@ -148,7 +142,13 @@ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFuncti
148
142
  shipmentCreatedAt: Date | null;
149
143
  paymentMethod: string | null;
150
144
  paymentProviderRef: string | null;
145
+ consents: {
146
+ id: string;
147
+ accepted: boolean;
148
+ label: string;
149
+ }[] | null;
151
150
  notes: string | null;
151
+ accessToken: string;
152
152
  };
153
153
  items: {
154
154
  id: string;
@@ -182,12 +182,6 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
182
182
  createdAt: Date;
183
183
  updatedAt: Date;
184
184
  language: string | null;
185
- accessToken: string;
186
- consents: {
187
- id: string;
188
- accepted: boolean;
189
- label: string;
190
- }[] | null;
191
185
  carrierType: string | null;
192
186
  currency: string;
193
187
  customerEmail: string;
@@ -207,7 +201,13 @@ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand
207
201
  shipmentCreatedAt: Date | null;
208
202
  paymentMethod: string | null;
209
203
  paymentProviderRef: string | null;
204
+ consents: {
205
+ id: string;
206
+ accepted: boolean;
207
+ label: string;
208
+ }[] | null;
210
209
  notes: string | null;
210
+ accessToken: string;
211
211
  }>>;
212
212
  export declare const resendOrderEmailCmd: import("@sveltejs/kit").RemoteCommand<{
213
213
  orderId: string;
@@ -1,2 +1,11 @@
1
1
  import type { AIAdapter, AIConfig } from '../types/adapters/ai.js';
2
+ /**
3
+ * Anthropic Claude AI adapter for `generateAltText`.
4
+ *
5
+ * `@anthropic-ai/sdk` is an **optional peer dependency** — install it in your
6
+ * project (`pnpm add @anthropic-ai/sdk`) when using this adapter. SDK loads
7
+ * lazily on first call; missing peer throws a clear error.
8
+ *
9
+ * @public
10
+ */
2
11
  export declare function claudeAdapter(config: AIConfig): AIAdapter;
@@ -1,14 +1,29 @@
1
1
  import { getCMS } from '../core/cms.js';
2
- import Anthropic from '@anthropic-ai/sdk';
3
2
  import sharp from 'sharp';
3
+ /**
4
+ * Anthropic Claude AI adapter for `generateAltText`.
5
+ *
6
+ * `@anthropic-ai/sdk` is an **optional peer dependency** — install it in your
7
+ * project (`pnpm add @anthropic-ai/sdk`) when using this adapter. SDK loads
8
+ * lazily on first call; missing peer throws a clear error.
9
+ *
10
+ * @public
11
+ */
4
12
  export function claudeAdapter(config) {
5
13
  let client = null;
6
- function getClient() {
7
- if (!client) {
8
- if (!config.apiKey)
9
- throw new Error('AI_CLAUDE_API_KEY is not set');
10
- client = new Anthropic({ apiKey: config.apiKey });
14
+ async function getClient() {
15
+ if (client)
16
+ return client;
17
+ if (!config.apiKey)
18
+ throw new Error('AI_CLAUDE_API_KEY is not set');
19
+ let Anthropic;
20
+ try {
21
+ Anthropic = (await import('@anthropic-ai/sdk')).default;
11
22
  }
23
+ catch {
24
+ throw new Error('@anthropic-ai/sdk is required for claudeAdapter — install it with `pnpm add @anthropic-ai/sdk`');
25
+ }
26
+ client = new Anthropic({ apiKey: config.apiKey });
12
27
  return client;
13
28
  }
14
29
  return {
@@ -29,7 +44,8 @@ export function claudeAdapter(config) {
29
44
  const pngBuffer = await sharp(fileBuffer).png().toBuffer();
30
45
  const imageBase64 = pngBuffer.toString('base64');
31
46
  const prompt = `Generate a concise and descriptive alt text for the following image file in polish language. The alt text should accurately describe the content and context of the image, be no longer than 125 characters, and avoid using phrases like "image of" or "picture of". Return only the alt text, nothing else.`;
32
- const message = await getClient().messages.create({
47
+ const anthropic = await getClient();
48
+ const message = await anthropic.messages.create({
33
49
  model: 'claude-haiku-4-5-20251001',
34
50
  max_tokens: 256,
35
51
  messages: [
@@ -1,2 +1,11 @@
1
1
  import type { AIAdapter, AIConfig } from '../types/adapters/ai.js';
2
+ /**
3
+ * OpenAI AI adapter for `generateAltText`.
4
+ *
5
+ * `openai` is an **optional peer dependency** — install it in your project
6
+ * (`pnpm add openai`) when using this adapter. SDK loads lazily on first call;
7
+ * missing peer throws a clear error.
8
+ *
9
+ * @public
10
+ */
2
11
  export declare function openAIAdapter(config: AIConfig): AIAdapter;
@@ -1,12 +1,32 @@
1
1
  import { getCMS } from '../core/cms.js';
2
- import OpenAI from 'openai';
3
- import { zodResponseFormat } from 'openai/helpers/zod.mjs';
4
2
  import z from 'zod';
5
3
  import sharp from 'sharp';
4
+ /**
5
+ * OpenAI AI adapter for `generateAltText`.
6
+ *
7
+ * `openai` is an **optional peer dependency** — install it in your project
8
+ * (`pnpm add openai`) when using this adapter. SDK loads lazily on first call;
9
+ * missing peer throws a clear error.
10
+ *
11
+ * @public
12
+ */
6
13
  export function openAIAdapter(config) {
7
- const openai = new OpenAI({
8
- apiKey: config.apiKey
9
- });
14
+ let openai = null;
15
+ let zodResponseFormat = null;
16
+ async function getClient() {
17
+ if (openai && zodResponseFormat)
18
+ return { client: openai, zodResponseFormat };
19
+ let OpenAI;
20
+ try {
21
+ OpenAI = (await import('openai')).default;
22
+ zodResponseFormat = (await import('openai/helpers/zod.mjs')).zodResponseFormat;
23
+ }
24
+ catch {
25
+ throw new Error('openai is required for openAIAdapter — install it with `pnpm add openai`');
26
+ }
27
+ openai = new OpenAI({ apiKey: config.apiKey });
28
+ return { client: openai, zodResponseFormat };
29
+ }
10
30
  return {
11
31
  generateAltText: async (fileId) => {
12
32
  const altTextSchema = z.object({
@@ -24,13 +44,12 @@ export function openAIAdapter(config) {
24
44
  if (!file) {
25
45
  throw new Error('File not found');
26
46
  }
27
- // Konwertuj plik na PNG używając Sharp i przekonwertuj na base64
28
47
  const fileBuffer = Buffer.from(await file.arrayBuffer());
29
48
  const pngBuffer = await sharp(fileBuffer).png().toBuffer();
30
49
  const imageBase64 = pngBuffer.toString('base64');
31
50
  const prompt = `Generate a concise and descriptive alt text for the following image file in polish language. The alt text should accurately describe the content and context of the image, be no longer than 125 characters, and avoid using phrases like "image of" or "picture of".`;
32
- const completion = await openai.chat.completions.parse({
33
- // model: 'gpt-4.1-nano',
51
+ const { client, zodResponseFormat: zrf } = await getClient();
52
+ const completion = await client.chat.completions.parse({
34
53
  model: 'gpt-4o',
35
54
  messages: [
36
55
  {
@@ -49,7 +68,7 @@ export function openAIAdapter(config) {
49
68
  ]
50
69
  }
51
70
  ],
52
- response_format: zodResponseFormat(altTextSchema, 'response')
71
+ response_format: zrf(altTextSchema, 'response')
53
72
  });
54
73
  const response = completion.choices[0].message;
55
74
  if (!response.parsed) {
@@ -1,14 +1,18 @@
1
1
  import type { SingleEntryMap, SingleSlug, CollectionEntryMap, CollectionSlug, FormEntryMap, SiteLanguage } from './types';
2
+ import { type PopulateConfig } from 'includio-cms/sveltekit/server';
2
3
  interface GetEntryOptions {
3
4
  id?: string;
4
- status?: 'draft' | 'published' | 'scheduled' | 'archived';
5
- dataValues?: Record<string, unknown>;
6
- language?: SiteLanguage;
5
+ status?: 'published' | 'draft' | 'scheduled';
6
+ populate?: PopulateConfig;
7
+ locale?: SiteLanguage;
7
8
  }
8
9
  interface GetEntriesOptions extends GetEntryOptions {
9
10
  ids?: string[];
10
- dataLike?: Record<string, unknown>;
11
- dataILikeOr?: Record<string, unknown>;
11
+ filter?: {
12
+ dataValues?: Record<string, unknown>;
13
+ dataLike?: Record<string, unknown>;
14
+ dataILikeOr?: Record<string, unknown>;
15
+ };
12
16
  orderBy?: {
13
17
  column: 'createdAt' | 'updatedAt' | 'sortOrder';
14
18
  direction: 'asc' | 'desc';
@@ -23,7 +27,7 @@ interface GetEntriesOptions extends GetEntryOptions {
23
27
  export declare function getSingleEntry<K extends SingleSlug>(slug: K, options?: GetEntryOptions): Promise<SingleEntryMap[K] | null>;
24
28
  export declare function getCollectionEntry<K extends CollectionSlug>(slug: K, options?: GetEntryOptions): Promise<CollectionEntryMap[K] | null>;
25
29
  export declare function getCollectionEntries<K extends CollectionSlug>(slug: K, options?: GetEntriesOptions): Promise<CollectionEntryMap[K][]>;
26
- export declare function countCollectionEntries<K extends CollectionSlug>(slug: K, options?: Omit<GetEntriesOptions, 'limit' | 'offset' | 'orderBy'>): Promise<number>;
30
+ export declare function countCollectionEntries<K extends CollectionSlug>(slug: K, options?: Omit<GetEntriesOptions, 'limit' | 'offset' | 'orderBy' | 'populate'>): Promise<number>;
27
31
  export interface SubmitFormOptions {
28
32
  ip?: string;
29
33
  userAgent?: string;
@@ -1,22 +1,22 @@
1
1
  // This file is auto-generated. Do not edit directly.
2
- import { getEntry, getEntries, countEntries, createFormSubmission } from 'includio-cms/sveltekit/server';
2
+ import { resolveEntry, resolveEntries, countEntries, createFormSubmission } from 'includio-cms/sveltekit/server';
3
3
  export async function getSingleEntry(slug, options = {}) {
4
- return (await getEntry({
5
- slug,
4
+ return (await resolveEntry({
5
+ collection: slug,
6
6
  ...options
7
7
  }));
8
8
  }
9
9
  export async function getCollectionEntry(slug, options = {}) {
10
- return (await getEntry({
11
- slug,
10
+ return (await resolveEntry({
11
+ collection: slug,
12
12
  ...options
13
13
  }));
14
14
  }
15
15
  export async function getCollectionEntries(slug, options = {}) {
16
- return (await getEntries({ slug, ...options }));
16
+ return (await resolveEntries({ collection: slug, ...options }));
17
17
  }
18
18
  export async function countCollectionEntries(slug, options = {}) {
19
- return countEntries({ slug, ...options });
19
+ return countEntries({ collection: slug, ...options });
20
20
  }
21
21
  export async function submitForm(slug, data, options) {
22
22
  return createFormSubmission({ slug, data, ...options });
@@ -1,4 +1,4 @@
1
1
  import { Accordion as AccordionPrimitive } from "bits-ui";
2
- declare const Accordion: import("svelte").Component<AccordionPrimitive.RootProps, {}, "value" | "ref">;
2
+ declare const Accordion: import("svelte").Component<AccordionPrimitive.RootProps, {}, "ref" | "value">;
3
3
  type Accordion = ReturnType<typeof Accordion>;
4
4
  export default Accordion;
@@ -16,6 +16,6 @@ type $$ComponentProps = WithoutChildrenOrChild<CalendarPrimitive.RootProps> & {
16
16
  outsideMonth: boolean;
17
17
  }]>;
18
18
  };
19
- declare const Calendar: import("svelte").Component<$$ComponentProps, {}, "value" | "ref" | "placeholder">;
19
+ declare const Calendar: import("svelte").Component<$$ComponentProps, {}, "ref" | "value" | "placeholder">;
20
20
  type Calendar = ReturnType<typeof Calendar>;
21
21
  export default Calendar;
@@ -7,6 +7,6 @@ type $$ComponentProps = WithoutChildrenOrChild<DialogPrimitive.RootProps> & With
7
7
  title?: string;
8
8
  description?: string;
9
9
  };
10
- declare const CommandDialog: import("svelte").Component<$$ComponentProps, {}, "value" | "ref" | "open">;
10
+ declare const CommandDialog: import("svelte").Component<$$ComponentProps, {}, "ref" | "value" | "open">;
11
11
  type CommandDialog = ReturnType<typeof CommandDialog>;
12
12
  export default CommandDialog;
@@ -1,4 +1,4 @@
1
1
  import { Command as CommandPrimitive } from "bits-ui";
2
- declare const CommandInput: import("svelte").Component<CommandPrimitive.InputProps, {}, "value" | "ref">;
2
+ declare const CommandInput: import("svelte").Component<CommandPrimitive.InputProps, {}, "ref" | "value">;
3
3
  type CommandInput = ReturnType<typeof CommandInput>;
4
4
  export default CommandInput;
@@ -3,6 +3,6 @@ export type CommandRootApi = CommandPrimitive.Root;
3
3
  type $$ComponentProps = CommandPrimitive.RootProps & {
4
4
  api?: CommandRootApi | null;
5
5
  };
6
- declare const Command: import("svelte").Component<$$ComponentProps, {}, "value" | "ref" | "api">;
6
+ declare const Command: import("svelte").Component<$$ComponentProps, {}, "ref" | "value" | "api">;
7
7
  type Command = ReturnType<typeof Command>;
8
8
  export default Command;