includio-cms 0.13.2 → 0.13.3
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 +20 -0
- package/ROADMAP.md +12 -2
- package/dist/admin/api/replace.js +4 -0
- package/dist/admin/api/rest/middleware/apiKey.js +7 -1
- package/dist/admin/api/upload.js +4 -0
- package/dist/admin/client/collection/collection-entries.svelte +8 -4
- package/dist/admin/client/collection/grid-view.svelte +1 -1
- package/dist/admin/client/entry/entry-header.svelte +37 -44
- package/dist/admin/client/entry/entry-header.svelte.d.ts +1 -2
- package/dist/admin/client/entry/entry-version.svelte +9 -3
- package/dist/admin/client/entry/entry.svelte +20 -1
- package/dist/admin/components/fields/seo-field.svelte +30 -16
- package/dist/admin/remote/entry.remote.js +3 -4
- package/dist/admin/state/content-language.svelte.d.ts +0 -3
- package/dist/admin/state/content-language.svelte.js +7 -11
- package/dist/admin/utils/entryLabel.js +2 -3
- package/dist/cms/runtime/api.d.ts +5 -0
- package/dist/cms/runtime/types.d.ts +13 -8
- package/dist/core/cms.js +3 -0
- package/dist/core/fields/layoutUtils.d.ts +2 -2
- package/dist/core/fields/layoutUtils.js +3 -10
- package/dist/core/server/entries/operations/get.js +2 -2
- package/dist/core/server/media/mimeBlocklist.d.ts +1 -0
- package/dist/core/server/media/mimeBlocklist.js +31 -0
- package/dist/paraglide/messages/_index.d.ts +3 -36
- package/dist/paraglide/messages/_index.js +3 -71
- package/dist/paraglide/messages/hello_world.d.ts +5 -0
- package/dist/paraglide/messages/hello_world.js +33 -0
- package/dist/paraglide/messages/login_hello.d.ts +16 -0
- package/dist/paraglide/messages/login_hello.js +34 -0
- package/dist/paraglide/messages/login_please_login.d.ts +16 -0
- package/dist/paraglide/messages/login_please_login.js +34 -0
- package/dist/sveltekit/server/handle.js +8 -0
- package/dist/updates/0.13.3/index.d.ts +2 -0
- package/dist/updates/0.13.3/index.js +21 -0
- package/dist/updates/index.js +2 -1
- package/package.json +1 -1
- package/dist/admin/utils/translationStatus.d.ts +0 -17
- package/dist/admin/utils/translationStatus.js +0 -133
- package/dist/demo/reset.d.ts +0 -1
- package/dist/demo/reset.js +0 -26
- package/dist/paraglide/messages/en.d.ts +0 -5
- package/dist/paraglide/messages/en.js +0 -14
- package/dist/paraglide/messages/pl.d.ts +0 -5
- package/dist/paraglide/messages/pl.js +0 -14
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ImageFieldData, VideoFieldData, StructuredContentDoc } from 'includio-cms/types';
|
|
2
2
|
export type SingleSlug = "settings" | "image-showcase";
|
|
3
3
|
export interface Settings {
|
|
4
4
|
_id: string;
|
|
5
5
|
_slug: string;
|
|
6
6
|
_type: string;
|
|
7
7
|
_publishedAt: Date | null;
|
|
8
|
+
_url?: string;
|
|
8
9
|
siteName: string;
|
|
9
10
|
description?: string;
|
|
10
|
-
logo?:
|
|
11
|
-
favicon?:
|
|
11
|
+
logo?: ImageFieldData | VideoFieldData | null;
|
|
12
|
+
favicon?: ImageFieldData | VideoFieldData | null;
|
|
12
13
|
socialLinks?: ({
|
|
13
14
|
_slug: 'socialLink';
|
|
14
15
|
platform: string;
|
|
@@ -25,7 +26,8 @@ export interface ImageShowcase {
|
|
|
25
26
|
_slug: string;
|
|
26
27
|
_type: string;
|
|
27
28
|
_publishedAt: Date | null;
|
|
28
|
-
|
|
29
|
+
_url?: string;
|
|
30
|
+
photo?: ImageFieldData | VideoFieldData | null;
|
|
29
31
|
}
|
|
30
32
|
export type SingleEntryMap = {
|
|
31
33
|
settings: Settings;
|
|
@@ -37,13 +39,14 @@ export interface BlogPost {
|
|
|
37
39
|
_slug: string;
|
|
38
40
|
_type: string;
|
|
39
41
|
_publishedAt: Date | null;
|
|
42
|
+
_url?: string;
|
|
40
43
|
title: string;
|
|
41
44
|
slug?: string;
|
|
42
|
-
cover?:
|
|
45
|
+
cover?: ImageFieldData | VideoFieldData | null;
|
|
43
46
|
rating: number;
|
|
44
47
|
category?: string;
|
|
45
48
|
publishedAt?: string;
|
|
46
|
-
thumbnail?:
|
|
49
|
+
thumbnail?: ImageFieldData | VideoFieldData | null;
|
|
47
50
|
content?: StructuredContentDoc;
|
|
48
51
|
tags?: string[];
|
|
49
52
|
seo: {
|
|
@@ -65,6 +68,7 @@ export interface Project {
|
|
|
65
68
|
_slug: string;
|
|
66
69
|
_type: string;
|
|
67
70
|
_publishedAt: Date | null;
|
|
71
|
+
_url?: string;
|
|
68
72
|
title: string;
|
|
69
73
|
description?: string;
|
|
70
74
|
status?: string;
|
|
@@ -72,7 +76,7 @@ export interface Project {
|
|
|
72
76
|
url?: {
|
|
73
77
|
url: string;
|
|
74
78
|
};
|
|
75
|
-
image?:
|
|
79
|
+
image?: ImageFieldData | VideoFieldData | null;
|
|
76
80
|
techStack?: ({
|
|
77
81
|
_slug: 'tech';
|
|
78
82
|
name: string;
|
|
@@ -92,6 +96,7 @@ export interface ArrayTest {
|
|
|
92
96
|
_slug: string;
|
|
93
97
|
_type: string;
|
|
94
98
|
_publishedAt: Date | null;
|
|
99
|
+
_url?: string;
|
|
95
100
|
name: string;
|
|
96
101
|
tags?: string[];
|
|
97
102
|
localizedTags?: Record<string, string>[];
|
|
@@ -104,7 +109,7 @@ export interface ArrayTest {
|
|
|
104
109
|
body?: StructuredContentDoc;
|
|
105
110
|
} | {
|
|
106
111
|
_slug: 'image-block';
|
|
107
|
-
image:
|
|
112
|
+
image: ImageFieldData | VideoFieldData;
|
|
108
113
|
caption?: string;
|
|
109
114
|
})[];
|
|
110
115
|
highlights?: ({
|
package/dist/core/cms.js
CHANGED
|
@@ -51,6 +51,9 @@ export class CMS {
|
|
|
51
51
|
};
|
|
52
52
|
});
|
|
53
53
|
this.languages = config.languages || [];
|
|
54
|
+
if (this.languages.length === 0) {
|
|
55
|
+
throw new Error('CMS config must include at least one language.');
|
|
56
|
+
}
|
|
54
57
|
this.apiKeys = config.apiKeys || [];
|
|
55
58
|
if (config.plugins) {
|
|
56
59
|
this.plugins = config.plugins;
|
|
@@ -25,8 +25,8 @@ export declare function collectAllLeafPaths(fields: Field[], prefix?: string): s
|
|
|
25
25
|
export declare function getDistributedObjectSlugs(nodes: LayoutNode[], fields: Field[]): Set<string>;
|
|
26
26
|
/**
|
|
27
27
|
* Build SuperForm-compatible path for a dot-notation field reference.
|
|
28
|
-
* 'hero.title' → 'hero.
|
|
29
|
-
* 'hero.contact.email' → 'hero.
|
|
28
|
+
* 'hero.title' → 'hero.title'
|
|
29
|
+
* 'hero.contact.email' → 'hero.contact.email'
|
|
30
30
|
* 'title' → 'title' (no change for top-level)
|
|
31
31
|
*/
|
|
32
32
|
export declare function buildFormPath(dotPath: string): string;
|
|
@@ -98,19 +98,12 @@ export function getDistributedObjectSlugs(nodes, fields) {
|
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Build SuperForm-compatible path for a dot-notation field reference.
|
|
101
|
-
* 'hero.title' → 'hero.
|
|
102
|
-
* 'hero.contact.email' → 'hero.
|
|
101
|
+
* 'hero.title' → 'hero.title'
|
|
102
|
+
* 'hero.contact.email' → 'hero.contact.email'
|
|
103
103
|
* 'title' → 'title' (no change for top-level)
|
|
104
104
|
*/
|
|
105
105
|
export function buildFormPath(dotPath) {
|
|
106
|
-
|
|
107
|
-
if (parts.length <= 1)
|
|
108
|
-
return dotPath;
|
|
109
|
-
const result = [parts[0]];
|
|
110
|
-
for (let i = 1; i < parts.length; i++) {
|
|
111
|
-
result.push('data', parts[i]);
|
|
112
|
-
}
|
|
113
|
-
return result.join('.');
|
|
106
|
+
return dotPath;
|
|
114
107
|
}
|
|
115
108
|
/** Count columns expected by a ratio string */
|
|
116
109
|
function columnCount(ratio) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCMS } from '../../../cms.js';
|
|
2
|
+
import { getAtPath } from '../../../../admin/utils/objectPath.js';
|
|
2
3
|
import { populateEntryData } from '../../fields/populateEntry.js';
|
|
3
4
|
import { getFieldsFromConfig } from '../../../fields/layoutUtils.js';
|
|
4
5
|
import { getEntrySlugPath, getSlugFromEntryData, getEntryPath } from '../../fields/slugResolver.js';
|
|
@@ -303,8 +304,7 @@ export const getEntryLabels = async (options) => {
|
|
|
303
304
|
const latestVersion = publishedVersion ?? sorted[0] ?? null;
|
|
304
305
|
let label = entry.id;
|
|
305
306
|
if (entryAdminTitle && latestVersion) {
|
|
306
|
-
const titleData = latestVersion.data
|
|
307
|
-
// Data is now flat — titleData is the string directly
|
|
307
|
+
const titleData = getAtPath(latestVersion.data, entryAdminTitle);
|
|
308
308
|
if (typeof titleData === 'string') {
|
|
309
309
|
label = titleData || entry.id;
|
|
310
310
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isBlockedMimeType(mimeType: string, fileName?: string): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const BLOCKED_MIME_TYPES = new Set([
|
|
2
|
+
'application/x-msdownload',
|
|
3
|
+
'application/x-executable',
|
|
4
|
+
'application/x-msdos-program',
|
|
5
|
+
'application/x-sh',
|
|
6
|
+
'application/x-shellscript',
|
|
7
|
+
'application/x-bat',
|
|
8
|
+
'application/x-msi',
|
|
9
|
+
'application/java-archive',
|
|
10
|
+
'application/x-httpd-php',
|
|
11
|
+
'text/x-php',
|
|
12
|
+
'application/hta'
|
|
13
|
+
]);
|
|
14
|
+
const BLOCKED_EXTENSIONS = new Set([
|
|
15
|
+
'.exe', '.bat', '.cmd', '.com', '.msi', '.scr', '.pif',
|
|
16
|
+
'.sh', '.bash', '.csh', '.ksh',
|
|
17
|
+
'.php', '.php3', '.php4', '.php5', '.phtml',
|
|
18
|
+
'.jsp', '.asp', '.aspx',
|
|
19
|
+
'.jar', '.class',
|
|
20
|
+
'.hta', '.vbs', '.vbe', '.wsf', '.wsh', '.ps1'
|
|
21
|
+
]);
|
|
22
|
+
export function isBlockedMimeType(mimeType, fileName) {
|
|
23
|
+
if (BLOCKED_MIME_TYPES.has(mimeType.toLowerCase()))
|
|
24
|
+
return true;
|
|
25
|
+
if (fileName) {
|
|
26
|
+
const ext = fileName.slice(fileName.lastIndexOf('.')).toLowerCase();
|
|
27
|
+
if (BLOCKED_EXTENSIONS.has(ext))
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
@@ -1,36 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
locale?: "en" | "pl";
|
|
5
|
-
}): string;
|
|
6
|
-
/**
|
|
7
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
8
|
-
*
|
|
9
|
-
* - Changing this function will be over-written by the next build.
|
|
10
|
-
*
|
|
11
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
12
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
13
|
-
*
|
|
14
|
-
* @param {{}} inputs
|
|
15
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
16
|
-
* @returns {string}
|
|
17
|
-
*/
|
|
18
|
-
declare function login_hello(inputs?: {}, options?: {
|
|
19
|
-
locale?: "en" | "pl";
|
|
20
|
-
}): string;
|
|
21
|
-
/**
|
|
22
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
23
|
-
*
|
|
24
|
-
* - Changing this function will be over-written by the next build.
|
|
25
|
-
*
|
|
26
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
27
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
28
|
-
*
|
|
29
|
-
* @param {{}} inputs
|
|
30
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
31
|
-
* @returns {string}
|
|
32
|
-
*/
|
|
33
|
-
declare function login_please_login(inputs?: {}, options?: {
|
|
34
|
-
locale?: "en" | "pl";
|
|
35
|
-
}): string;
|
|
36
|
-
export { login_hello as login.hello, login_please_login as login.please_login };
|
|
1
|
+
export * from "./hello_world.js";
|
|
2
|
+
export * from "./login_hello.js";
|
|
3
|
+
export * from "./login_please_login.js";
|
|
@@ -1,72 +1,4 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
7
|
-
*
|
|
8
|
-
* - Changing this function will be over-written by the next build.
|
|
9
|
-
*
|
|
10
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
11
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
12
|
-
*
|
|
13
|
-
* @param {{ name: NonNullable<unknown> }} inputs
|
|
14
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
18
|
-
export const hello_world = (inputs, options = {}) => {
|
|
19
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
20
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.hello_world(inputs)
|
|
21
|
-
}
|
|
22
|
-
const locale = options.locale ?? getLocale()
|
|
23
|
-
trackMessageCall("hello_world", locale)
|
|
24
|
-
if (locale === "en") return en.hello_world(inputs)
|
|
25
|
-
return pl.hello_world(inputs)
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
29
|
-
*
|
|
30
|
-
* - Changing this function will be over-written by the next build.
|
|
31
|
-
*
|
|
32
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
33
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
34
|
-
*
|
|
35
|
-
* @param {{}} inputs
|
|
36
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
37
|
-
* @returns {string}
|
|
38
|
-
*/
|
|
39
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
40
|
-
const login_hello = (inputs = {}, options = {}) => {
|
|
41
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
42
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.login_hello(inputs)
|
|
43
|
-
}
|
|
44
|
-
const locale = options.locale ?? getLocale()
|
|
45
|
-
trackMessageCall("login_hello", locale)
|
|
46
|
-
if (locale === "en") return en.login_hello(inputs)
|
|
47
|
-
return pl.login_hello(inputs)
|
|
48
|
-
};
|
|
49
|
-
export { login_hello as "login.hello" }
|
|
50
|
-
/**
|
|
51
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
52
|
-
*
|
|
53
|
-
* - Changing this function will be over-written by the next build.
|
|
54
|
-
*
|
|
55
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
56
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
57
|
-
*
|
|
58
|
-
* @param {{}} inputs
|
|
59
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
60
|
-
* @returns {string}
|
|
61
|
-
*/
|
|
62
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
63
|
-
const login_please_login = (inputs = {}, options = {}) => {
|
|
64
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
65
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.login_please_login(inputs)
|
|
66
|
-
}
|
|
67
|
-
const locale = options.locale ?? getLocale()
|
|
68
|
-
trackMessageCall("login_please_login", locale)
|
|
69
|
-
if (locale === "en") return en.login_please_login(inputs)
|
|
70
|
-
return pl.login_please_login(inputs)
|
|
71
|
-
};
|
|
72
|
-
export { login_please_login as "login.please_login" }
|
|
2
|
+
export * from './hello_world.js'
|
|
3
|
+
export * from './login_hello.js'
|
|
4
|
+
export * from './login_please_login.js'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
+
|
|
4
|
+
const en_hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
5
|
+
return `Hello, ${i.name} from en!`
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const pl_hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
9
|
+
return `Hello, ${i.name} from pl!`
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
+
*
|
|
15
|
+
* - Changing this function will be over-written by the next build.
|
|
16
|
+
*
|
|
17
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
+
*
|
|
20
|
+
* @param {{ name: NonNullable<unknown> }} inputs
|
|
21
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
+
export const hello_world = (inputs, options = {}) => {
|
|
26
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.hello_world(inputs)
|
|
28
|
+
}
|
|
29
|
+
const locale = options.locale ?? getLocale()
|
|
30
|
+
trackMessageCall("hello_world", locale)
|
|
31
|
+
if (locale === "en") return en_hello_world(inputs)
|
|
32
|
+
return pl_hello_world(inputs)
|
|
33
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { login_hello as login.hello };
|
|
2
|
+
/**
|
|
3
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
4
|
+
*
|
|
5
|
+
* - Changing this function will be over-written by the next build.
|
|
6
|
+
*
|
|
7
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
8
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
9
|
+
*
|
|
10
|
+
* @param {{}} inputs
|
|
11
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
declare function login_hello(inputs?: {}, options?: {
|
|
15
|
+
locale?: "en" | "pl";
|
|
16
|
+
}): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
+
|
|
4
|
+
const en_login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
5
|
+
return `Welcome back`
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const pl_login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
+
return `Witaj ponownie`
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
+
*
|
|
15
|
+
* - Changing this function will be over-written by the next build.
|
|
16
|
+
*
|
|
17
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
+
*
|
|
20
|
+
* @param {{}} inputs
|
|
21
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
+
const login_hello = (inputs = {}, options = {}) => {
|
|
26
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.login_hello(inputs)
|
|
28
|
+
}
|
|
29
|
+
const locale = options.locale ?? getLocale()
|
|
30
|
+
trackMessageCall("login_hello", locale)
|
|
31
|
+
if (locale === "en") return en_login_hello(inputs)
|
|
32
|
+
return pl_login_hello(inputs)
|
|
33
|
+
};
|
|
34
|
+
export { login_hello as "login.hello" }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { login_please_login as login.please_login };
|
|
2
|
+
/**
|
|
3
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
4
|
+
*
|
|
5
|
+
* - Changing this function will be over-written by the next build.
|
|
6
|
+
*
|
|
7
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
8
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
9
|
+
*
|
|
10
|
+
* @param {{}} inputs
|
|
11
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
declare function login_please_login(inputs?: {}, options?: {
|
|
15
|
+
locale?: "en" | "pl";
|
|
16
|
+
}): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
+
|
|
4
|
+
const en_login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
5
|
+
return `Login to your account`
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const pl_login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
+
return `Zaloguj się na swoje konto`
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
+
*
|
|
15
|
+
* - Changing this function will be over-written by the next build.
|
|
16
|
+
*
|
|
17
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
+
*
|
|
20
|
+
* @param {{}} inputs
|
|
21
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
+
const login_please_login = (inputs = {}, options = {}) => {
|
|
26
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.login_please_login(inputs)
|
|
28
|
+
}
|
|
29
|
+
const locale = options.locale ?? getLocale()
|
|
30
|
+
trackMessageCall("login_please_login", locale)
|
|
31
|
+
if (locale === "en") return en_login_please_login(inputs)
|
|
32
|
+
return pl_login_please_login(inputs)
|
|
33
|
+
};
|
|
34
|
+
export { login_please_login as "login.please_login" }
|
|
@@ -65,5 +65,13 @@ export function includioCMS(cmsConfig) {
|
|
|
65
65
|
handles.push(handleAuth);
|
|
66
66
|
}
|
|
67
67
|
handles.push(adminGuard);
|
|
68
|
+
handles.push(securityHeaders);
|
|
68
69
|
return handles;
|
|
69
70
|
}
|
|
71
|
+
const securityHeaders = async ({ event, resolve }) => {
|
|
72
|
+
const response = await resolve(event);
|
|
73
|
+
response.headers.set('X-Content-Type-Options', 'nosniff');
|
|
74
|
+
response.headers.set('X-Frame-Options', 'DENY');
|
|
75
|
+
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
76
|
+
return response;
|
|
77
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.13.3',
|
|
3
|
+
date: '2026-03-23',
|
|
4
|
+
description: 'Security hardening, per-language content fixes',
|
|
5
|
+
features: [
|
|
6
|
+
'Timing-safe API key comparison (prevents timing attacks)',
|
|
7
|
+
'MIME type blocklist on upload and file replace endpoints',
|
|
8
|
+
'Security headers: X-Content-Type-Options, X-Frame-Options, Referrer-Policy',
|
|
9
|
+
'CMS constructor validates that at least one language is configured'
|
|
10
|
+
],
|
|
11
|
+
fixes: [
|
|
12
|
+
'Form submission rate limiting applies to all requests (not just multipart uploads)',
|
|
13
|
+
'Form submission uses SvelteKit getClientAddress() instead of spoofable x-forwarded-for header',
|
|
14
|
+
'Removed demo reset endpoint with hardcoded fallback secret',
|
|
15
|
+
'Added .catch() handlers for unhandled promise rejections in admin components',
|
|
16
|
+
'Per-language content language state and entry label fixes'
|
|
17
|
+
],
|
|
18
|
+
breakingChanges: [
|
|
19
|
+
'CMS config with empty languages array now throws an error at initialization'
|
|
20
|
+
]
|
|
21
|
+
};
|
package/dist/updates/index.js
CHANGED
|
@@ -35,7 +35,8 @@ import { update as update0120 } from './0.12.0/index.js';
|
|
|
35
35
|
import { update as update0130 } from './0.13.0/index.js';
|
|
36
36
|
import { update as update0131 } from './0.13.1/index.js';
|
|
37
37
|
import { update as update0132 } from './0.13.2/index.js';
|
|
38
|
-
|
|
38
|
+
import { update as update0133 } from './0.13.3/index.js';
|
|
39
|
+
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, update0131, update0132, update0133];
|
|
39
40
|
export const getUpdatesFrom = (fromVersion) => {
|
|
40
41
|
const fromParts = fromVersion.split('.').map(Number);
|
|
41
42
|
return updates.filter((update) => {
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Field } from '../../types/fields.js';
|
|
2
|
-
export type TranslationCompleteness = 'complete' | 'partial' | 'empty';
|
|
3
|
-
export interface LangStatus {
|
|
4
|
-
filled: number;
|
|
5
|
-
total: number;
|
|
6
|
-
percentage: number;
|
|
7
|
-
status: TranslationCompleteness;
|
|
8
|
-
missingFields: {
|
|
9
|
-
slug: string;
|
|
10
|
-
label: string;
|
|
11
|
-
}[];
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Compute translation status for each language.
|
|
15
|
-
* Checks all localized fields (text, richtext, content) + seo/url sub-fields.
|
|
16
|
-
*/
|
|
17
|
-
export declare function computeTranslationStatus(data: Record<string, unknown>, fields: Field[], languages: string[]): Record<string, LangStatus>;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { getAtPath } from './objectPath.js';
|
|
2
|
-
/** Extract a label string from Localized, preferring pl then en then slug. */
|
|
3
|
-
function extractLabel(label, fallback) {
|
|
4
|
-
if (!label)
|
|
5
|
-
return fallback;
|
|
6
|
-
if (typeof label === 'string')
|
|
7
|
-
return label;
|
|
8
|
-
return label.pl || label.en || fallback;
|
|
9
|
-
}
|
|
10
|
-
/** Check if a value counts as "filled" for a given field type. */
|
|
11
|
-
function isFieldFilled(value, fieldType) {
|
|
12
|
-
if (value == null)
|
|
13
|
-
return false;
|
|
14
|
-
switch (fieldType) {
|
|
15
|
-
case 'text':
|
|
16
|
-
return typeof value === 'string' && value.length > 0;
|
|
17
|
-
case 'content': {
|
|
18
|
-
if (typeof value !== 'object')
|
|
19
|
-
return false;
|
|
20
|
-
const doc = value;
|
|
21
|
-
return doc.type === 'doc' && Array.isArray(doc.content) && doc.content.length > 0;
|
|
22
|
-
}
|
|
23
|
-
case 'seo': {
|
|
24
|
-
if (typeof value !== 'object')
|
|
25
|
-
return false;
|
|
26
|
-
const seo = value;
|
|
27
|
-
// At least title or description filled
|
|
28
|
-
return ((typeof seo.title === 'string' && seo.title.length > 0) ||
|
|
29
|
-
(typeof seo.description === 'string' && seo.description.length > 0));
|
|
30
|
-
}
|
|
31
|
-
case 'url': {
|
|
32
|
-
if (typeof value !== 'object')
|
|
33
|
-
return false;
|
|
34
|
-
const url = value;
|
|
35
|
-
return typeof url.url === 'string' && url.url.length > 0;
|
|
36
|
-
}
|
|
37
|
-
default:
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/** Collect all localized fields from a field list, including nested seo/url sub-fields. */
|
|
42
|
-
function collectLocalizedFields(fields) {
|
|
43
|
-
const result = [];
|
|
44
|
-
for (const field of fields) {
|
|
45
|
-
if (field.localized === false)
|
|
46
|
-
continue;
|
|
47
|
-
const label = extractLabel(field.label, field.slug);
|
|
48
|
-
if (field.type === 'text' || field.type === 'content') {
|
|
49
|
-
result.push({ slug: field.slug, label, type: field.type, required: !!field.required });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// SEO and URL fields are always localized by nature (sub-fields are lang-keyed)
|
|
53
|
-
for (const field of fields) {
|
|
54
|
-
if (field.type === 'seo') {
|
|
55
|
-
const label = extractLabel(field.label, field.slug);
|
|
56
|
-
result.push({ slug: field.slug, label, type: 'seo', required: !!field.required });
|
|
57
|
-
}
|
|
58
|
-
if (field.type === 'url') {
|
|
59
|
-
const label = extractLabel(field.label, field.slug);
|
|
60
|
-
result.push({ slug: field.slug, label, type: 'url', required: !!field.required });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
/** Resolve the value of a field for a given language. */
|
|
66
|
-
function resolveFieldValue(data, field, lang) {
|
|
67
|
-
if (field.type === 'seo') {
|
|
68
|
-
const seoData = getAtPath(data, field.slug);
|
|
69
|
-
if (seoData && typeof seoData === 'object') {
|
|
70
|
-
const seo = seoData;
|
|
71
|
-
const title = extractLangValue(seo.title, lang);
|
|
72
|
-
const desc = extractLangValue(seo.description, lang);
|
|
73
|
-
return { title, description: desc };
|
|
74
|
-
}
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
else if (field.type === 'url') {
|
|
78
|
-
const urlData = getAtPath(data, field.slug);
|
|
79
|
-
if (urlData && typeof urlData === 'object') {
|
|
80
|
-
const url = urlData;
|
|
81
|
-
const urlVal = url.url && typeof url.url === 'object'
|
|
82
|
-
? url.url[lang]
|
|
83
|
-
: undefined;
|
|
84
|
-
return { url: urlVal || '' };
|
|
85
|
-
}
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
const fieldData = getAtPath(data, field.slug);
|
|
90
|
-
if (fieldData && typeof fieldData === 'object' && !Array.isArray(fieldData)) {
|
|
91
|
-
return fieldData[lang];
|
|
92
|
-
}
|
|
93
|
-
return undefined;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Compute translation status for each language.
|
|
98
|
-
* Checks all localized fields (text, richtext, content) + seo/url sub-fields.
|
|
99
|
-
*/
|
|
100
|
-
export function computeTranslationStatus(data, fields, languages) {
|
|
101
|
-
const allLocalizedFields = collectLocalizedFields(fields);
|
|
102
|
-
// Pre-filter: keep field if required OR has content in at least one language
|
|
103
|
-
const localizedFields = allLocalizedFields.filter((field) => field.required ||
|
|
104
|
-
languages.some((lang) => isFieldFilled(resolveFieldValue(data, field, lang), field.type)));
|
|
105
|
-
const result = {};
|
|
106
|
-
for (const lang of languages) {
|
|
107
|
-
let filled = 0;
|
|
108
|
-
const total = localizedFields.length;
|
|
109
|
-
const missingFields = [];
|
|
110
|
-
for (const field of localizedFields) {
|
|
111
|
-
const value = resolveFieldValue(data, field, lang);
|
|
112
|
-
if (isFieldFilled(value, field.type)) {
|
|
113
|
-
filled++;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
missingFields.push({ slug: field.slug, label: field.label });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const percentage = total === 0 ? 100 : Math.round((filled / total) * 100);
|
|
120
|
-
const status = percentage === 100 ? 'complete' : percentage === 0 ? 'empty' : 'partial';
|
|
121
|
-
result[lang] = { filled, total, percentage, status, missingFields };
|
|
122
|
-
}
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
/** Extract lang value from a possibly lang-keyed value. */
|
|
126
|
-
function extractLangValue(value, lang) {
|
|
127
|
-
if (typeof value === 'string')
|
|
128
|
-
return value;
|
|
129
|
-
if (value && typeof value === 'object') {
|
|
130
|
-
return (value[lang]) || '';
|
|
131
|
-
}
|
|
132
|
-
return '';
|
|
133
|
-
}
|
package/dist/demo/reset.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function resetDemoData(): Promise<void>;
|