@bleedingdev/modern-js-plugin-i18n 3.2.0-ultramodern.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/dist/cjs/cli/index.js +154 -0
  4. package/dist/cjs/runtime/I18nLink.js +68 -0
  5. package/dist/cjs/runtime/context.js +142 -0
  6. package/dist/cjs/runtime/hooks.js +194 -0
  7. package/dist/cjs/runtime/i18n/backend/config.js +39 -0
  8. package/dist/cjs/runtime/i18n/backend/defaults.js +56 -0
  9. package/dist/cjs/runtime/i18n/backend/defaults.node.js +56 -0
  10. package/dist/cjs/runtime/i18n/backend/index.js +108 -0
  11. package/dist/cjs/runtime/i18n/backend/middleware.common.js +105 -0
  12. package/dist/cjs/runtime/i18n/backend/middleware.js +54 -0
  13. package/dist/cjs/runtime/i18n/backend/middleware.node.js +58 -0
  14. package/dist/cjs/runtime/i18n/backend/sdk-backend.js +175 -0
  15. package/dist/cjs/runtime/i18n/backend/sdk-event.js +64 -0
  16. package/dist/cjs/runtime/i18n/detection/config.js +63 -0
  17. package/dist/cjs/runtime/i18n/detection/index.js +309 -0
  18. package/dist/cjs/runtime/i18n/detection/middleware.js +185 -0
  19. package/dist/cjs/runtime/i18n/detection/middleware.node.js +74 -0
  20. package/dist/cjs/runtime/i18n/index.js +43 -0
  21. package/dist/cjs/runtime/i18n/instance.js +132 -0
  22. package/dist/cjs/runtime/i18n/utils.js +189 -0
  23. package/dist/cjs/runtime/index.js +174 -0
  24. package/dist/cjs/runtime/types.js +18 -0
  25. package/dist/cjs/runtime/utils.js +136 -0
  26. package/dist/cjs/server/index.js +218 -0
  27. package/dist/cjs/shared/deepMerge.js +54 -0
  28. package/dist/cjs/shared/detection.js +105 -0
  29. package/dist/cjs/shared/type.js +18 -0
  30. package/dist/cjs/shared/utils.js +78 -0
  31. package/dist/esm/cli/index.mjs +107 -0
  32. package/dist/esm/rslib-runtime.mjs +18 -0
  33. package/dist/esm/runtime/I18nLink.mjs +32 -0
  34. package/dist/esm/runtime/context.mjs +105 -0
  35. package/dist/esm/runtime/hooks.mjs +151 -0
  36. package/dist/esm/runtime/i18n/backend/config.mjs +5 -0
  37. package/dist/esm/runtime/i18n/backend/defaults.mjs +19 -0
  38. package/dist/esm/runtime/i18n/backend/defaults.node.mjs +19 -0
  39. package/dist/esm/runtime/i18n/backend/index.mjs +74 -0
  40. package/dist/esm/runtime/i18n/backend/middleware.common.mjs +61 -0
  41. package/dist/esm/runtime/i18n/backend/middleware.mjs +7 -0
  42. package/dist/esm/runtime/i18n/backend/middleware.node.mjs +8 -0
  43. package/dist/esm/runtime/i18n/backend/sdk-backend.mjs +141 -0
  44. package/dist/esm/runtime/i18n/backend/sdk-event.mjs +21 -0
  45. package/dist/esm/runtime/i18n/detection/config.mjs +26 -0
  46. package/dist/esm/runtime/i18n/detection/index.mjs +260 -0
  47. package/dist/esm/runtime/i18n/detection/middleware.mjs +132 -0
  48. package/dist/esm/runtime/i18n/detection/middleware.node.mjs +31 -0
  49. package/dist/esm/runtime/i18n/index.mjs +2 -0
  50. package/dist/esm/runtime/i18n/instance.mjs +77 -0
  51. package/dist/esm/runtime/i18n/utils.mjs +140 -0
  52. package/dist/esm/runtime/index.mjs +132 -0
  53. package/dist/esm/runtime/types.mjs +0 -0
  54. package/dist/esm/runtime/utils.mjs +75 -0
  55. package/dist/esm/server/index.mjs +182 -0
  56. package/dist/esm/shared/deepMerge.mjs +20 -0
  57. package/dist/esm/shared/detection.mjs +71 -0
  58. package/dist/esm/shared/type.mjs +0 -0
  59. package/dist/esm/shared/utils.mjs +35 -0
  60. package/dist/esm-node/cli/index.mjs +108 -0
  61. package/dist/esm-node/rslib-runtime.mjs +19 -0
  62. package/dist/esm-node/runtime/I18nLink.mjs +33 -0
  63. package/dist/esm-node/runtime/context.mjs +106 -0
  64. package/dist/esm-node/runtime/hooks.mjs +152 -0
  65. package/dist/esm-node/runtime/i18n/backend/config.mjs +6 -0
  66. package/dist/esm-node/runtime/i18n/backend/defaults.mjs +20 -0
  67. package/dist/esm-node/runtime/i18n/backend/defaults.node.mjs +20 -0
  68. package/dist/esm-node/runtime/i18n/backend/index.mjs +75 -0
  69. package/dist/esm-node/runtime/i18n/backend/middleware.common.mjs +62 -0
  70. package/dist/esm-node/runtime/i18n/backend/middleware.mjs +8 -0
  71. package/dist/esm-node/runtime/i18n/backend/middleware.node.mjs +9 -0
  72. package/dist/esm-node/runtime/i18n/backend/sdk-backend.mjs +142 -0
  73. package/dist/esm-node/runtime/i18n/backend/sdk-event.mjs +22 -0
  74. package/dist/esm-node/runtime/i18n/detection/config.mjs +27 -0
  75. package/dist/esm-node/runtime/i18n/detection/index.mjs +261 -0
  76. package/dist/esm-node/runtime/i18n/detection/middleware.mjs +133 -0
  77. package/dist/esm-node/runtime/i18n/detection/middleware.node.mjs +32 -0
  78. package/dist/esm-node/runtime/i18n/index.mjs +3 -0
  79. package/dist/esm-node/runtime/i18n/instance.mjs +78 -0
  80. package/dist/esm-node/runtime/i18n/utils.mjs +141 -0
  81. package/dist/esm-node/runtime/index.mjs +133 -0
  82. package/dist/esm-node/runtime/types.mjs +1 -0
  83. package/dist/esm-node/runtime/utils.mjs +76 -0
  84. package/dist/esm-node/server/index.mjs +183 -0
  85. package/dist/esm-node/shared/deepMerge.mjs +21 -0
  86. package/dist/esm-node/shared/detection.mjs +72 -0
  87. package/dist/esm-node/shared/type.mjs +1 -0
  88. package/dist/esm-node/shared/utils.mjs +36 -0
  89. package/dist/types/cli/index.d.ts +21 -0
  90. package/dist/types/runtime/I18nLink.d.ts +8 -0
  91. package/dist/types/runtime/context.d.ts +38 -0
  92. package/dist/types/runtime/hooks.d.ts +28 -0
  93. package/dist/types/runtime/i18n/backend/config.d.ts +2 -0
  94. package/dist/types/runtime/i18n/backend/defaults.d.ts +13 -0
  95. package/dist/types/runtime/i18n/backend/defaults.node.d.ts +8 -0
  96. package/dist/types/runtime/i18n/backend/index.d.ts +3 -0
  97. package/dist/types/runtime/i18n/backend/middleware.common.d.ts +14 -0
  98. package/dist/types/runtime/i18n/backend/middleware.d.ts +12 -0
  99. package/dist/types/runtime/i18n/backend/middleware.node.d.ts +13 -0
  100. package/dist/types/runtime/i18n/backend/sdk-backend.d.ts +53 -0
  101. package/dist/types/runtime/i18n/backend/sdk-event.d.ts +9 -0
  102. package/dist/types/runtime/i18n/detection/config.d.ts +11 -0
  103. package/dist/types/runtime/i18n/detection/index.d.ts +50 -0
  104. package/dist/types/runtime/i18n/detection/middleware.d.ts +24 -0
  105. package/dist/types/runtime/i18n/detection/middleware.node.d.ts +17 -0
  106. package/dist/types/runtime/i18n/index.d.ts +3 -0
  107. package/dist/types/runtime/i18n/instance.d.ts +93 -0
  108. package/dist/types/runtime/i18n/utils.d.ts +29 -0
  109. package/dist/types/runtime/index.d.ts +20 -0
  110. package/dist/types/runtime/types.d.ts +15 -0
  111. package/dist/types/runtime/utils.d.ts +33 -0
  112. package/dist/types/server/index.d.ts +8 -0
  113. package/dist/types/shared/deepMerge.d.ts +1 -0
  114. package/dist/types/shared/detection.d.ts +11 -0
  115. package/dist/types/shared/type.d.ts +156 -0
  116. package/dist/types/shared/utils.d.ts +5 -0
  117. package/package.json +136 -0
  118. package/rslib.config.mts +4 -0
  119. package/src/cli/index.ts +245 -0
  120. package/src/runtime/I18nLink.tsx +76 -0
  121. package/src/runtime/context.tsx +281 -0
  122. package/src/runtime/hooks.ts +298 -0
  123. package/src/runtime/i18n/backend/config.ts +10 -0
  124. package/src/runtime/i18n/backend/defaults.node.ts +31 -0
  125. package/src/runtime/i18n/backend/defaults.ts +37 -0
  126. package/src/runtime/i18n/backend/index.ts +181 -0
  127. package/src/runtime/i18n/backend/middleware.common.ts +116 -0
  128. package/src/runtime/i18n/backend/middleware.node.ts +32 -0
  129. package/src/runtime/i18n/backend/middleware.ts +28 -0
  130. package/src/runtime/i18n/backend/sdk-backend.ts +306 -0
  131. package/src/runtime/i18n/backend/sdk-event.ts +39 -0
  132. package/src/runtime/i18n/detection/config.ts +32 -0
  133. package/src/runtime/i18n/detection/index.ts +641 -0
  134. package/src/runtime/i18n/detection/middleware.node.ts +84 -0
  135. package/src/runtime/i18n/detection/middleware.ts +251 -0
  136. package/src/runtime/i18n/index.ts +8 -0
  137. package/src/runtime/i18n/instance.ts +227 -0
  138. package/src/runtime/i18n/utils.ts +351 -0
  139. package/src/runtime/index.tsx +285 -0
  140. package/src/runtime/types.ts +17 -0
  141. package/src/runtime/utils.ts +163 -0
  142. package/src/server/index.ts +406 -0
  143. package/src/shared/deepMerge.ts +38 -0
  144. package/src/shared/detection.ts +131 -0
  145. package/src/shared/type.ts +170 -0
  146. package/src/shared/utils.ts +82 -0
  147. package/tsconfig.json +13 -0
