includio-cms 0.7.1 → 0.13.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/CHANGELOG.md +117 -0
- package/ROADMAP.md +44 -2
- package/dist/admin/api/generate-styles.d.ts +2 -0
- package/dist/admin/api/generate-styles.js +32 -0
- package/dist/admin/api/handler.js +33 -0
- package/dist/admin/api/media-gc.js +10 -4
- package/dist/admin/api/rest/handler.js +17 -0
- package/dist/admin/api/rest/routes/collections.js +25 -13
- package/dist/admin/api/rest/routes/entries.d.ts +1 -1
- package/dist/admin/api/rest/routes/entries.js +10 -10
- package/dist/admin/api/rest/routes/media.d.ts +2 -0
- package/dist/admin/api/rest/routes/media.js +9 -0
- package/dist/admin/api/rest/routes/schema.d.ts +5 -0
- package/dist/admin/api/rest/routes/schema.js +152 -0
- package/dist/admin/api/rest/routes/singletons.d.ts +1 -1
- package/dist/admin/api/rest/routes/singletons.js +8 -7
- package/dist/admin/api/rest/routes/upload.d.ts +2 -0
- package/dist/admin/api/rest/routes/upload.js +28 -0
- package/dist/admin/api/upload.js +13 -0
- package/dist/admin/client/collection/collection-entries.svelte +19 -6
- package/dist/admin/client/entry/entry.svelte +21 -23
- package/dist/admin/client/entry/header/a11y-validator.js +2 -2
- package/dist/admin/client/entry/header/publish-panel.svelte +33 -85
- package/dist/admin/client/entry/header/status-badge.svelte +2 -2
- package/dist/admin/client/entry/header/version-history-sheet.svelte +9 -9
- package/dist/admin/client/entry/header/visibility.svelte +16 -10
- package/dist/admin/client/entry/utils.d.ts +3 -0
- package/dist/admin/client/entry/utils.js +22 -4
- package/dist/admin/client/form/form-submission/form-submission-page.svelte +4 -1
- package/dist/admin/client/form/form-submission/submission-field.svelte +10 -0
- package/dist/admin/client/index.d.ts +1 -0
- package/dist/admin/client/index.js +1 -0
- package/dist/admin/client/maintenance/maintenance-page.svelte +146 -2
- package/dist/admin/components/fields/blocks-field.svelte +9 -10
- package/dist/admin/components/fields/field-renderer.svelte +4 -8
- package/dist/admin/components/fields/object-field.svelte +7 -12
- package/dist/admin/components/fields/select-field.svelte +8 -2
- package/dist/admin/components/fields/seo-field.svelte +40 -93
- package/dist/admin/components/fields/simple-array-field.svelte +5 -5
- package/dist/admin/components/fields/text-field-wrapper.svelte +52 -197
- package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
- package/dist/admin/components/fields/url-field-wrapper.svelte +15 -25
- package/dist/admin/components/fields/url-field.svelte +61 -72
- package/dist/admin/components/media/file-upload.svelte +5 -1
- package/dist/admin/components/media/file-upload.svelte.d.ts +1 -0
- package/dist/admin/components/media/media-library.svelte +109 -37
- package/dist/admin/components/media/media-selector.svelte +79 -11
- package/dist/admin/components/media/tag-sidebar.svelte +10 -6
- package/dist/admin/components/media/tag-sidebar.svelte.d.ts +7 -2
- package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +21 -93
- package/dist/admin/components/tiptap/inline-block-node.js +6 -5
- package/dist/admin/components/tiptap/link-dialog.svelte +10 -11
- package/dist/admin/components/tiptap/slash-command.js +1 -1
- package/dist/admin/remote/entry.remote.d.ts +2 -5
- package/dist/admin/remote/entry.remote.js +22 -27
- package/dist/admin/remote/media.remote.d.ts +15 -0
- package/dist/admin/remote/media.remote.js +18 -2
- package/dist/admin/remote/preview.remote.js +3 -1
- package/dist/admin/utils/entryLabel.js +9 -6
- package/dist/admin/utils/translationStatus.js +1 -2
- package/dist/cli/create-user.d.ts +2 -0
- package/dist/cli/create-user.js +81 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/scaffold/admin.js +34 -2
- package/dist/cms/runtime/api.d.ts +16 -12
- package/dist/cms/runtime/api.js +7 -6
- package/dist/cms/runtime/remote.js +2 -2
- package/dist/cms/runtime/schemas.d.ts +1 -1
- package/dist/cms/runtime/schemas.js +1 -1
- package/dist/cms/runtime/types.d.ts +118 -112
- package/dist/cms/runtime/types.js +0 -12
- package/dist/core/cms.d.ts +3 -1
- package/dist/core/cms.js +30 -0
- package/dist/core/fields/fieldSchemaToTs.js +9 -15
- package/dist/core/fields/formFieldSchemaToTs.js +7 -0
- package/dist/core/server/entries/operations/create.js +10 -4
- package/dist/core/server/entries/operations/get.d.ts +1 -0
- package/dist/core/server/entries/operations/get.js +186 -191
- package/dist/core/server/entries/operations/update.d.ts +6 -7
- package/dist/core/server/entries/operations/update.js +20 -38
- package/dist/core/server/fields/populateEntry.js +16 -52
- package/dist/core/server/fields/resolveImageFields.js +69 -120
- package/dist/core/server/fields/resolveRelationFields.js +30 -51
- package/dist/core/server/fields/resolveRichtextLinks.js +46 -100
- package/dist/core/server/fields/resolveTypographyOrphans.bench.d.ts +1 -0
- package/dist/core/server/fields/resolveTypographyOrphans.bench.js +87 -0
- package/dist/core/server/fields/resolveTypographyOrphans.d.ts +3 -0
- package/dist/core/server/fields/resolveTypographyOrphans.js +128 -0
- package/dist/core/server/fields/resolveUrlFields.js +47 -56
- package/dist/core/server/fields/utils/fixOrphans.d.ts +5 -0
- package/dist/core/server/fields/utils/fixOrphans.js +12 -0
- package/dist/core/server/fields/utils/imageStyles.d.ts +4 -2
- package/dist/core/server/fields/utils/imageStyles.js +41 -25
- package/dist/core/server/fields/utils/resolveMedia.js +1 -6
- package/dist/core/server/forms/submissions/operations/delete.js +26 -2
- package/dist/core/server/forms/submissions/utils/parseMultipart.d.ts +2 -0
- package/dist/core/server/forms/submissions/utils/parseMultipart.js +75 -0
- package/dist/core/server/generator/fields.d.ts +6 -0
- package/dist/core/server/generator/fields.js +43 -5
- package/dist/core/server/generator/formFieldSchemaToString.js +10 -0
- package/dist/core/server/generator/formFields.js +1 -0
- package/dist/core/server/generator/generator.js +98 -30
- package/dist/core/server/media/operations/getFiles.d.ts +5 -0
- package/dist/core/server/media/operations/getFiles.js +6 -0
- package/dist/core/server/media/operations/uploadPrivateFile.d.ts +4 -0
- package/dist/core/server/media/operations/uploadPrivateFile.js +8 -0
- package/dist/core/server/media/styles/operations/batchGenerateStyles.d.ts +16 -0
- package/dist/core/server/media/styles/operations/batchGenerateStyles.js +144 -0
- package/dist/db-postgres/index.js +303 -37
- package/dist/db-postgres/schema/entry.d.ts +0 -94
- package/dist/db-postgres/schema/entry.js +0 -6
- package/dist/db-postgres/schema/entryVersion.d.ts +17 -0
- package/dist/db-postgres/schema/entryVersion.js +1 -0
- package/dist/entity/index.d.ts +9 -4
- package/dist/entity/index.js +24 -24
- package/dist/files-local/index.js +43 -0
- package/dist/sveltekit/components/preview.svelte +2 -326
- package/dist/sveltekit/components/preview.svelte.d.ts +5 -16
- package/dist/sveltekit/server/index.d.ts +2 -1
- package/dist/sveltekit/server/index.js +2 -1
- package/dist/sveltekit/server/preview.js +4 -7
- package/dist/types/adapters/db.d.ts +15 -1
- package/dist/types/adapters/files.d.ts +6 -0
- package/dist/types/cms.d.ts +5 -0
- package/dist/types/entries.d.ts +54 -18
- package/dist/types/fields.d.ts +14 -24
- package/dist/types/formFields.d.ts +7 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/structured-content.d.ts +5 -0
- package/dist/updates/0.10.0/index.d.ts +2 -0
- package/dist/updates/0.10.0/index.js +15 -0
- package/dist/updates/0.11.0/index.d.ts +2 -0
- package/dist/updates/0.11.0/index.js +12 -0
- package/dist/updates/0.12.0/index.d.ts +2 -0
- package/dist/updates/0.12.0/index.js +12 -0
- package/dist/updates/0.13.0/index.d.ts +2 -0
- package/dist/updates/0.13.0/index.js +10 -0
- package/dist/updates/0.7.2/index.d.ts +2 -0
- package/dist/updates/0.7.2/index.js +10 -0
- package/dist/updates/0.7.3/index.d.ts +2 -0
- package/dist/updates/0.7.3/index.js +10 -0
- package/dist/updates/0.8.0/index.d.ts +2 -0
- package/dist/updates/0.8.0/index.js +18 -0
- package/dist/updates/0.8.0/migrate.d.ts +2 -0
- package/dist/updates/0.8.0/migrate.js +101 -0
- package/dist/updates/0.9.0/index.d.ts +2 -0
- package/dist/updates/0.9.0/index.js +38 -0
- package/dist/updates/index.js +9 -1
- package/package.json +7 -6
- package/dist/admin/components/fields/image-field.svelte +0 -198
- package/dist/admin/components/fields/image-field.svelte.d.ts +0 -8
- package/dist/admin/components/fields/richtext-field.svelte +0 -13
- package/dist/admin/components/fields/richtext-field.svelte.d.ts +0 -8
- package/dist/admin/components/tiptap.svelte +0 -11
- package/dist/admin/components/tiptap.svelte.d.ts +0 -6
- package/dist/core/server/entries/utils/getEntryTranslation.d.ts +0 -1
- package/dist/core/server/entries/utils/getEntryTranslation.js +0 -18
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ConsentLogData } from '../consent.js';
|
|
2
|
-
import type { DbEntry, DbEntryInsert, DbEntryVersion, DbEntryVersionInsert, GetDbEntriesOptions, GetDbEntryVersionsOptions, PaginationOptions } from '../entries.js';
|
|
2
|
+
import type { DbEntry, DbEntryInsert, DbEntryVersion, DbEntryVersionInsert, GetDbEntriesOptions, GetDbEntryVersionsOptions, GetPaginatedEntriesOptions, PaginatedEntryRow, PaginationOptions } from '../entries.js';
|
|
3
3
|
import type { ImageFieldStyle } from '../fields.js';
|
|
4
4
|
import type { FormSubmission } from '../forms.js';
|
|
5
5
|
import type { ImageStyle, MediaFile, MediaTag, UploadedMediaFile } from '../media.js';
|
|
@@ -20,6 +20,8 @@ export interface DatabaseAdapter {
|
|
|
20
20
|
getFormSubmission: GetFormSubmission;
|
|
21
21
|
updateFormSubmission: UpdateFormSubmission;
|
|
22
22
|
deleteFormSubmission: DeleteFormSubmission;
|
|
23
|
+
getPaginatedEntries?: GetPaginatedEntries;
|
|
24
|
+
countPaginatedEntries?: CountPaginatedEntries;
|
|
23
25
|
createConsentLog: CreateConsentLog;
|
|
24
26
|
getMediaTags: GetMediaTags;
|
|
25
27
|
createMediaTag: CreateMediaTag;
|
|
@@ -35,6 +37,8 @@ export interface DatabaseAdapter {
|
|
|
35
37
|
getAllImageStyles: GetAllImageStyles;
|
|
36
38
|
deleteAllImageStyles: DeleteAllImageStyles;
|
|
37
39
|
getMediaFiles: GetMediaFiles;
|
|
40
|
+
countMediaFiles: CountMediaFiles;
|
|
41
|
+
getMediaTagsWithCounts: GetMediaTagsWithCounts;
|
|
38
42
|
getMediaFile: GetMediaFile;
|
|
39
43
|
updateMediaFile: UpdateMediaFile;
|
|
40
44
|
deleteMediaFile: DeleteMediaFile;
|
|
@@ -49,6 +53,8 @@ export type UpdateEntry = (data: {
|
|
|
49
53
|
export type DeleteEntry = (data: {
|
|
50
54
|
id: string;
|
|
51
55
|
}) => Promise<void>;
|
|
56
|
+
export type GetPaginatedEntries = (data: GetPaginatedEntriesOptions) => Promise<PaginatedEntryRow[]>;
|
|
57
|
+
export type CountPaginatedEntries = (data: Omit<GetPaginatedEntriesOptions, 'limit' | 'offset' | 'orderBy'>) => Promise<number>;
|
|
52
58
|
export type ArchiveEntry = (data: {
|
|
53
59
|
id: string;
|
|
54
60
|
archivedAt?: Date;
|
|
@@ -80,9 +86,17 @@ export interface GetMediaFilesOptions {
|
|
|
80
86
|
ids?: string[];
|
|
81
87
|
mimeTypes?: string[];
|
|
82
88
|
search?: string;
|
|
89
|
+
untagged?: boolean;
|
|
90
|
+
limit?: number;
|
|
91
|
+
offset?: number;
|
|
83
92
|
};
|
|
84
93
|
}
|
|
85
94
|
export type GetMediaFiles = (data: GetMediaFilesOptions) => Promise<MediaFile[]>;
|
|
95
|
+
export type CountMediaFiles = (data: GetMediaFilesOptions) => Promise<number>;
|
|
96
|
+
export type GetMediaTagsWithCounts = () => Promise<{
|
|
97
|
+
tag: MediaTag;
|
|
98
|
+
count: number;
|
|
99
|
+
}[]>;
|
|
86
100
|
export interface GetMediaFileOptions {
|
|
87
101
|
data: {
|
|
88
102
|
id?: string;
|
|
@@ -5,6 +5,12 @@ export interface FilesAdapter {
|
|
|
5
5
|
renameFile: RenameFile;
|
|
6
6
|
deleteFile: DeleteFile;
|
|
7
7
|
listFiles: ListFiles;
|
|
8
|
+
uploadPrivateFile?: (file: File) => Promise<{
|
|
9
|
+
filename: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}>;
|
|
12
|
+
downloadPrivateFile?: (filename: string) => Promise<File | null>;
|
|
13
|
+
deletePrivateFile?: (filename: string) => Promise<void>;
|
|
8
14
|
}
|
|
9
15
|
export type DownloadFile = (id: string) => Promise<File | null>;
|
|
10
16
|
export type UploadFile = (file: File) => Promise<UploadedMediaFile>;
|
package/dist/types/cms.d.ts
CHANGED
|
@@ -36,6 +36,9 @@ export interface ApiKeyConfig {
|
|
|
36
36
|
name?: string;
|
|
37
37
|
role?: 'admin' | 'editor';
|
|
38
38
|
}
|
|
39
|
+
export interface TypographyConfig {
|
|
40
|
+
fixOrphans?: boolean;
|
|
41
|
+
}
|
|
39
42
|
export interface CMSConfig {
|
|
40
43
|
languages: Language[];
|
|
41
44
|
collections?: CollectionConfig[];
|
|
@@ -49,6 +52,7 @@ export interface CMSConfig {
|
|
|
49
52
|
ai?: AIAdapter;
|
|
50
53
|
media?: MediaConfig;
|
|
51
54
|
apiKeys?: ApiKeyConfig[];
|
|
55
|
+
typography?: TypographyConfig;
|
|
52
56
|
}
|
|
53
57
|
export interface ICMS {
|
|
54
58
|
collections: Record<string, CollectionConfigWithType>;
|
|
@@ -64,4 +68,5 @@ export interface ICMS {
|
|
|
64
68
|
aiAdapter: AIAdapter | null;
|
|
65
69
|
mediaConfig: MediaConfig;
|
|
66
70
|
apiKeys: ApiKeyConfig[];
|
|
71
|
+
typographyConfig: TypographyConfig;
|
|
67
72
|
}
|
package/dist/types/entries.d.ts
CHANGED
|
@@ -12,44 +12,40 @@ export interface DbEntry {
|
|
|
12
12
|
id: string;
|
|
13
13
|
slug: string;
|
|
14
14
|
type: EntryType;
|
|
15
|
-
availableLocales: string[] | null;
|
|
16
15
|
createdAt: Date;
|
|
17
16
|
updatedAt: Date;
|
|
18
17
|
archivedAt: Date | null;
|
|
19
|
-
publishedAt: Date | null;
|
|
20
|
-
publishedVersionId: string | null;
|
|
21
|
-
publishedBy: string | null;
|
|
22
18
|
sortOrder: number | null;
|
|
23
19
|
}
|
|
24
20
|
export interface DbEntryInsert {
|
|
25
21
|
slug: string;
|
|
26
22
|
type: EntryType;
|
|
27
|
-
availableLocales?: string[] | null;
|
|
28
23
|
createdAt?: Date;
|
|
29
24
|
updatedAt?: Date;
|
|
30
25
|
archivedAt?: Date | null;
|
|
31
|
-
publishedAt?: Date | null;
|
|
32
|
-
publishedVersionId?: string | null;
|
|
33
|
-
publishedBy?: string | null;
|
|
34
26
|
sortOrder?: number | null;
|
|
35
27
|
}
|
|
36
28
|
export interface RawEntry extends DbEntry {
|
|
37
29
|
collection: CollectionConfigWithType | SingleConfigWithType;
|
|
38
30
|
versions: DbEntryVersion[];
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
data: PopulatedEntryData;
|
|
46
|
-
slug: string;
|
|
47
|
-
type: EntryType;
|
|
48
|
-
publishedAt?: Date | null;
|
|
31
|
+
/** Per-language published versions */
|
|
32
|
+
publishedVersions: Record<string, DbEntryVersion | null>;
|
|
33
|
+
/** Per-language scheduled versions */
|
|
34
|
+
scheduledVersions: Record<string, DbEntryVersion | null>;
|
|
35
|
+
/** Per-language latest draft versions */
|
|
36
|
+
draftVersions: Record<string, DbEntryVersion | null>;
|
|
49
37
|
}
|
|
38
|
+
export type Entry = {
|
|
39
|
+
_id: string;
|
|
40
|
+
_slug: string;
|
|
41
|
+
_type: EntryType;
|
|
42
|
+
_publishedAt?: Date | null;
|
|
43
|
+
_url?: string;
|
|
44
|
+
} & Record<string, unknown>;
|
|
50
45
|
export interface DbEntryVersion {
|
|
51
46
|
id: string;
|
|
52
47
|
entryId: string;
|
|
48
|
+
lang: string;
|
|
53
49
|
versionNumber: number;
|
|
54
50
|
data: EntryData;
|
|
55
51
|
createdAt: Date;
|
|
@@ -59,6 +55,7 @@ export interface DbEntryVersion {
|
|
|
59
55
|
}
|
|
60
56
|
export interface DbEntryVersionInsert {
|
|
61
57
|
entryId: string;
|
|
58
|
+
lang: string;
|
|
62
59
|
versionNumber?: number;
|
|
63
60
|
data: EntryData;
|
|
64
61
|
createdAt?: Date;
|
|
@@ -73,6 +70,10 @@ export interface PaginationOptions {
|
|
|
73
70
|
column: 'createdAt' | 'updatedAt' | 'sortOrder';
|
|
74
71
|
direction: 'asc' | 'desc';
|
|
75
72
|
};
|
|
73
|
+
dataOrderBy?: {
|
|
74
|
+
field: string;
|
|
75
|
+
direction: 'asc' | 'desc';
|
|
76
|
+
};
|
|
76
77
|
}
|
|
77
78
|
export interface GetDbEntriesOptions extends PaginationOptions {
|
|
78
79
|
ids?: string[];
|
|
@@ -103,30 +104,65 @@ export interface GetEntriesOptions {
|
|
|
103
104
|
slug?: string;
|
|
104
105
|
dataValues?: Record<string, unknown>;
|
|
105
106
|
dataLike?: Record<string, unknown>;
|
|
107
|
+
dataILikeOr?: Record<string, unknown>;
|
|
106
108
|
language?: string;
|
|
107
109
|
status?: EntryStatus;
|
|
108
110
|
orderBy?: {
|
|
109
111
|
column: 'createdAt' | 'updatedAt' | 'sortOrder';
|
|
110
112
|
direction: 'asc' | 'desc';
|
|
111
113
|
};
|
|
114
|
+
dataOrderBy?: {
|
|
115
|
+
field: string;
|
|
116
|
+
direction: 'asc' | 'desc';
|
|
117
|
+
};
|
|
118
|
+
limit?: number;
|
|
119
|
+
offset?: number;
|
|
112
120
|
}
|
|
113
121
|
export interface GetEntryOptions {
|
|
114
122
|
id?: string;
|
|
115
123
|
slug?: string;
|
|
116
124
|
dataValues?: Record<string, unknown>;
|
|
117
125
|
dataLike?: Record<string, unknown>;
|
|
126
|
+
dataILikeOr?: Record<string, unknown>;
|
|
118
127
|
language?: string;
|
|
119
128
|
status?: EntryStatus;
|
|
120
129
|
}
|
|
121
130
|
export interface GetDbEntryVersionsOptions {
|
|
122
131
|
ids?: string[];
|
|
123
132
|
entryIds?: string[];
|
|
133
|
+
lang?: string;
|
|
124
134
|
dataValues?: Record<string, unknown>;
|
|
125
135
|
dataLike?: Record<string, unknown>;
|
|
136
|
+
dataILikeOr?: Record<string, unknown>;
|
|
126
137
|
}
|
|
127
138
|
export interface GetDbEntryVersionOptions {
|
|
128
139
|
id?: string;
|
|
129
140
|
entryId?: string;
|
|
141
|
+
lang?: string;
|
|
130
142
|
dataValues?: Record<string, unknown>;
|
|
131
143
|
dataLike?: Record<string, unknown>;
|
|
144
|
+
dataILikeOr?: Record<string, unknown>;
|
|
145
|
+
}
|
|
146
|
+
export interface GetPaginatedEntriesOptions {
|
|
147
|
+
slug?: string;
|
|
148
|
+
ids?: string[];
|
|
149
|
+
language: string;
|
|
150
|
+
status: EntryStatus;
|
|
151
|
+
dataValues?: Record<string, unknown>;
|
|
152
|
+
dataLike?: Record<string, unknown>;
|
|
153
|
+
dataILikeOr?: Record<string, unknown>;
|
|
154
|
+
orderBy?: {
|
|
155
|
+
column: 'createdAt' | 'updatedAt' | 'sortOrder';
|
|
156
|
+
direction: 'asc' | 'desc';
|
|
157
|
+
};
|
|
158
|
+
dataOrderBy?: {
|
|
159
|
+
field: string;
|
|
160
|
+
direction: 'asc' | 'desc';
|
|
161
|
+
};
|
|
162
|
+
limit: number;
|
|
163
|
+
offset: number;
|
|
164
|
+
}
|
|
165
|
+
export interface PaginatedEntryRow {
|
|
166
|
+
entry: DbEntry;
|
|
167
|
+
version: DbEntryVersion;
|
|
132
168
|
}
|
package/dist/types/fields.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { FormatEnum } from 'sharp';
|
|
|
2
2
|
import type { ImageStyle, MediaFile } from './media.js';
|
|
3
3
|
import type { Localized } from './languages.js';
|
|
4
4
|
import type { StructuredContentDoc } from './structured-content.js';
|
|
5
|
-
export type FieldType = 'text' | '
|
|
5
|
+
export type FieldType = 'text' | 'content' | 'number' | 'boolean' | 'date' | 'datetime' | 'file' | 'media' | 'select' | 'radio' | 'checkboxes' | 'relation' | 'object' | 'array' | 'blocks' | 'slug' | 'seo' | 'url' | 'custom';
|
|
6
6
|
export interface FieldCondition {
|
|
7
7
|
field: string;
|
|
8
8
|
equals?: string | string[];
|
|
@@ -26,12 +26,6 @@ export interface TextField extends BaseField {
|
|
|
26
26
|
multiline?: boolean;
|
|
27
27
|
defaultValue?: string;
|
|
28
28
|
}
|
|
29
|
-
export interface RichtextField extends BaseField {
|
|
30
|
-
type: 'richtext';
|
|
31
|
-
allowedTags?: string[];
|
|
32
|
-
allowedFormats?: string[];
|
|
33
|
-
defaultValue?: string;
|
|
34
|
-
}
|
|
35
29
|
export interface ContentField extends BaseField {
|
|
36
30
|
type: 'content';
|
|
37
31
|
inlineBlocks?: ObjectField[];
|
|
@@ -67,18 +61,6 @@ export interface FileField extends BaseField {
|
|
|
67
61
|
multiple?: boolean;
|
|
68
62
|
defaultValue?: string | string[];
|
|
69
63
|
}
|
|
70
|
-
export interface ImageField extends BaseField {
|
|
71
|
-
type: 'image';
|
|
72
|
-
accept?: string;
|
|
73
|
-
maxSizeMB?: number;
|
|
74
|
-
multiple?: boolean;
|
|
75
|
-
width?: number;
|
|
76
|
-
height?: number;
|
|
77
|
-
aspectRatio?: number;
|
|
78
|
-
thumbnail?: boolean;
|
|
79
|
-
defaultValue?: string | string[];
|
|
80
|
-
styles?: ImageFieldStyle[];
|
|
81
|
-
}
|
|
82
64
|
export interface ImageFieldStyle {
|
|
83
65
|
name: string;
|
|
84
66
|
width?: number;
|
|
@@ -109,6 +91,15 @@ export interface VideoFieldData {
|
|
|
109
91
|
audioDescription: MediaFile | null;
|
|
110
92
|
}
|
|
111
93
|
export type MediaFieldData = ImageFieldData | VideoFieldData;
|
|
94
|
+
export type FlatImageFieldData = MediaFile & {
|
|
95
|
+
_styles: Record<string, ImageStyle>;
|
|
96
|
+
_blurDataUrl?: string | null;
|
|
97
|
+
};
|
|
98
|
+
export type FlatVideoFieldData = MediaFile & {
|
|
99
|
+
_transcript: MediaFile | null;
|
|
100
|
+
_audioDescription: MediaFile | null;
|
|
101
|
+
};
|
|
102
|
+
export type FlatMediaFieldData = FlatImageFieldData | FlatVideoFieldData;
|
|
112
103
|
export interface SelectField extends BaseField {
|
|
113
104
|
type: 'select';
|
|
114
105
|
options: {
|
|
@@ -149,11 +140,10 @@ export interface ObjectField extends BaseField {
|
|
|
149
140
|
defaultValue?: ObjectFieldData;
|
|
150
141
|
thumbnail?: string;
|
|
151
142
|
}
|
|
152
|
-
export
|
|
143
|
+
export type ObjectFieldData = {
|
|
153
144
|
_id?: string;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
145
|
+
_slug?: string;
|
|
146
|
+
} & Record<string, unknown>;
|
|
157
147
|
export type SimpleArrayItemType = 'text' | 'number' | 'url';
|
|
158
148
|
export interface ArrayField extends BaseField {
|
|
159
149
|
type: 'array';
|
|
@@ -211,4 +201,4 @@ export interface CustomField extends BaseField {
|
|
|
211
201
|
/** Plugin-specific configuration, opaque to core */
|
|
212
202
|
config?: Record<string, unknown>;
|
|
213
203
|
}
|
|
214
|
-
export type Field = TextField |
|
|
204
|
+
export type Field = TextField | ContentField | NumberField | BooleanField | DateField | DateTimeField | FileField | MediaField | SelectField | RadioField | CheckboxesField | RelationField | ObjectField | ArrayField | BlocksField | SlugField | SeoField | UrlField | CustomField;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Localized } from './languages.js';
|
|
2
|
-
export type FormFieldType = 'text' | 'email' | 'textarea' | 'checkbox' | 'select';
|
|
2
|
+
export type FormFieldType = 'text' | 'email' | 'textarea' | 'checkbox' | 'select' | 'file';
|
|
3
3
|
export interface FormBaseField {
|
|
4
4
|
slug: string;
|
|
5
5
|
label?: Localized;
|
|
@@ -37,4 +37,9 @@ export interface FormSelectField extends FormBaseField {
|
|
|
37
37
|
}[];
|
|
38
38
|
defaultValue?: string;
|
|
39
39
|
}
|
|
40
|
-
export
|
|
40
|
+
export interface FormFileField extends FormBaseField {
|
|
41
|
+
type: 'file';
|
|
42
|
+
accept?: string;
|
|
43
|
+
maxSize?: number;
|
|
44
|
+
}
|
|
45
|
+
export type FormField = FormTextField | FormEmailField | FormTextareaField | FormCheckboxField | FormSelectField | FormFileField;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from './fields.js';
|
|
2
|
-
export { type StructuredContentDoc, type SCNode, type SCMark, type SCInlineBlockAttrs, type SCFigureAttrs, type SCVideoAttrs } from './structured-content.js';
|
|
2
|
+
export { type StructuredContentDoc, type SCNode, type SCMark, type SCInlineBlockAttrs, type SCTypedInlineBlock, type SCFigureAttrs, type SCVideoAttrs } from './structured-content.js';
|
|
3
3
|
export { type MediaFile, type MediaFileType, type ImageStyle, type MediaTag } from './media.js';
|
|
4
4
|
export { type ConsentLogData } from './consent.js';
|
|
5
5
|
export { type Entry, type EntryType, type EntryStatus, type EntryVersionStatus } from './entries.js';
|
|
@@ -9,7 +9,7 @@ export { type CollectionConfig } from './collections.js';
|
|
|
9
9
|
export { type SingleConfig } from './singles.js';
|
|
10
10
|
export { type FormConfig, type FormSubmission } from './forms.js';
|
|
11
11
|
export { type FormField, type FormFieldType, type FormBaseField, type FormTextField, type FormEmailField, type FormTextareaField, type FormCheckboxField, type FormSelectField } from './formFields.js';
|
|
12
|
-
export { type CMSConfig, type ApiKeyConfig, type AuthConfig } from './cms.js';
|
|
12
|
+
export { type CMSConfig, type ApiKeyConfig, type AuthConfig, type TypographyConfig } from './cms.js';
|
|
13
13
|
export { type PluginConfig, type CustomFieldDefinition } from './plugins.js';
|
|
14
14
|
export { type Language, type Localized } from './languages.js';
|
|
15
15
|
export { type Layout, type LayoutNode, type LayoutPreset, type LayoutNodeType, type ColumnRatio, type SectionNode, type ColumnsNode, type CardNode, type AccordionNode, type StackNode } from './layout.js';
|
|
@@ -57,6 +57,11 @@ export interface SCInlineBlockAttrs {
|
|
|
57
57
|
blockData: Record<string, unknown>;
|
|
58
58
|
blockId: string;
|
|
59
59
|
}
|
|
60
|
+
export interface SCTypedInlineBlock<T = Record<string, unknown>> {
|
|
61
|
+
blockType: string;
|
|
62
|
+
blockData: T;
|
|
63
|
+
blockId: string;
|
|
64
|
+
}
|
|
60
65
|
export interface StructuredContentDoc {
|
|
61
66
|
type: 'doc';
|
|
62
67
|
content: SCNode[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.10.0',
|
|
3
|
+
date: '2026-03-18',
|
|
4
|
+
description: 'Remove image, video, richtext field types — consolidate to media and content',
|
|
5
|
+
features: [],
|
|
6
|
+
fixes: [],
|
|
7
|
+
breakingChanges: [
|
|
8
|
+
'Removed `image` field type — use `media` with `accept: "image/*"` instead',
|
|
9
|
+
'Removed `richtext` field type — use `content` (structured ProseMirror JSON) instead',
|
|
10
|
+
'Removed `ImageField` and `RichtextField` TypeScript interfaces',
|
|
11
|
+
'`image-field.svelte` and `richtext-field.svelte` components removed',
|
|
12
|
+
'`tiptap.svelte` (HTML richtext wrapper) removed'
|
|
13
|
+
],
|
|
14
|
+
notes: 'No automatic data migration. Replace `type: "image"` with `type: "media", accept: "image/*"` in your collection/singleton configs. Replace `type: "richtext"` with `type: "content"`. Existing stored data (media UUIDs, ProseMirror docs) remains compatible.'
|
|
15
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.11.0',
|
|
3
|
+
date: '2026-03-18',
|
|
4
|
+
description: 'Codegen overhaul and REST API consolidation',
|
|
5
|
+
features: [
|
|
6
|
+
'Codegen: flat entry types, inline block types, `countEntries` query helper, simplified API surface',
|
|
7
|
+
'REST API: catch-all route handler, file upload endpoint, media endpoint, schema template endpoints',
|
|
8
|
+
'Admin scaffold updated for new REST route structure'
|
|
9
|
+
],
|
|
10
|
+
fixes: [],
|
|
11
|
+
breakingChanges: []
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.12.0',
|
|
3
|
+
date: '2026-03-18',
|
|
4
|
+
description: 'File field type, dataOrderBy, and _url population',
|
|
5
|
+
features: [
|
|
6
|
+
'File field type with multipart upload, file validation, and rate limiting',
|
|
7
|
+
'`dataOrderBy` — sort entries by JSON data fields in queries',
|
|
8
|
+
'Auto-populate `_url` field on entries from slug resolver and `pathTemplate`'
|
|
9
|
+
],
|
|
10
|
+
fixes: [],
|
|
11
|
+
breakingChanges: []
|
|
12
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.13.0',
|
|
3
|
+
date: '2026-03-19',
|
|
4
|
+
description: 'Private file uploads for form submissions',
|
|
5
|
+
features: [
|
|
6
|
+
'Private file uploads — form submissions can upload files to a non-public directory with access control'
|
|
7
|
+
],
|
|
8
|
+
fixes: [],
|
|
9
|
+
breakingChanges: []
|
|
10
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.7.2',
|
|
3
|
+
date: '2026-03-16',
|
|
4
|
+
description: 'CLI create-user command',
|
|
5
|
+
features: [
|
|
6
|
+
'CLI `create-user` command — interactive user creation with email, password (auto-generate option), name, and role via better-auth'
|
|
7
|
+
],
|
|
8
|
+
fixes: [],
|
|
9
|
+
breakingChanges: []
|
|
10
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.7.3',
|
|
3
|
+
date: '2026-03-17',
|
|
4
|
+
description: 'Typography orphan fix for Polish conjunctions',
|
|
5
|
+
features: [
|
|
6
|
+
'Read-time orphan fix — replace space after single-letter Polish conjunctions (i, w, z, o, u, a) with non-breaking space `\\u00A0`'
|
|
7
|
+
],
|
|
8
|
+
fixes: [],
|
|
9
|
+
breakingChanges: []
|
|
10
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.8.0',
|
|
3
|
+
date: '2026-03-17',
|
|
4
|
+
description: 'Flat entry format — remove data wrapper from objects/blocks',
|
|
5
|
+
features: [
|
|
6
|
+
'Flat entry format: objects use `_slug` + spread fields instead of `slug` + `data` wrapper',
|
|
7
|
+
'Blocks use `_slug` instead of `slug` with flat fields',
|
|
8
|
+
'Entry type unified: `FlatEntry` renamed to `Entry`, old `Entry` removed'
|
|
9
|
+
],
|
|
10
|
+
fixes: [],
|
|
11
|
+
breakingChanges: [
|
|
12
|
+
'Object field data format: `{ slug, data: {...} }` → `{ _slug, ...fields }`',
|
|
13
|
+
'Blocks field data format: `{ _id, slug, data: {...} }` → `{ _id, _slug, ...fields }`',
|
|
14
|
+
'`FlatEntry` type removed — use `Entry` instead',
|
|
15
|
+
'`flattenEntry`/`flattenFields` removed — data is flat from resolve functions'
|
|
16
|
+
],
|
|
17
|
+
notes: 'Run `includio update` to migrate existing entry data in the database.'
|
|
18
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate entry version data from wrapped format to flat format.
|
|
3
|
+
*
|
|
4
|
+
* Objects: { slug, data: {...} } → { _slug, ...fields }
|
|
5
|
+
* Blocks: [{ _id, slug, data: {...} }] → [{ _id, _slug, ...fields }]
|
|
6
|
+
* Content inline blocks: blockData with nested objects/blocks also transformed.
|
|
7
|
+
*/
|
|
8
|
+
function isWrappedObject(val) {
|
|
9
|
+
return (val != null &&
|
|
10
|
+
typeof val === 'object' &&
|
|
11
|
+
'slug' in val &&
|
|
12
|
+
'data' in val &&
|
|
13
|
+
typeof val.slug === 'string' &&
|
|
14
|
+
typeof val.data === 'object' &&
|
|
15
|
+
val.data !== null);
|
|
16
|
+
}
|
|
17
|
+
function migrateValue(val) {
|
|
18
|
+
if (val == null)
|
|
19
|
+
return val;
|
|
20
|
+
if (Array.isArray(val)) {
|
|
21
|
+
return val.map((item) => {
|
|
22
|
+
if (isWrappedObject(item)) {
|
|
23
|
+
const { slug, data, _id, ...rest } = item;
|
|
24
|
+
const flatData = migrateRecord(data);
|
|
25
|
+
return {
|
|
26
|
+
...rest,
|
|
27
|
+
...(_id != null ? { _id } : {}),
|
|
28
|
+
_slug: slug,
|
|
29
|
+
...flatData
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return migrateValue(item);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (typeof val === 'object') {
|
|
36
|
+
// Check if this is a wrapped object (not an array)
|
|
37
|
+
if (isWrappedObject(val)) {
|
|
38
|
+
const { slug, data, _id, ...rest } = val;
|
|
39
|
+
const flatData = migrateRecord(data);
|
|
40
|
+
return {
|
|
41
|
+
...rest,
|
|
42
|
+
...(_id != null ? { _id } : {}),
|
|
43
|
+
_slug: slug,
|
|
44
|
+
...flatData
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Check if this is a structured content doc — recurse into inline blocks
|
|
48
|
+
if ('type' in val && val.type === 'doc') {
|
|
49
|
+
return migrateStructuredDoc(val);
|
|
50
|
+
}
|
|
51
|
+
// Generic object — recurse into values
|
|
52
|
+
return migrateRecord(val);
|
|
53
|
+
}
|
|
54
|
+
return val;
|
|
55
|
+
}
|
|
56
|
+
function migrateRecord(record) {
|
|
57
|
+
const result = {};
|
|
58
|
+
for (const [key, value] of Object.entries(record)) {
|
|
59
|
+
result[key] = migrateValue(value);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
function migrateStructuredDoc(doc) {
|
|
64
|
+
if (!doc.content || !Array.isArray(doc.content))
|
|
65
|
+
return doc;
|
|
66
|
+
return {
|
|
67
|
+
...doc,
|
|
68
|
+
content: doc.content.map((node) => {
|
|
69
|
+
if (node.type === 'inlineBlock' && node.attrs) {
|
|
70
|
+
const attrs = { ...node.attrs };
|
|
71
|
+
if (attrs.blockData && typeof attrs.blockData === 'object') {
|
|
72
|
+
attrs.blockData = migrateRecord(attrs.blockData);
|
|
73
|
+
}
|
|
74
|
+
return { ...node, attrs };
|
|
75
|
+
}
|
|
76
|
+
// Recurse into child content
|
|
77
|
+
if (node.content && Array.isArray(node.content)) {
|
|
78
|
+
return migrateStructuredDoc(node);
|
|
79
|
+
}
|
|
80
|
+
return node;
|
|
81
|
+
})
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export async function migrateEntryData(db) {
|
|
85
|
+
// Get all entries
|
|
86
|
+
const entries = await db.getEntries({});
|
|
87
|
+
let migratedCount = 0;
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const versions = await db.getEntryVersions({ entryIds: [entry.id] });
|
|
90
|
+
for (const version of versions) {
|
|
91
|
+
const originalData = version.data;
|
|
92
|
+
const migratedData = migrateRecord(originalData);
|
|
93
|
+
// Only update if data actually changed
|
|
94
|
+
if (JSON.stringify(originalData) !== JSON.stringify(migratedData)) {
|
|
95
|
+
await db.updateEntryVersion(version.id, { data: migratedData });
|
|
96
|
+
migratedCount++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return migratedCount;
|
|
101
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.9.0',
|
|
3
|
+
date: '2026-03-17',
|
|
4
|
+
description: 'Per-language entry versions — separate entry_version per language',
|
|
5
|
+
features: [
|
|
6
|
+
'Per-language entry versions: each language gets its own entry_version with flat data',
|
|
7
|
+
'Per-language publication: publish/unpublish each language independently',
|
|
8
|
+
'Simplified data format: no more nested `{ pl: "X", en: "Y" }` — values are flat strings',
|
|
9
|
+
'Language switching in admin loads different version data'
|
|
10
|
+
],
|
|
11
|
+
fixes: [],
|
|
12
|
+
breakingChanges: [
|
|
13
|
+
'`entry_version` table: new `lang` column (NOT NULL)',
|
|
14
|
+
'`entry` table: removed `published_at`, `published_version_id`, `published_by`, `available_locales` columns',
|
|
15
|
+
'`RawEntry`: `publishedVersion`/`draftVersion`/`scheduledVersion` replaced with per-lang `publishedVersions`/`draftVersions`/`scheduledVersions` records',
|
|
16
|
+
'`DbEntryVersion`/`DbEntryVersionInsert`: new required `lang` field',
|
|
17
|
+
'`translateObject` removed — data is single-language per version',
|
|
18
|
+
'Resolve functions (relation, media, url, richtext) expect flat content/richtext values, not `Record<lang, value>`',
|
|
19
|
+
'`upsertDraftVersion` and `pruneOldDraftVersions` now require `lang` parameter',
|
|
20
|
+
'`unpublishEntry` renamed to `unpublishEntryLang` with required `lang` parameter'
|
|
21
|
+
],
|
|
22
|
+
sql: `-- Step 1: Add lang column as nullable
|
|
23
|
+
ALTER TABLE entry_version ADD COLUMN lang TEXT;
|
|
24
|
+
|
|
25
|
+
-- Step 2: Run migration script to split multi-lang versions (scripts/migrate-lang-versions.ts)
|
|
26
|
+
-- After migration, set NOT NULL:
|
|
27
|
+
ALTER TABLE entry_version ALTER COLUMN lang SET NOT NULL;
|
|
28
|
+
|
|
29
|
+
-- Step 3: Create index for performance
|
|
30
|
+
CREATE INDEX idx_entry_version_publish ON entry_version(entry_id, lang, published_at);
|
|
31
|
+
|
|
32
|
+
-- Step 4: Remove entry-level publish columns
|
|
33
|
+
ALTER TABLE entry DROP COLUMN IF EXISTS published_at;
|
|
34
|
+
ALTER TABLE entry DROP COLUMN IF EXISTS published_version_id;
|
|
35
|
+
ALTER TABLE entry DROP COLUMN IF EXISTS published_by;
|
|
36
|
+
ALTER TABLE entry DROP COLUMN IF EXISTS available_locales;`,
|
|
37
|
+
notes: 'Run the migration script BEFORE setting lang to NOT NULL. See scripts/migrate-lang-versions.ts for data migration.'
|
|
38
|
+
};
|
package/dist/updates/index.js
CHANGED
|
@@ -25,7 +25,15 @@ import { update as update061 } from './0.6.1/index.js';
|
|
|
25
25
|
import { update as update062 } from './0.6.2/index.js';
|
|
26
26
|
import { update as update070 } from './0.7.0/index.js';
|
|
27
27
|
import { update as update071 } from './0.7.1/index.js';
|
|
28
|
-
|
|
28
|
+
import { update as update072 } from './0.7.2/index.js';
|
|
29
|
+
import { update as update073 } from './0.7.3/index.js';
|
|
30
|
+
import { update as update080 } from './0.8.0/index.js';
|
|
31
|
+
import { update as update090 } from './0.9.0/index.js';
|
|
32
|
+
import { update as update0100 } from './0.10.0/index.js';
|
|
33
|
+
import { update as update0110 } from './0.11.0/index.js';
|
|
34
|
+
import { update as update0120 } from './0.12.0/index.js';
|
|
35
|
+
import { update as update0130 } from './0.13.0/index.js';
|
|
36
|
+
export const updates = [update0065, update0066, update0067, update0068, update0069, update010, update011, update012, update013, update014, update015, update020, update022, update050, update051, update052, update053, update054, update055, update056, update057, update058, update060, update061, update062, update070, update071, update072, update073, update080, update090, update0100, update0110, update0120, update0130];
|
|
29
37
|
export const getUpdatesFrom = (fromVersion) => {
|
|
30
38
|
const fromParts = fromVersion.split('.').map(Number);
|
|
31
39
|
return updates.filter((update) => {
|