crelte 0.5.8 → 0.5.10
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/dist/blocks/Blocks.d.ts +41 -4
- package/dist/blocks/Blocks.d.ts.map +1 -1
- package/dist/blocks/Blocks.js +47 -2
- package/dist/blocks/Blocks.svelte +2 -16
- package/dist/blocks/Blocks.svelte.d.ts +20 -37
- package/dist/blocks/Blocks.svelte.d.ts.map +1 -1
- package/dist/blocks/index.d.ts +2 -2
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +2 -2
- package/dist/cookies/ServerCookies.d.ts +1 -1
- package/dist/cookies/ServerCookies.js +1 -1
- package/dist/cookies/index.d.ts +1 -1
- package/dist/crelte.d.ts +21 -10
- package/dist/crelte.d.ts.map +1 -1
- package/dist/index.d.ts +19 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -13
- package/dist/init/client.d.ts +2 -2
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +3 -2
- package/dist/init/server.d.ts +7 -6
- package/dist/init/server.d.ts.map +1 -1
- package/dist/init/server.js +6 -6
- package/dist/loadData/Globals.d.ts +3 -3
- package/dist/loadData/Globals.js +3 -3
- package/dist/loadData/loadData.d.ts +8 -18
- package/dist/loadData/loadData.d.ts.map +1 -1
- package/dist/loadData/loadData.js +2 -2
- package/dist/node/index.d.ts +5 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +84 -35
- package/dist/plugins/Events.d.ts +4 -4
- package/dist/plugins/Plugins.d.ts +2 -2
- package/dist/plugins/index.d.ts +2 -3
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +2 -1
- package/dist/queries/Queries.d.ts +9 -0
- package/dist/queries/Queries.d.ts.map +1 -1
- package/dist/queries/Queries.js +29 -17
- package/dist/queries/QueryError.d.ts +2 -0
- package/dist/queries/QueryError.d.ts.map +1 -1
- package/dist/queries/QueryError.js +6 -1
- package/dist/queries/gql.d.ts +2 -2
- package/dist/queries/gql.js +2 -2
- package/dist/queries/index.d.ts +7 -5
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/vars.d.ts +7 -7
- package/dist/queries/vars.d.ts.map +1 -1
- package/dist/queries/vars.js +10 -8
- package/dist/routing/LoadRunner.d.ts +1 -1
- package/dist/routing/LoadRunner.js +1 -1
- package/dist/routing/index.d.ts +4 -4
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/route/BaseRoute.d.ts +25 -25
- package/dist/routing/route/BaseRoute.js +24 -24
- package/dist/routing/route/Request.d.ts +4 -4
- package/dist/routing/route/Request.js +4 -4
- package/dist/routing/route/Route.d.ts +2 -2
- package/dist/routing/route/Route.js +2 -2
- package/dist/routing/router/BaseRouter.d.ts +4 -4
- package/dist/routing/router/BaseRouter.js +3 -3
- package/dist/routing/router/ClientRouter.d.ts +1 -1
- package/dist/routing/router/ClientRouter.js +1 -1
- package/dist/routing/router/Router.d.ts +27 -25
- package/dist/routing/router/Router.d.ts.map +1 -1
- package/dist/routing/router/Router.js +24 -21
- package/dist/routing/router/ServerRouter.d.ts +1 -1
- package/dist/routing/router/ServerRouter.js +1 -1
- package/dist/server/CrelteServer.d.ts +5 -5
- package/dist/server/CrelteServer.d.ts.map +1 -1
- package/dist/server/CrelteServer.js +4 -4
- package/dist/server/Request.d.ts +7 -1
- package/dist/server/Request.d.ts.map +1 -1
- package/dist/server/Request.js +7 -1
- package/dist/server/ServerRouter.d.ts +1 -1
- package/dist/server/ServerRouter.d.ts.map +1 -1
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/shared.d.ts +7 -13
- package/dist/server/shared.d.ts.map +1 -1
- package/dist/server/shared.js +14 -16
- package/dist/ssr/SsrCache.d.ts +56 -4
- package/dist/ssr/SsrCache.d.ts.map +1 -1
- package/dist/ssr/SsrCache.js +94 -20
- package/dist/std/index.d.ts +13 -0
- package/dist/std/index.d.ts.map +1 -1
- package/dist/std/index.js +13 -0
- package/dist/std/rand/index.d.ts +34 -0
- package/dist/std/rand/index.d.ts.map +1 -0
- package/dist/std/rand/index.js +45 -0
- package/dist/std/rand/internal.d.ts +8 -0
- package/dist/std/rand/internal.d.ts.map +1 -0
- package/dist/std/rand/internal.js +15 -0
- package/dist/std/stores/Writable.d.ts +1 -1
- package/dist/std/stores/Writable.js +1 -1
- package/dist/translations/index.d.ts +28 -0
- package/dist/translations/index.d.ts.map +1 -0
- package/dist/translations/index.js +31 -0
- package/dist/translations/loadTranslations.d.ts +23 -0
- package/dist/translations/loadTranslations.d.ts.map +1 -0
- package/dist/translations/loadTranslations.js +26 -0
- package/dist/translations/loader/GlobalLoader.d.ts +34 -0
- package/dist/translations/loader/GlobalLoader.d.ts.map +1 -0
- package/dist/translations/loader/GlobalLoader.js +45 -0
- package/dist/translations/loader/fileLoader/ClientFileLoader.d.ts +10 -0
- package/dist/translations/loader/fileLoader/ClientFileLoader.d.ts.map +1 -0
- package/dist/translations/loader/fileLoader/ClientFileLoader.js +24 -0
- package/dist/translations/loader/fileLoader/NodeFileLoader.d.ts +9 -0
- package/dist/translations/loader/fileLoader/NodeFileLoader.d.ts.map +1 -0
- package/dist/translations/loader/fileLoader/NodeFileLoader.js +21 -0
- package/dist/translations/loader/fileLoader/fileLoader.d.ts +5 -0
- package/dist/translations/loader/fileLoader/fileLoader.d.ts.map +1 -0
- package/dist/translations/loader/fileLoader/fileLoader.js +16 -0
- package/dist/translations/loader/index.d.ts +7 -0
- package/dist/translations/loader/index.d.ts.map +1 -0
- package/dist/translations/loader/index.js +1 -0
- package/dist/translations/translationsPlugin.d.ts +64 -0
- package/dist/translations/translationsPlugin.d.ts.map +1 -0
- package/dist/translations/translationsPlugin.js +110 -0
- package/dist/translations/utils.d.ts +8 -0
- package/dist/translations/utils.d.ts.map +1 -0
- package/dist/translations/utils.js +15 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +30 -38
- package/package.json +9 -1
- package/src/blocks/Blocks.svelte +3 -78
- package/src/blocks/Blocks.ts +63 -6
- package/src/blocks/index.ts +2 -2
- package/src/cookies/ServerCookies.ts +1 -1
- package/src/cookies/index.ts +1 -1
- package/src/crelte.ts +21 -10
- package/src/index.ts +19 -14
- package/src/init/client.ts +3 -2
- package/src/init/server.ts +14 -8
- package/src/loadData/Globals.ts +3 -3
- package/src/loadData/loadData.ts +8 -18
- package/src/node/index.ts +100 -39
- package/src/plugins/Events.ts +4 -4
- package/src/plugins/Plugins.ts +2 -2
- package/src/plugins/index.ts +2 -3
- package/src/queries/Queries.ts +35 -18
- package/src/queries/QueryError.ts +10 -1
- package/src/queries/gql.ts +2 -2
- package/src/queries/index.ts +7 -4
- package/src/queries/vars.ts +12 -8
- package/src/routing/LoadRunner.ts +1 -1
- package/src/routing/index.ts +13 -3
- package/src/routing/route/BaseRoute.ts +25 -25
- package/src/routing/route/Request.ts +4 -4
- package/src/routing/route/Route.ts +2 -2
- package/src/routing/router/BaseRouter.ts +4 -4
- package/src/routing/router/ClientRouter.ts +1 -1
- package/src/routing/router/Router.ts +28 -25
- package/src/routing/router/ServerRouter.ts +1 -1
- package/src/server/CrelteServer.ts +5 -5
- package/src/server/Request.ts +7 -1
- package/src/server/ServerRouter.ts +1 -2
- package/src/server/index.ts +17 -3
- package/src/server/shared.ts +28 -33
- package/src/ssr/SsrCache.ts +104 -22
- package/src/std/index.ts +14 -0
- package/src/std/rand/index.ts +55 -0
- package/src/std/rand/internal.ts +17 -0
- package/src/std/stores/Writable.ts +1 -1
- package/src/translations/index.ts +56 -0
- package/src/translations/loadTranslations.ts +33 -0
- package/src/translations/loader/GlobalLoader.ts +62 -0
- package/src/translations/loader/fileLoader/ClientFileLoader.ts +40 -0
- package/src/translations/loader/fileLoader/NodeFileLoader.ts +32 -0
- package/src/translations/loader/fileLoader/fileLoader.ts +19 -0
- package/src/translations/loader/index.ts +8 -0
- package/src/translations/translationsPlugin.ts +145 -0
- package/src/translations/utils.ts +17 -0
- package/src/vite/index.ts +43 -39
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getTranslationsPlugin } from './translationsPlugin.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a translate store and loads the specified namespace.
|
|
4
|
+
*
|
|
5
|
+
* #### Example
|
|
6
|
+
* ```svelte
|
|
7
|
+
* <script module>
|
|
8
|
+
* import { loadTranslations } from 'crelte/translations';
|
|
9
|
+
* export const loadData = {
|
|
10
|
+
* t: cr => loadTranslations(cr, 'customNamespace')
|
|
11
|
+
* };
|
|
12
|
+
* </script>
|
|
13
|
+
*
|
|
14
|
+
* <script>
|
|
15
|
+
* let { t } = $props();
|
|
16
|
+
* </script>
|
|
17
|
+
*
|
|
18
|
+
* <h1>{$t('welcome_message')}</h1>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export default async function loadTranslations(cr, namespace) {
|
|
22
|
+
const plugin = getTranslationsPlugin(cr);
|
|
23
|
+
// we don't need the return value here as it's cached
|
|
24
|
+
await plugin.load(cr, namespace);
|
|
25
|
+
return plugin.z_createTranslateStore(namespace);
|
|
26
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Translations } from '../translationsPlugin.js';
|
|
2
|
+
import { Crelte, CrelteRequest } from '../../crelte.js';
|
|
3
|
+
import { LoaderCreator, TranslationsLoader } from '../index.js';
|
|
4
|
+
export default class GlobalLoader implements TranslationsLoader {
|
|
5
|
+
private handle;
|
|
6
|
+
constructor(_crelte: Crelte, opts: {
|
|
7
|
+
handle?: string;
|
|
8
|
+
});
|
|
9
|
+
load(cr: CrelteRequest, namespace: string): Promise<Translations>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a loader that loads translations from a global set.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createTranslations, createGlobalLoader } from 'crelte/translations';
|
|
16
|
+
*
|
|
17
|
+
* createTranslations({ loader: createGlobalLoader() });
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Then in you're global export a `translations` globalSet with namespaces
|
|
21
|
+
* as fields, at least `common`.
|
|
22
|
+
*
|
|
23
|
+
* ```graphql
|
|
24
|
+
* translations: globalSet(handle: "translations", siteId: $siteId) {
|
|
25
|
+
* ... on translations_GlobalSet {
|
|
26
|
+
* common
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
export declare function createGlobalLoader(opts?: {
|
|
31
|
+
/** the handle for the global set containing the namespaces (default = translations) */
|
|
32
|
+
handle?: string;
|
|
33
|
+
}): LoaderCreator;
|
|
34
|
+
//# sourceMappingURL=GlobalLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GlobalLoader.d.ts","sourceRoot":"","sources":["../../../src/translations/loader/GlobalLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,CAAC,OAAO,OAAO,YAAa,YAAW,kBAAkB;IAC9D,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAIhD,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAsBvE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,GAAE;IACL,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;CACX,GACJ,aAAa,CAEf"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default class GlobalLoader {
|
|
2
|
+
handle;
|
|
3
|
+
constructor(_crelte, opts) {
|
|
4
|
+
this.handle = opts.handle ?? 'translations';
|
|
5
|
+
}
|
|
6
|
+
async load(cr, namespace) {
|
|
7
|
+
const globalSet = await cr.globals.getAsync(this.handle);
|
|
8
|
+
if (!globalSet || typeof globalSet !== 'object')
|
|
9
|
+
throw new Error(`missing globals \`${this.handle}\``);
|
|
10
|
+
const data = globalSet[namespace];
|
|
11
|
+
if (!data)
|
|
12
|
+
throw new Error(`could not find \`${namespace}\` in globals \`${this.handle}\``);
|
|
13
|
+
if (typeof data !== 'string')
|
|
14
|
+
return data;
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(data);
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
throw new Error(`could not parse \`${this.handle}.${namespace}\` as json \n\n` +
|
|
20
|
+
(e instanceof Error ? e.message : ''));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a loader that loads translations from a global set.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { createTranslations, createGlobalLoader } from 'crelte/translations';
|
|
29
|
+
*
|
|
30
|
+
* createTranslations({ loader: createGlobalLoader() });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Then in you're global export a `translations` globalSet with namespaces
|
|
34
|
+
* as fields, at least `common`.
|
|
35
|
+
*
|
|
36
|
+
* ```graphql
|
|
37
|
+
* translations: globalSet(handle: "translations", siteId: $siteId) {
|
|
38
|
+
* ... on translations_GlobalSet {
|
|
39
|
+
* common
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
*/
|
|
43
|
+
export function createGlobalLoader(opts = {}) {
|
|
44
|
+
return crelte => new GlobalLoader(crelte, opts);
|
|
45
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CrelteRequest } from '../../../crelte.js';
|
|
2
|
+
import SsrCache from '../../../ssr/SsrCache.js';
|
|
3
|
+
import { Translations } from '../../translationsPlugin.js';
|
|
4
|
+
import { TranslationsLoader } from '../index.js';
|
|
5
|
+
export default class ClientFileLoader implements TranslationsLoader {
|
|
6
|
+
private readonly runNumber;
|
|
7
|
+
constructor(cache: SsrCache);
|
|
8
|
+
load(cr: CrelteRequest, namespace: string): Promise<Translations>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ClientFileLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientFileLoader.d.ts","sourceRoot":"","sources":["../../../../src/translations/loader/fileLoader/ClientFileLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,CAAC,OAAO,OAAO,gBAAiB,YAAW,kBAAkB;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,KAAK,EAAE,QAAQ;IAIrB,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA0BvE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SSR_RUN_NUMBER_KEY, translationFilePath } from './fileLoader.js';
|
|
2
|
+
export default class ClientFileLoader {
|
|
3
|
+
runNumber;
|
|
4
|
+
constructor(cache) {
|
|
5
|
+
this.runNumber = cache.get(SSR_RUN_NUMBER_KEY) ?? '';
|
|
6
|
+
}
|
|
7
|
+
async load(cr, namespace) {
|
|
8
|
+
const lang = cr.site.language;
|
|
9
|
+
try {
|
|
10
|
+
const resp = await fetch(`${translationFilePath(lang, namespace)}?run=${this.runNumber}`);
|
|
11
|
+
if (!resp.ok) {
|
|
12
|
+
throw new Error(`Failed to fetch translations file for ${lang}/${namespace}`);
|
|
13
|
+
}
|
|
14
|
+
// todo: validate data
|
|
15
|
+
const data = await resp.json();
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
console.error(e);
|
|
20
|
+
throw new Error('There is something wrong with your translations file. \n\n' +
|
|
21
|
+
(e instanceof Error ? e.message : ''));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Translations } from '../../translationsPlugin.js';
|
|
2
|
+
import SsrCache from '../../../ssr/SsrCache.js';
|
|
3
|
+
import { CrelteRequest } from '../../../crelte.js';
|
|
4
|
+
import { TranslationsLoader } from '../index.js';
|
|
5
|
+
export default class NodeFileLoader implements TranslationsLoader {
|
|
6
|
+
constructor(cache: SsrCache);
|
|
7
|
+
load(cr: CrelteRequest, namespace: string): Promise<Translations>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=NodeFileLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeFileLoader.d.ts","sourceRoot":"","sources":["../../../../src/translations/loader/fileLoader/NodeFileLoader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,cAAe,YAAW,kBAAkB;gBACpD,KAAK,EAAE,QAAQ;IAKrB,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAiBvE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { SSR_RUN_NUMBER_KEY, translationFilePath } from './fileLoader.js';
|
|
3
|
+
import { randomToken } from '../../utils.js';
|
|
4
|
+
export default class NodeFileLoader {
|
|
5
|
+
constructor(cache) {
|
|
6
|
+
// store RUN_NUMBER in ssr store
|
|
7
|
+
cache.set(SSR_RUN_NUMBER_KEY, randomToken());
|
|
8
|
+
}
|
|
9
|
+
async load(cr, namespace) {
|
|
10
|
+
const lang = cr.site.language;
|
|
11
|
+
try {
|
|
12
|
+
const fileString = await fs.readFile(`./public${translationFilePath(lang, namespace)}`, 'utf-8');
|
|
13
|
+
// todo: validate data
|
|
14
|
+
return JSON.parse(fileString);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
throw new Error('There is something wrong with your translations file. \n\n' +
|
|
18
|
+
(e instanceof Error ? e.message : ''));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { LoaderCreator } from '../index.js';
|
|
2
|
+
export declare const SSR_RUN_NUMBER_KEY = "st-run-number";
|
|
3
|
+
export declare function translationFilePath(lang: string, namespace: string): string;
|
|
4
|
+
export declare function createFileLoader(): LoaderCreator;
|
|
5
|
+
//# sourceMappingURL=fileLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileLoader.d.ts","sourceRoot":"","sources":["../../../../src/translations/loader/fileLoader/fileLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAIlD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import ClientFileLoader from './ClientFileLoader.js';
|
|
2
|
+
import NodeFileLoader from './NodeFileLoader.js';
|
|
3
|
+
export const SSR_RUN_NUMBER_KEY = 'st-run-number';
|
|
4
|
+
/// Returns a path to the translations file for the given language and namespace.
|
|
5
|
+
/// Always prefixed with a slash.
|
|
6
|
+
export function translationFilePath(lang, namespace) {
|
|
7
|
+
return `/translations/${lang}/${namespace}.json`;
|
|
8
|
+
}
|
|
9
|
+
export function createFileLoader() {
|
|
10
|
+
if (import.meta.env.SSR) {
|
|
11
|
+
return crelte => new NodeFileLoader(crelte.ssrCache);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return crelte => new ClientFileLoader(crelte.ssrCache);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Translations } from '../translationsPlugin.js';
|
|
2
|
+
import { Crelte, CrelteRequest } from '../../crelte.js';
|
|
3
|
+
export interface TranslationsLoader {
|
|
4
|
+
load(cr: CrelteRequest, namespace: string): Promise<Translations>;
|
|
5
|
+
}
|
|
6
|
+
export type LoaderCreator = (crelte: Crelte) => TranslationsLoader;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/translations/loader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,kBAAkB;IAClC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { LoaderCreator } from './loader/index.js';
|
|
2
|
+
import { Plugin, PluginCreator } from '../plugins/Plugins.js';
|
|
3
|
+
import { Crelte, CrelteRequest } from '../crelte.js';
|
|
4
|
+
import Readable from '../std/stores/Readable.js';
|
|
5
|
+
export type TranslateFunction = (key: string) => string;
|
|
6
|
+
export type TranslateStore = Readable<TranslateFunction>;
|
|
7
|
+
export type Translations = Record<string, string>;
|
|
8
|
+
export type TranslationsPluginOptions = {
|
|
9
|
+
/** use either `createFileLoader()` or `createGlobalLoader()` */
|
|
10
|
+
loader: LoaderCreator;
|
|
11
|
+
/** The common namespace is always loaded */
|
|
12
|
+
loadNamespaces?: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare class TranslationsPlugin implements Plugin {
|
|
15
|
+
private crelte;
|
|
16
|
+
private translations;
|
|
17
|
+
private loader;
|
|
18
|
+
private firstLang;
|
|
19
|
+
get name(): string;
|
|
20
|
+
constructor(crelte: Crelte, opts: TranslationsPluginOptions);
|
|
21
|
+
/**
|
|
22
|
+
* load needs to take a CrelteRequest to be able to get the correct site
|
|
23
|
+
* and globals
|
|
24
|
+
*
|
|
25
|
+
* in crelte 0.5 this should also be possible without a CrelteRequest
|
|
26
|
+
* but with multiple plugin instances / Request State plugins
|
|
27
|
+
*/
|
|
28
|
+
load(cr: CrelteRequest, namespace: string): Promise<Translations>;
|
|
29
|
+
get(lang: string, namespace: string): Translations | null;
|
|
30
|
+
/** @hidden */
|
|
31
|
+
z_createTranslateStore(namespace: string): TranslateStore;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create the TranslationsPlugin
|
|
35
|
+
*
|
|
36
|
+
* #### Setup file loader
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { createTranslations, createFileLoader } from 'crelte/translations';
|
|
40
|
+
*
|
|
41
|
+
* createTranslations({ loader: createFileLoader() });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* #### Setup global loader
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { createTranslations, createGlobalLoader } from 'crelte/translations';
|
|
47
|
+
*
|
|
48
|
+
* createTranslations({ loader: createGlobalLoader() });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Then in you're global export a `translations` globalSet with namespaces
|
|
52
|
+
* as fields, at least `common`.
|
|
53
|
+
*
|
|
54
|
+
* ```graphql
|
|
55
|
+
* translations: globalSet(handle: "translations", siteId: $siteId) {
|
|
56
|
+
* ... on translations_GlobalSet {
|
|
57
|
+
* common
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function createTranslations(opts: TranslationsPluginOptions): PluginCreator;
|
|
63
|
+
export declare function getTranslationsPlugin(crelte?: Crelte): TranslationsPlugin;
|
|
64
|
+
//# sourceMappingURL=translationsPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translationsPlugin.d.ts","sourceRoot":"","sources":["../../src/translations/translationsPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAsB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AAGjD,MAAM,MAAM,iBAAiB,GAAG,CAC/B,GAAG,EAAE,MAAM,KAEP,MAAM,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AACzD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClD,MAAM,MAAM,yBAAyB,GAAG;IACvC,gEAAgE;IAChE,MAAM,EAAE,aAAa,CAAC;IACtB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAIF,qBAAa,kBAAmB,YAAW,MAAM;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,MAAM,CAAqB;IAGnC,OAAO,CAAC,SAAS,CAAgB;IAEjC,IAAI,IAAI,IAAI,MAAM,CAEjB;gBAEW,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB;IAyB3D;;;;;;OAMG;IACG,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAiBvE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIzD,cAAc;IACd,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;CAczD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,yBAAyB,GAC7B,aAAa,CAEf;AAED,wBAAgB,qBAAqB,CACpC,MAAM,GAAE,MAAoB,GAC1B,kBAAkB,CAEpB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { derived } from 'svelte/store';
|
|
2
|
+
import Readable from '../std/stores/Readable.js';
|
|
3
|
+
import { getCrelte } from '../index.js';
|
|
4
|
+
const SSR_KEY = '_translations';
|
|
5
|
+
export class TranslationsPlugin {
|
|
6
|
+
crelte;
|
|
7
|
+
/// Map<`lang-namespace`, Translations>
|
|
8
|
+
translations;
|
|
9
|
+
loader;
|
|
10
|
+
/// When the derived of site is used in the first loadData site is not defined
|
|
11
|
+
/// so we need to store the first language here
|
|
12
|
+
firstLang;
|
|
13
|
+
get name() {
|
|
14
|
+
return 'translations';
|
|
15
|
+
}
|
|
16
|
+
constructor(crelte, opts) {
|
|
17
|
+
this.crelte = crelte;
|
|
18
|
+
this.translations = new Map(crelte.ssrCache.get(SSR_KEY));
|
|
19
|
+
this.firstLang = null;
|
|
20
|
+
if (import.meta.env.DEV && typeof opts?.loader !== 'function') {
|
|
21
|
+
throw new Error('TranslationsPlugin requires a loader, use `createFileLoader()` or ' +
|
|
22
|
+
'`createGlobalLoader()`');
|
|
23
|
+
}
|
|
24
|
+
this.loader = opts.loader(crelte);
|
|
25
|
+
const loadNamespaces = opts.loadNamespaces ?? [];
|
|
26
|
+
// preload default translations
|
|
27
|
+
crelte.events.on('loadGlobalData', async (cr) => {
|
|
28
|
+
this.firstLang = cr.site.language;
|
|
29
|
+
await Promise.all([
|
|
30
|
+
this.load(cr, 'common'),
|
|
31
|
+
...loadNamespaces.map(ns => this.load(cr, ns)),
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* load needs to take a CrelteRequest to be able to get the correct site
|
|
37
|
+
* and globals
|
|
38
|
+
*
|
|
39
|
+
* in crelte 0.5 this should also be possible without a CrelteRequest
|
|
40
|
+
* but with multiple plugin instances / Request State plugins
|
|
41
|
+
*/
|
|
42
|
+
async load(cr, namespace) {
|
|
43
|
+
const lang = cr.site.language;
|
|
44
|
+
const key = `${lang}-${namespace}`;
|
|
45
|
+
const tData = this.translations.get(key);
|
|
46
|
+
if (tData)
|
|
47
|
+
return tData;
|
|
48
|
+
const data = await this.loader.load(cr, namespace);
|
|
49
|
+
this.translations.set(key, data);
|
|
50
|
+
if (import.meta.env.SSR) {
|
|
51
|
+
// only store the translations in the ssrCache during ssr
|
|
52
|
+
// since after that we wont read it again
|
|
53
|
+
cr.ssrCache.set(SSR_KEY, Array.from(this.translations.entries()));
|
|
54
|
+
}
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
get(lang, namespace) {
|
|
58
|
+
return this.translations.get(`${lang}-${namespace}`) ?? null;
|
|
59
|
+
}
|
|
60
|
+
/** @hidden */
|
|
61
|
+
z_createTranslateStore(namespace) {
|
|
62
|
+
const store = derived(this.crelte.router.site, site => {
|
|
63
|
+
return (key) => {
|
|
64
|
+
const lang = site?.language ?? this.firstLang;
|
|
65
|
+
if (!lang)
|
|
66
|
+
throw new Error('no lang');
|
|
67
|
+
const data = this.get(lang, namespace);
|
|
68
|
+
if (!data)
|
|
69
|
+
console.error(`namespace '${namespace}' not loaded`);
|
|
70
|
+
return data?.[key] || key;
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
return new Readable(store);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create the TranslationsPlugin
|
|
78
|
+
*
|
|
79
|
+
* #### Setup file loader
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* import { createTranslations, createFileLoader } from 'crelte/translations';
|
|
83
|
+
*
|
|
84
|
+
* createTranslations({ loader: createFileLoader() });
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* #### Setup global loader
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { createTranslations, createGlobalLoader } from 'crelte/translations';
|
|
90
|
+
*
|
|
91
|
+
* createTranslations({ loader: createGlobalLoader() });
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* Then in you're global export a `translations` globalSet with namespaces
|
|
95
|
+
* as fields, at least `common`.
|
|
96
|
+
*
|
|
97
|
+
* ```graphql
|
|
98
|
+
* translations: globalSet(handle: "translations", siteId: $siteId) {
|
|
99
|
+
* ... on translations_GlobalSet {
|
|
100
|
+
* common
|
|
101
|
+
* }
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function createTranslations(opts) {
|
|
106
|
+
return crelte => new TranslationsPlugin(crelte, opts);
|
|
107
|
+
}
|
|
108
|
+
export function getTranslationsPlugin(crelte = getCrelte()) {
|
|
109
|
+
return crelte.getPlugin('translations');
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/translations/utils.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,MAAU,GAAG,MAAM,CAMtD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
2
|
+
const ALPHABET_LENGTH = ALPHABET.length;
|
|
3
|
+
/**
|
|
4
|
+
* Generates a random token of a specified length.
|
|
5
|
+
*
|
|
6
|
+
* @param length - The desired length of the token.
|
|
7
|
+
* @returns A random token.
|
|
8
|
+
*/
|
|
9
|
+
export function randomToken(length = 8) {
|
|
10
|
+
let s = '';
|
|
11
|
+
for (let i = 0; i < length; i++) {
|
|
12
|
+
s += ALPHABET[Math.floor(Math.random() * ALPHABET_LENGTH)];
|
|
13
|
+
}
|
|
14
|
+
return s;
|
|
15
|
+
}
|
package/dist/vite/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,MAAM,EAON,MAAM,MAAM,CAAC;AAkJd,MAAM,MAAM,aAAa,GAAG;IAC3B,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,MAAM,CAyK3D"}
|
package/dist/vite/index.js
CHANGED
|
@@ -2,11 +2,12 @@ import { relative } from 'node:path';
|
|
|
2
2
|
import MagicString from 'magic-string';
|
|
3
3
|
import { build as viteBuild, } from 'vite';
|
|
4
4
|
import fs from 'node:fs/promises';
|
|
5
|
-
import { initEnvData, modRender, modRenderError, } from '../server/shared.js';
|
|
5
|
+
import { initEnvData, initSites, modRender, modRenderError, } from '../server/shared.js';
|
|
6
6
|
import ServerRouter from '../server/ServerRouter.js';
|
|
7
7
|
import sveltePackage from 'svelte/package.json' with { type: 'json' };
|
|
8
8
|
import { initQueryRoutes } from '../server/queries/queries.js';
|
|
9
9
|
import { PLATFORM, requestToWebRequest, webResponseToResponse, } from '../node/utils.js';
|
|
10
|
+
import QueryError from '../queries/QueryError.js';
|
|
10
11
|
const VIRT_MOD_ID = 'virtual:crelte/svelteComponents';
|
|
11
12
|
const RESOLVED_VIRT_MOD_ID = '\0' + VIRT_MOD_ID;
|
|
12
13
|
async function readFile(path) {
|
|
@@ -253,60 +254,51 @@ export default function crelte(opts) {
|
|
|
253
254
|
};
|
|
254
255
|
}
|
|
255
256
|
async function serveVite(env, vite) {
|
|
256
|
-
|
|
257
|
+
let sites = null;
|
|
258
|
+
const handle = async (nReq, res) => {
|
|
257
259
|
const protocol = vite.config.server.https ? 'https' : 'http';
|
|
258
260
|
const baseUrl = protocol + '://' + nReq.headers['host'];
|
|
259
261
|
const req = requestToWebRequest(baseUrl, nReq);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
serverMod = await vite.ssrLoadModule('./src/server.js', {
|
|
264
|
-
fixStacktrace: true,
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
catch (e) {
|
|
268
|
-
next(e);
|
|
269
|
-
return;
|
|
262
|
+
const serverMod = await vite.ssrLoadModule('./src/server.js');
|
|
263
|
+
if (!sites) {
|
|
264
|
+
sites = await initSites(env);
|
|
270
265
|
}
|
|
271
|
-
|
|
272
|
-
const router = new ServerRouter(env.endpointUrl, env.frontendUrl, env.env, env.sites, {
|
|
273
|
-
endpointToken: env.endpointToken,
|
|
274
|
-
});
|
|
266
|
+
const router = new ServerRouter(env.endpointUrl, env.frontendUrl, env.env, sites, { endpointToken: env.endpointToken });
|
|
275
267
|
await initQueryRoutes(PLATFORM, serverMod, router);
|
|
276
268
|
if (typeof serverMod.routes === 'function') {
|
|
277
269
|
await serverMod.routes(router);
|
|
278
270
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
await webResponseToResponse(response, res);
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
catch (e) {
|
|
287
|
-
vite.ssrFixStacktrace(e);
|
|
288
|
-
next(e);
|
|
271
|
+
const routeResp = await router.z_handle(req);
|
|
272
|
+
if (routeResp) {
|
|
273
|
+
await webResponseToResponse(routeResp, res);
|
|
289
274
|
return;
|
|
290
275
|
}
|
|
291
276
|
let template = await readFile('./index.html');
|
|
292
277
|
template = await vite.transformIndexHtml(nReq.originalUrl ?? '', template);
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
278
|
+
if (serverMod.debugError) {
|
|
279
|
+
let error;
|
|
280
|
+
if (typeof serverMod.debugError === 'number') {
|
|
281
|
+
error = new QueryError({ status: serverMod.debugError });
|
|
282
|
+
}
|
|
283
|
+
else if (typeof serverMod.debugError === 'function') {
|
|
284
|
+
error = serverMod.debugError(req);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
error = new Error('Simulated Error');
|
|
288
|
+
}
|
|
289
|
+
const errorResp = await modRenderError(env, serverMod, error, template, req, { debugError: true });
|
|
290
|
+
await webResponseToResponse(errorResp, res);
|
|
296
291
|
return;
|
|
297
292
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
thrownError = e;
|
|
303
|
-
}
|
|
293
|
+
const response = await modRender(env, sites, serverMod, template, req);
|
|
294
|
+
await webResponseToResponse(response, res);
|
|
295
|
+
};
|
|
296
|
+
vite.middlewares.use(async (nReq, res, next) => {
|
|
304
297
|
try {
|
|
305
|
-
|
|
306
|
-
await webResponseToResponse(response, res);
|
|
307
|
-
return;
|
|
298
|
+
await handle(nReq, res);
|
|
308
299
|
}
|
|
309
300
|
catch (e) {
|
|
301
|
+
vite.ssrFixStacktrace(e);
|
|
310
302
|
next(e);
|
|
311
303
|
}
|
|
312
304
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crelte",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.10",
|
|
4
4
|
"author": "Crelte <support@crelte.com>",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -80,6 +80,10 @@
|
|
|
80
80
|
"types": "./dist/static/index.d.ts",
|
|
81
81
|
"default": "./dist/static/index.js"
|
|
82
82
|
},
|
|
83
|
+
"./translations": {
|
|
84
|
+
"types": "./dist/translations/index.d.ts",
|
|
85
|
+
"default": "./dist/translations/index.js"
|
|
86
|
+
},
|
|
83
87
|
"./std": {
|
|
84
88
|
"types": "./dist/std/index.d.ts",
|
|
85
89
|
"default": "./dist/std/index.js"
|
|
@@ -95,6 +99,10 @@
|
|
|
95
99
|
"./std/intl": {
|
|
96
100
|
"types": "./dist/std/intl/index.d.ts",
|
|
97
101
|
"default": "./dist/std/intl/index.js"
|
|
102
|
+
},
|
|
103
|
+
"./std/rand": {
|
|
104
|
+
"types": "./dist/std/rand/index.d.ts",
|
|
105
|
+
"default": "./dist/std/rand/index.js"
|
|
98
106
|
}
|
|
99
107
|
},
|
|
100
108
|
"dependencies": {
|