@@ -0,0 +1,131 @@
1
+ import {
2
+ DEFAULT_I18NEXT_DETECTION_OPTIONS,
3
+ mergeDetectionOptions,
4
+ } from '../runtime/i18n/detection/config.js';
5
+ import type { LanguageDetectorOptions } from '../runtime/i18n/instance';
6
+
7
+ /**
8
+ * Detect language from request using the same detection logic as i18next
9
+ * This ensures consistency between server-side and client-side detection
10
+ */
11
+ export function detectLanguageFromRequest(
12
+ req: {
13
+ url: string;
14
+ headers:
15
+ | {
16
+ get: (name: string) => string | null;
17
+ }
18
+ | Headers;
19
+ },
20
+ languages: string[],
21
+ detectionOptions?: LanguageDetectorOptions,
22
+ ): string | null {
23
+ try {
24
+ // Merge user detection options with defaults
25
+ const mergedDetection = detectionOptions
26
+ ? mergeDetectionOptions(detectionOptions)
27
+ : DEFAULT_I18NEXT_DETECTION_OPTIONS;
28
+
29
+ // Get detection order, excluding 'path' and browser-only detectors
30
+ const order = (mergedDetection.order || []).filter(
31
+ (item: string) =>
32
+ !['path', 'localStorage', 'navigator', 'htmlTag', 'subdomain'].includes(
33
+ item,
34
+ ),
35
+ );
36
+
37
+ // If no order specified, use default server-side order
38
+ const detectionOrder =
39
+ order.length > 0 ? order : ['querystring', 'cookie', 'header'];
40
+
41
+ // Helper to get header value
42
+ const getHeader = (name: string): string | null => {
43
+ if (req.headers instanceof Headers) {
44
+ return req.headers.get(name);
45
+ }
46
+ return req.headers.get(name);
47
+ };
48
+
49
+ // Try each detection method in order
50
+ for (const method of detectionOrder) {
51
+ let detectedLang: string | null = null;
52
+
53
+ switch (method) {
54
+ case 'querystring': {
55
+ const lookupKey =
56
+ mergedDetection.lookupQuerystring ||
57
+ DEFAULT_I18NEXT_DETECTION_OPTIONS.lookupQuerystring ||
58
+ 'lng';
59
+ const host = getHeader('host') || 'localhost';
60
+ const url = new URL(req.url, `http://${host}`);
61
+ detectedLang = url.searchParams.get(lookupKey);
62
+ break;
63
+ }
64
+ case 'cookie': {
65
+ const lookupKey =
66
+ mergedDetection.lookupCookie ||
67
+ DEFAULT_I18NEXT_DETECTION_OPTIONS.lookupCookie ||
68
+ 'i18next';
69
+ const cookieHeader = getHeader('Cookie');
70
+ if (cookieHeader) {
71
+ const cookies = cookieHeader
72
+ .split(';')
73
+ .reduce((acc: Record<string, string>, item: string) => {
74
+ const [key, value] = item.trim().split('=');
75
+ if (key && value) {
76
+ acc[key] = value;
77
+ }
78
+ return acc;
79
+ }, {});
80
+ detectedLang = cookies[lookupKey] || null;
81
+ }
82
+ break;
83
+ }
84
+ case 'header': {
85
+ const lookupKey =
86
+ mergedDetection.lookupHeader ||
87
+ DEFAULT_I18NEXT_DETECTION_OPTIONS.lookupHeader ||
88
+ 'accept-language';
89
+ const acceptLanguage = getHeader(lookupKey);
90
+ if (acceptLanguage) {
91
+ // Parse Accept-Language header: "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"
92
+ const languagesList = acceptLanguage
93
+ .split(',')
94
+ .map((lang: string) => {
95
+ const [code, q] = lang.trim().split(';');
96
+ return {
97
+ code: code.split('-')[0], // Extract base language code
98
+ quality: q ? parseFloat(q.split('=')[1]) : 1.0,
99
+ };
100
+ })
101
+ .sort(
102
+ (a: { quality: number }, b: { quality: number }) =>
103
+ b.quality - a.quality,
104
+ );
105
+
106
+ // Find first matching language
107
+ for (const lang of languagesList) {
108
+ if (languages.length === 0 || languages.includes(lang.code)) {
109
+ detectedLang = lang.code;
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ break;
115
+ }
116
+ }
117
+
118
+ // If detected and valid, return it
119
+ if (
120
+ detectedLang &&
121
+ (languages.length === 0 || languages.includes(detectedLang))
122
+ ) {
123
+ return detectedLang;
124
+ }
125
+ }
126
+ } catch (error) {
127
+ // Silently ignore errors
128
+ }
129
+
130
+ return null;
131
+ }
@@ -0,0 +1,170 @@
1
+ import type {
2
+ LanguageDetectorOptions,
3
+ Resources,
4
+ } from '../runtime/i18n/instance';
5
+
6
+ export interface BaseLocaleDetectionOptions {
7
+ localePathRedirect?: boolean;
8
+ i18nextDetector?: boolean;
9
+ languages?: string[];
10
+ fallbackLanguage?: string;
11
+ detection?: LanguageDetectorOptions;
12
+ ignoreRedirectRoutes?: string[] | ((pathname: string) => boolean);
13
+ }
14
+
15
+ export interface LocaleDetectionOptions extends BaseLocaleDetectionOptions {
16
+ localeDetectionByEntry?: Record<string, BaseLocaleDetectionOptions>;
17
+ }
18
+
19
+ /**
20
+ * Options for loading i18n resources via SDK
21
+ */
22
+ export interface I18nSdkLoadOptions {
23
+ /** Single language code to load (e.g., 'en', 'zh') */
24
+ lng?: string;
25
+ /** Single namespace to load (e.g., 'translation', 'common') */
26
+ ns?: string;
27
+ /** Multiple language codes to load */
28
+ lngs?: string[];
29
+ /** Multiple namespaces to load */
30
+ nss?: string[];
31
+ /** Load all available languages and namespaces */
32
+ all?: boolean;
33
+ }
34
+
35
+ /**
36
+ * SDK function to load i18n resources
37
+ * Supports multiple loading modes:
38
+ * 1. Single resource: sdk({ lng: 'en', ns: 'translation' })
39
+ * 2. Batch by languages: sdk({ lngs: ['en', 'zh'], ns: 'translation' })
40
+ * 3. Batch by namespaces: sdk({ lng: 'en', nss: ['translation', 'common'] })
41
+ * 4. Batch by both: sdk({ lngs: ['en', 'zh'], nss: ['translation', 'common'] })
42
+ * 5. Load all: sdk({ all: true }) or sdk()
43
+ *
44
+ * @param options - Loading options
45
+ * @returns Promise that resolves to resources object or the resources object directly
46
+ * Resources format: { [lng]: { [ns]: { [key]: value } } }
47
+ */
48
+ export type I18nSdkLoader = (
49
+ options: I18nSdkLoadOptions,
50
+ ) => Promise<Resources> | Resources;
51
+
52
+ /**
53
+ * Chained backend configuration
54
+ * Used internally when both loadPath and sdk are provided
55
+ */
56
+ export interface ChainedBackendConfig {
57
+ _useChainedBackend: boolean;
58
+ _chainedBackendConfig: {
59
+ backendOptions: Array<Record<string, unknown>>;
60
+ };
61
+ cacheHitMode?: 'none' | 'refresh' | 'refreshAndUpdateStore';
62
+ }
63
+
64
+ /**
65
+ * Extended backend options that may include chained backend configuration
66
+ */
67
+ export type ExtendedBackendOptions = BaseBackendOptions &
68
+ Partial<ChainedBackendConfig>;
69
+
70
+ export interface BaseBackendOptions {
71
+ enabled?: boolean;
72
+ loadPath?: string;
73
+ addPath?: string;
74
+ /**
75
+ * Cache hit mode for chained backend (only effective when both `loadPath` and `sdk` are provided)
76
+ *
77
+ * - `'none'` (default): If the first backend returns resources, stop and don't try the next backend
78
+ * - `'refresh'`: Try to refresh the cache by loading from the next backend and update the cache
79
+ * - `'refreshAndUpdateStore'`: Try to refresh the cache by loading from the next backend,
80
+ * update the cache and also update the i18next resource store. This allows FS/HTTP resources
81
+ * to be displayed first, then SDK resources will update them asynchronously.
82
+ *
83
+ * @default 'refreshAndUpdateStore' when both loadPath and sdk are provided
84
+ */
85
+ cacheHitMode?: 'none' | 'refresh' | 'refreshAndUpdateStore';
86
+ /**
87
+ * SDK function to load i18n resources dynamically
88
+ *
89
+ * **Important**: In `modern.config.ts`, you can only set this to `true` or any identifier
90
+ * to enable SDK mode. The actual SDK function must be provided in `modern.runtime.ts`
91
+ * via `initOptions.backend.sdk`.
92
+ *
93
+ * When both `loadPath` (or FS backend) and `sdk` are provided, the plugin will automatically
94
+ * use `i18next-chained-backend` to chain multiple backends. The order will be:
95
+ * 1. HTTP/FS backend (primary) - loads from `loadPath` or file system first for quick initial display
96
+ * 2. SDK backend (fallback/update) - loads from the SDK function to update/refresh translations
97
+ *
98
+ * With `cacheHitMode: 'refreshAndUpdateStore'` (default), FS/HTTP resources will be displayed
99
+ * immediately, then SDK resources will be loaded asynchronously to update the translations.
100
+ *
101
+ * If only `sdk` is provided, it will be used instead of the default HTTP/FS backend
102
+ *
103
+ * @example In modern.config.ts - enable SDK mode
104
+ * ```ts
105
+ * backend: {
106
+ * enabled: true,
107
+ * sdk: true, // or any identifier, just to enable SDK mode
108
+ * }
109
+ * ```
110
+ *
111
+ * @example In modern.runtime.ts - provide the actual SDK function
112
+ * ```ts
113
+ * export default defineRuntimeConfig({
114
+ * i18n: {
115
+ * initOptions: {
116
+ * backend: {
117
+ * sdk: async (options) => {
118
+ * // Your SDK implementation
119
+ * if (options.all) {
120
+ * return await mySdk.getAllResources();
121
+ * }
122
+ * if (options.lng && options.ns) {
123
+ * return await mySdk.getResource(options.lng, options.ns);
124
+ * }
125
+ * // Handle other cases...
126
+ * }
127
+ * }
128
+ * }
129
+ * }
130
+ * });
131
+ * ```
132
+ *
133
+ * @example Single resource loading
134
+ * ```ts
135
+ * sdk: async (options) => {
136
+ * if (options.lng && options.ns) {
137
+ * const response = await fetch(`/api/i18n/${options.lng}/${options.ns}`);
138
+ * return response.json();
139
+ * }
140
+ * }
141
+ * ```
142
+ *
143
+ * @example Load all resources at once
144
+ * ```ts
145
+ * sdk: async (options) => {
146
+ * if (options?.all) {
147
+ * // Load all languages and namespaces
148
+ * return await mySdk.getAllResources();
149
+ * }
150
+ * // Handle other cases...
151
+ * }
152
+ * ```
153
+ *
154
+ * @example Batch loading
155
+ * ```ts
156
+ * sdk: async (options) => {
157
+ * if (options?.lngs && options?.nss) {
158
+ * // Load multiple languages and namespaces
159
+ * return await mySdk.getBatchResources(options.lngs, options.nss);
160
+ * }
161
+ * // Handle single or other cases...
162
+ * }
163
+ * ```
164
+ */
165
+ sdk?: I18nSdkLoader | boolean | string;
166
+ }
167
+
168
+ export interface BackendOptions extends BaseBackendOptions {
169
+ backendOptionsByEntry?: Record<string, BaseBackendOptions>;
170
+ }
@@ -0,0 +1,82 @@
1
+ import type {
2
+ BackendOptions,
3
+ BaseBackendOptions,
4
+ BaseLocaleDetectionOptions,
5
+ LocaleDetectionOptions,
6
+ } from './type';
7
+
8
+ export function getEntryConfig<T extends Record<string, any>>(
9
+ entryName: string,
10
+ config: T,
11
+ entryKey: string,
12
+ ): T | undefined {
13
+ const entryConfigMap = (config as any)[entryKey] as
14
+ | Record<string, T>
15
+ | undefined;
16
+ return entryConfigMap?.[entryName];
17
+ }
18
+
19
+ export function removeEntryConfigKey<T extends Record<string, any>>(
20
+ config: T,
21
+ entryKey: string,
22
+ ): Omit<T, typeof entryKey> {
23
+ const { [entryKey]: _, ...rest } = config;
24
+ return rest;
25
+ }
26
+
27
+ export function getLocaleDetectionOptions(
28
+ entryName: string,
29
+ localeDetection: BaseLocaleDetectionOptions,
30
+ ): BaseLocaleDetectionOptions {
31
+ const fullConfig = localeDetection as LocaleDetectionOptions;
32
+ const entryConfig = getEntryConfig(
33
+ entryName,
34
+ fullConfig,
35
+ 'localeDetectionByEntry',
36
+ );
37
+
38
+ if (entryConfig) {
39
+ const globalConfig = removeEntryConfigKey(
40
+ fullConfig,
41
+ 'localeDetectionByEntry',
42
+ );
43
+ return {
44
+ ...globalConfig,
45
+ ...entryConfig,
46
+ };
47
+ }
48
+
49
+ if ('localeDetectionByEntry' in fullConfig) {
50
+ return removeEntryConfigKey(fullConfig, 'localeDetectionByEntry');
51
+ }
52
+
53
+ return localeDetection;
54
+ }
55
+
56
+ export function getBackendOptions(
57
+ entryName: string,
58
+ backend: BaseBackendOptions,
59
+ ): BaseBackendOptions {
60
+ const fullConfig = backend as BackendOptions;
61
+ const entryConfig = getEntryConfig(
62
+ entryName,
63
+ fullConfig,
64
+ 'backendOptionsByEntry',
65
+ );
66
+ if (entryConfig) {
67
+ const globalConfig = removeEntryConfigKey(
68
+ fullConfig,
69
+ 'backendOptionsByEntry',
70
+ );
71
+ return {
72
+ ...globalConfig,
73
+ ...entryConfig,
74
+ };
75
+ }
76
+
77
+ if ('backendOptionsByEntry' in fullConfig) {
78
+ return removeEntryConfigKey(fullConfig, 'backendOptionsByEntry');
79
+ }
80
+
81
+ return backend;
82
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "@modern-js/tsconfig/base",
3
+ "compilerOptions": {
4
+ "declaration": false,
5
+ "lib": ["DOM", "ESNext", "dom.iterable"],
6
+ "jsx": "preserve",
7
+ "baseUrl": "./",
8
+ "isolatedModules": true,
9
+ "paths": {},
10
+ "rootDir": "./src"
11
+ },
12
+ "include": ["src", "types"]
13
+ }