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.
Files changed (175) hide show
  1. package/dist/blocks/Blocks.d.ts +41 -4
  2. package/dist/blocks/Blocks.d.ts.map +1 -1
  3. package/dist/blocks/Blocks.js +47 -2
  4. package/dist/blocks/Blocks.svelte +2 -16
  5. package/dist/blocks/Blocks.svelte.d.ts +20 -37
  6. package/dist/blocks/Blocks.svelte.d.ts.map +1 -1
  7. package/dist/blocks/index.d.ts +2 -2
  8. package/dist/blocks/index.d.ts.map +1 -1
  9. package/dist/blocks/index.js +2 -2
  10. package/dist/cookies/ServerCookies.d.ts +1 -1
  11. package/dist/cookies/ServerCookies.js +1 -1
  12. package/dist/cookies/index.d.ts +1 -1
  13. package/dist/crelte.d.ts +21 -10
  14. package/dist/crelte.d.ts.map +1 -1
  15. package/dist/index.d.ts +19 -14
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +17 -13
  18. package/dist/init/client.d.ts +2 -2
  19. package/dist/init/client.d.ts.map +1 -1
  20. package/dist/init/client.js +3 -2
  21. package/dist/init/server.d.ts +7 -6
  22. package/dist/init/server.d.ts.map +1 -1
  23. package/dist/init/server.js +6 -6
  24. package/dist/loadData/Globals.d.ts +3 -3
  25. package/dist/loadData/Globals.js +3 -3
  26. package/dist/loadData/loadData.d.ts +8 -18
  27. package/dist/loadData/loadData.d.ts.map +1 -1
  28. package/dist/loadData/loadData.js +2 -2
  29. package/dist/node/index.d.ts +5 -0
  30. package/dist/node/index.d.ts.map +1 -1
  31. package/dist/node/index.js +84 -35
  32. package/dist/plugins/Events.d.ts +4 -4
  33. package/dist/plugins/Plugins.d.ts +2 -2
  34. package/dist/plugins/index.d.ts +2 -3
  35. package/dist/plugins/index.d.ts.map +1 -1
  36. package/dist/plugins/index.js +2 -1
  37. package/dist/queries/Queries.d.ts +9 -0
  38. package/dist/queries/Queries.d.ts.map +1 -1
  39. package/dist/queries/Queries.js +29 -17
  40. package/dist/queries/QueryError.d.ts +2 -0
  41. package/dist/queries/QueryError.d.ts.map +1 -1
  42. package/dist/queries/QueryError.js +6 -1
  43. package/dist/queries/gql.d.ts +2 -2
  44. package/dist/queries/gql.js +2 -2
  45. package/dist/queries/index.d.ts +7 -5
  46. package/dist/queries/index.d.ts.map +1 -1
  47. package/dist/queries/vars.d.ts +7 -7
  48. package/dist/queries/vars.d.ts.map +1 -1
  49. package/dist/queries/vars.js +10 -8
  50. package/dist/routing/LoadRunner.d.ts +1 -1
  51. package/dist/routing/LoadRunner.js +1 -1
  52. package/dist/routing/index.d.ts +4 -4
  53. package/dist/routing/index.d.ts.map +1 -1
  54. package/dist/routing/route/BaseRoute.d.ts +25 -25
  55. package/dist/routing/route/BaseRoute.js +24 -24
  56. package/dist/routing/route/Request.d.ts +4 -4
  57. package/dist/routing/route/Request.js +4 -4
  58. package/dist/routing/route/Route.d.ts +2 -2
  59. package/dist/routing/route/Route.js +2 -2
  60. package/dist/routing/router/BaseRouter.d.ts +4 -4
  61. package/dist/routing/router/BaseRouter.js +3 -3
  62. package/dist/routing/router/ClientRouter.d.ts +1 -1
  63. package/dist/routing/router/ClientRouter.js +1 -1
  64. package/dist/routing/router/Router.d.ts +27 -25
  65. package/dist/routing/router/Router.d.ts.map +1 -1
  66. package/dist/routing/router/Router.js +24 -21
  67. package/dist/routing/router/ServerRouter.d.ts +1 -1
  68. package/dist/routing/router/ServerRouter.js +1 -1
  69. package/dist/server/CrelteServer.d.ts +5 -5
  70. package/dist/server/CrelteServer.d.ts.map +1 -1
  71. package/dist/server/CrelteServer.js +4 -4
  72. package/dist/server/Request.d.ts +7 -1
  73. package/dist/server/Request.d.ts.map +1 -1
  74. package/dist/server/Request.js +7 -1
  75. package/dist/server/ServerRouter.d.ts +1 -1
  76. package/dist/server/ServerRouter.d.ts.map +1 -1
  77. package/dist/server/index.d.ts +4 -4
  78. package/dist/server/index.d.ts.map +1 -1
  79. package/dist/server/index.js +1 -1
  80. package/dist/server/shared.d.ts +7 -13
  81. package/dist/server/shared.d.ts.map +1 -1
  82. package/dist/server/shared.js +14 -16
  83. package/dist/ssr/SsrCache.d.ts +56 -4
  84. package/dist/ssr/SsrCache.d.ts.map +1 -1
  85. package/dist/ssr/SsrCache.js +94 -20
  86. package/dist/std/index.d.ts +13 -0
  87. package/dist/std/index.d.ts.map +1 -1
  88. package/dist/std/index.js +13 -0
  89. package/dist/std/rand/index.d.ts +34 -0
  90. package/dist/std/rand/index.d.ts.map +1 -0
  91. package/dist/std/rand/index.js +45 -0
  92. package/dist/std/rand/internal.d.ts +8 -0
  93. package/dist/std/rand/internal.d.ts.map +1 -0
  94. package/dist/std/rand/internal.js +15 -0
  95. package/dist/std/stores/Writable.d.ts +1 -1
  96. package/dist/std/stores/Writable.js +1 -1
  97. package/dist/translations/index.d.ts +28 -0
  98. package/dist/translations/index.d.ts.map +1 -0
  99. package/dist/translations/index.js +31 -0
  100. package/dist/translations/loadTranslations.d.ts +23 -0
  101. package/dist/translations/loadTranslations.d.ts.map +1 -0
  102. package/dist/translations/loadTranslations.js +26 -0
  103. package/dist/translations/loader/GlobalLoader.d.ts +34 -0
  104. package/dist/translations/loader/GlobalLoader.d.ts.map +1 -0
  105. package/dist/translations/loader/GlobalLoader.js +45 -0
  106. package/dist/translations/loader/fileLoader/ClientFileLoader.d.ts +10 -0
  107. package/dist/translations/loader/fileLoader/ClientFileLoader.d.ts.map +1 -0
  108. package/dist/translations/loader/fileLoader/ClientFileLoader.js +24 -0
  109. package/dist/translations/loader/fileLoader/NodeFileLoader.d.ts +9 -0
  110. package/dist/translations/loader/fileLoader/NodeFileLoader.d.ts.map +1 -0
  111. package/dist/translations/loader/fileLoader/NodeFileLoader.js +21 -0
  112. package/dist/translations/loader/fileLoader/fileLoader.d.ts +5 -0
  113. package/dist/translations/loader/fileLoader/fileLoader.d.ts.map +1 -0
  114. package/dist/translations/loader/fileLoader/fileLoader.js +16 -0
  115. package/dist/translations/loader/index.d.ts +7 -0
  116. package/dist/translations/loader/index.d.ts.map +1 -0
  117. package/dist/translations/loader/index.js +1 -0
  118. package/dist/translations/translationsPlugin.d.ts +64 -0
  119. package/dist/translations/translationsPlugin.d.ts.map +1 -0
  120. package/dist/translations/translationsPlugin.js +110 -0
  121. package/dist/translations/utils.d.ts +8 -0
  122. package/dist/translations/utils.d.ts.map +1 -0
  123. package/dist/translations/utils.js +15 -0
  124. package/dist/vite/index.d.ts.map +1 -1
  125. package/dist/vite/index.js +30 -38
  126. package/package.json +9 -1
  127. package/src/blocks/Blocks.svelte +3 -78
  128. package/src/blocks/Blocks.ts +63 -6
  129. package/src/blocks/index.ts +2 -2
  130. package/src/cookies/ServerCookies.ts +1 -1
  131. package/src/cookies/index.ts +1 -1
  132. package/src/crelte.ts +21 -10
  133. package/src/index.ts +19 -14
  134. package/src/init/client.ts +3 -2
  135. package/src/init/server.ts +14 -8
  136. package/src/loadData/Globals.ts +3 -3
  137. package/src/loadData/loadData.ts +8 -18
  138. package/src/node/index.ts +100 -39
  139. package/src/plugins/Events.ts +4 -4
  140. package/src/plugins/Plugins.ts +2 -2
  141. package/src/plugins/index.ts +2 -3
  142. package/src/queries/Queries.ts +35 -18
  143. package/src/queries/QueryError.ts +10 -1
  144. package/src/queries/gql.ts +2 -2
  145. package/src/queries/index.ts +7 -4
  146. package/src/queries/vars.ts +12 -8
  147. package/src/routing/LoadRunner.ts +1 -1
  148. package/src/routing/index.ts +13 -3
  149. package/src/routing/route/BaseRoute.ts +25 -25
  150. package/src/routing/route/Request.ts +4 -4
  151. package/src/routing/route/Route.ts +2 -2
  152. package/src/routing/router/BaseRouter.ts +4 -4
  153. package/src/routing/router/ClientRouter.ts +1 -1
  154. package/src/routing/router/Router.ts +28 -25
  155. package/src/routing/router/ServerRouter.ts +1 -1
  156. package/src/server/CrelteServer.ts +5 -5
  157. package/src/server/Request.ts +7 -1
  158. package/src/server/ServerRouter.ts +1 -2
  159. package/src/server/index.ts +17 -3
  160. package/src/server/shared.ts +28 -33
  161. package/src/ssr/SsrCache.ts +104 -22
  162. package/src/std/index.ts +14 -0
  163. package/src/std/rand/index.ts +55 -0
  164. package/src/std/rand/internal.ts +17 -0
  165. package/src/std/stores/Writable.ts +1 -1
  166. package/src/translations/index.ts +56 -0
  167. package/src/translations/loadTranslations.ts +33 -0
  168. package/src/translations/loader/GlobalLoader.ts +62 -0
  169. package/src/translations/loader/fileLoader/ClientFileLoader.ts +40 -0
  170. package/src/translations/loader/fileLoader/NodeFileLoader.ts +32 -0
  171. package/src/translations/loader/fileLoader/fileLoader.ts +19 -0
  172. package/src/translations/loader/index.ts +8 -0
  173. package/src/translations/translationsPlugin.ts +145 -0
  174. package/src/translations/utils.ts +17 -0
  175. 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,8 @@
1
+ /**
2
+ * Generates a random token of a specified length.
3
+ *
4
+ * @param length - The desired length of the token.
5
+ * @returns A random token.
6
+ */
7
+ export declare function randomToken(length?: number): string;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -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
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,MAAM,EAMN,MAAM,MAAM,CAAC;AA8Id,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"}
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"}
@@ -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
- vite.middlewares.use(async (nReq, res, next) => {
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
- let thrownError = null;
261
- let serverMod;
262
- try {
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
- // check if a route matches (todo can i move this out of the middleware?)
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
- try {
280
- const response = await router.z_handle(req);
281
- if (response) {
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
- try {
294
- const response = await modRender(env, serverMod, template, req);
295
- await webResponseToResponse(response, res);
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
- catch (e) {
299
- vite.ssrFixStacktrace(e);
300
- if (typeof serverMod.renderError !== 'function')
301
- return next(e);
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
- const response = await modRenderError(env, serverMod, thrownError, template, req);
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.8",
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": {