@xndrjs/i18n 0.7.0 → 0.8.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 (69) hide show
  1. package/README.md +67 -872
  2. package/dist/codegen/index.d.ts +117 -51
  3. package/dist/codegen/index.js +1585 -93
  4. package/dist/codegen/index.js.map +1 -1
  5. package/dist/index.d.ts +100 -234
  6. package/dist/index.js +74 -638
  7. package/dist/index.js.map +1 -1
  8. package/dist/validation/index.d.ts +5 -0
  9. package/dist/validation/index.js.map +1 -1
  10. package/package.json +2 -2
  11. package/src/IcuTranslationProviderMulti.test.ts +18 -40
  12. package/src/IcuTranslationProviderMulti.ts +27 -37
  13. package/src/audit/audit-dictionaries.ts +1 -1
  14. package/src/audit/run-audit.test.ts +6 -7
  15. package/src/builder-load-registry.ts +26 -5
  16. package/src/builder-loaders.ts +8 -11
  17. package/src/builder-types.test.ts +11 -42
  18. package/src/builder.test.ts +82 -243
  19. package/src/builder.ts +8 -110
  20. package/src/codegen/codegen-config-schema.ts +82 -77
  21. package/src/codegen/config.test.ts +55 -143
  22. package/src/codegen/config.ts +10 -67
  23. package/src/codegen/dictionary-spec-contract.test.ts +28 -0
  24. package/src/codegen/dictionary-spec-contract.ts +138 -0
  25. package/src/codegen/emit/dictionary-schema-file.ts +7 -43
  26. package/src/codegen/emit/instance-file.test.ts +35 -52
  27. package/src/codegen/emit/instance-file.ts +170 -268
  28. package/src/codegen/emit/namespace-loaders-file.test.ts +72 -74
  29. package/src/codegen/emit/namespace-loaders-file.ts +147 -90
  30. package/src/codegen/emit/types-file.test.ts +20 -41
  31. package/src/codegen/emit/types-file.ts +48 -74
  32. package/src/codegen/generate-i18n-types.test.ts +163 -492
  33. package/src/codegen/generate-i18n-types.ts +7 -269
  34. package/src/codegen/paths.ts +0 -14
  35. package/src/codegen/project-locales-set-namespace.test.ts +44 -86
  36. package/src/codegen/read-dictionary.test.ts +27 -9
  37. package/src/codegen/read-dictionary.ts +18 -40
  38. package/src/codegen/regenerate-namespaces.ts +180 -0
  39. package/src/codegen/run-codegen.test.ts +230 -0
  40. package/src/codegen/run-codegen.ts +252 -0
  41. package/src/codegen/types.ts +0 -6
  42. package/src/codegen-config/build-config.ts +4 -23
  43. package/src/codegen-config/codegen-config.test.ts +10 -6
  44. package/src/codegen-config/index.ts +18 -3
  45. package/src/engine.ts +3 -27
  46. package/src/fetch-artifact.ts +16 -0
  47. package/src/i18n-handle.ts +202 -0
  48. package/src/index.ts +15 -34
  49. package/src/project-locales.ts +2 -2
  50. package/src/scope-multi.ts +1 -20
  51. package/src/scope-types.ts +14 -6
  52. package/src/scope.test.ts +3 -312
  53. package/src/serialized-state.test.ts +114 -0
  54. package/src/serialized-state.ts +28 -0
  55. package/src/setup/setup-i18n.test.ts +22 -33
  56. package/src/setup/setup-i18n.ts +22 -27
  57. package/src/types.ts +3 -3
  58. package/src/validation/index.ts +4 -0
  59. package/src/IcuTranslationProviderSingle.test.ts +0 -177
  60. package/src/IcuTranslationProviderSingle.ts +0 -114
  61. package/src/builder-multi.ts +0 -481
  62. package/src/codegen/emit/dictionary-file.test.ts +0 -215
  63. package/src/codegen/emit/dictionary-file.ts +0 -244
  64. package/src/deep-freeze.test.ts +0 -40
  65. package/src/deep-freeze.ts +0 -22
  66. package/src/patch-key.test.ts +0 -186
  67. package/src/patch-key.ts +0 -140
  68. package/src/scope-single.ts +0 -85
  69. package/src/single-builder.ts +0 -153
@@ -1,16 +1,11 @@
1
1
  import { GENERATED_FILE_BANNER, toModuleBasename, toRelativeModuleImport } from "../paths.js";
2
- import type { DeliveryMode } from "../codegen-config-schema.js";
2
+ import type { DeliveryMode, LoaderStrategy } from "../codegen-config-schema.js";
3
3
  import type { ImportExtension } from "../types.js";
4
4
 
5
- /**
6
- * Emits the generated instance module: `createI18n` factory wrapping the ICU provider
7
- * plus runtime projection helpers (`projectDictionaryLocales`, etc.).
8
- */
5
+ /** Emits the generated instance module: `createI18n` factory wrapping the ICU provider. */
9
6
  export interface InstanceFileOptions {
10
- isSingle: boolean;
11
- hasLazy: boolean;
12
7
  typesOutputPath: string;
13
- namespaceLoadersOutputPath?: string;
8
+ namespaceLoadersOutputPath: string;
14
9
  paramsTypeName: string;
15
10
  schemaTypeName: string;
16
11
  localeTypeName: string;
@@ -18,17 +13,16 @@ export interface InstanceFileOptions {
18
13
  factoryName: string;
19
14
  hasLocaleFallback: boolean;
20
15
  hasLocaleType: boolean;
21
- namespaceNames: string[];
22
16
  importExtension: ImportExtension;
23
17
  delivery: DeliveryMode;
24
- deliveryAreaTypeName?: string;
25
- deliveryArtifactsTypeName?: string;
18
+ localeDeliveryAreaConstName?: string;
19
+ loaderStrategy?: LoaderStrategy;
26
20
  }
27
21
 
22
+ const STATE_TYPE = `{ dictionary: InitialSchema; resources?: readonly (readonly [string, string])[] }`;
23
+
28
24
  export function formatInstanceFile(options: InstanceFileOptions): string {
29
25
  const {
30
- isSingle,
31
- hasLazy,
32
26
  typesOutputPath,
33
27
  namespaceLoadersOutputPath,
34
28
  paramsTypeName,
@@ -38,82 +32,44 @@ export function formatInstanceFile(options: InstanceFileOptions): string {
38
32
  factoryName,
39
33
  hasLocaleFallback,
40
34
  hasLocaleType,
41
- namespaceNames,
42
35
  importExtension,
43
36
  delivery,
44
- deliveryAreaTypeName,
45
- deliveryArtifactsTypeName,
37
+ localeDeliveryAreaConstName = "LOCALE_DELIVERY_AREA",
38
+ loaderStrategy = "import",
46
39
  } = options;
47
40
 
48
- const emitDeliveryAreaHelpers = delivery === "custom";
49
- const providerClass = isSingle ? "IcuTranslationProviderSingle" : "IcuTranslationProviderMulti";
41
+ const providerClass = "IcuTranslationProviderMulti";
50
42
  const typesModule = toModuleBasename(typesOutputPath);
51
43
  const typesImport = toRelativeModuleImport(typesModule, importExtension);
52
- const loadersModule = namespaceLoadersOutputPath
53
- ? toModuleBasename(namespaceLoadersOutputPath)
54
- : null;
55
- const loadersImport =
56
- loadersModule && namespaceLoadersOutputPath
57
- ? toRelativeModuleImport(loadersModule, importExtension)
58
- : null;
59
- const dictionaryParamType = hasLazy ? "InitialSchema" : schemaTypeName;
60
- const schemaTypesImport =
61
- hasLazy && delivery === "custom" && deliveryAreaTypeName && deliveryArtifactsTypeName
62
- ? `import type { ${paramsTypeName}, ${schemaTypeName}, InitialSchema, ${deliveryAreaTypeName}, ${deliveryArtifactsTypeName} } from '${typesImport}';\n`
63
- : hasLazy
64
- ? `import type { ${paramsTypeName}, ${schemaTypeName}, InitialSchema } from '${typesImport}';\n`
65
- : `import type { ${paramsTypeName}, ${schemaTypeName} } from '${typesImport}';\n`;
66
- const providerTypeArgs = hasLocaleFallback
67
- ? `${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}, typeof ${localeFallbackConstName}`
68
- : `${schemaTypeName}, ${paramsTypeName}`;
69
- const providerOptions = hasLocaleFallback
70
- ? `, {\n localeFallback: ${localeFallbackConstName},\n ...options,\n }`
71
- : `, options`;
72
- const typesImportLine = hasLocaleType
73
- ? hasLocaleFallback
74
- ? `import { ${localeFallbackConstName}, type ${localeTypeName} } from '${typesImport}';\n`
75
- : `import type { ${localeTypeName} } from '${typesImport}';\n`
76
- : "";
77
- const localesParamType = hasLocaleType ? `readonly ${localeTypeName}[]` : "readonly string[]";
78
- const fallbackArg = hasLocaleFallback ? `, ${localeFallbackConstName}` : "";
79
- const packageImports = formatPackageImports(
80
- providerClass,
81
- isSingle,
82
- hasLazy,
83
- emitDeliveryAreaHelpers
84
- );
85
- const projectionBlock = isSingle
86
- ? formatSingleProjectionBlock(
87
- schemaTypeName,
88
- localesParamType,
89
- fallbackArg,
90
- emitDeliveryAreaHelpers
91
- )
92
- : formatMultiProjectionBlock(
93
- schemaTypeName,
94
- namespaceNames,
95
- localesParamType,
96
- fallbackArg,
97
- emitDeliveryAreaHelpers
98
- );
44
+ const loadersModule = toModuleBasename(namespaceLoadersOutputPath);
45
+ const loadersImport = toRelativeModuleImport(loadersModule, importExtension);
46
+ const schemaTypesImport = `import type { ${paramsTypeName}, ${schemaTypeName}, InitialSchema } from '${typesImport}';\n`;
47
+ const typesImportLine = formatTypesValueImport({
48
+ hasLocaleType,
49
+ hasLocaleFallback,
50
+ localeTypeName,
51
+ localeFallbackConstName,
52
+ localeDeliveryAreaConstName,
53
+ delivery,
54
+ typesImport,
55
+ });
56
+ const packageImports = formatPackageImports(providerClass, loaderStrategy);
57
+ const loadersImportLine =
58
+ loaderStrategy === "fetch"
59
+ ? `import { createNamespaceLoaders } from '${loadersImport}';\n`
60
+ : `import { namespaceLoaders } from '${loadersImport}';\n`;
99
61
 
100
62
  const createFactoryBlock = formatCreateI18nFactory({
101
- isSingle,
102
- hasLazy,
103
- hasLocaleFallback,
104
63
  providerClass,
105
- providerTypeArgs,
106
- providerOptions,
107
- factoryName,
108
- dictionaryParamType,
109
64
  schemaTypeName,
110
65
  paramsTypeName,
111
66
  localeTypeName,
112
- namespaceNames,
113
- loadersImport,
67
+ localeFallbackConstName,
68
+ factoryName,
69
+ hasLocaleFallback,
114
70
  delivery,
115
- ...(deliveryAreaTypeName !== undefined ? { deliveryAreaTypeName } : {}),
116
- ...(deliveryArtifactsTypeName !== undefined ? { deliveryArtifactsTypeName } : {}),
71
+ localeDeliveryAreaConstName,
72
+ loaderStrategy,
117
73
  });
118
74
 
119
75
  return (
@@ -123,233 +79,179 @@ export function formatInstanceFile(options: InstanceFileOptions): string {
123
79
  `} from '@xndrjs/i18n';\n` +
124
80
  schemaTypesImport +
125
81
  typesImportLine +
126
- (hasLazy && loadersImport ? `import { namespaceLoaders } from '${loadersImport}';\n` : "") +
82
+ loadersImportLine +
127
83
  `\n` +
128
- createFactoryBlock +
129
- projectionBlock
84
+ createFactoryBlock
130
85
  );
131
86
  }
132
87
 
133
- function formatCreateI18nFactory(options: {
134
- isSingle: boolean;
135
- hasLazy: boolean;
88
+ function formatTypesValueImport(options: {
89
+ hasLocaleType: boolean;
136
90
  hasLocaleFallback: boolean;
91
+ localeTypeName: string;
92
+ localeFallbackConstName: string;
93
+ localeDeliveryAreaConstName: string;
94
+ delivery: DeliveryMode;
95
+ typesImport: string;
96
+ }): string {
97
+ const {
98
+ hasLocaleType,
99
+ hasLocaleFallback,
100
+ localeTypeName,
101
+ localeFallbackConstName,
102
+ localeDeliveryAreaConstName,
103
+ delivery,
104
+ typesImport,
105
+ } = options;
106
+
107
+ if (!hasLocaleType && delivery !== "custom") {
108
+ return "";
109
+ }
110
+
111
+ const valueNames: string[] = [];
112
+ if (hasLocaleFallback) {
113
+ valueNames.push(localeFallbackConstName);
114
+ }
115
+ if (delivery === "custom") {
116
+ valueNames.push(localeDeliveryAreaConstName);
117
+ }
118
+
119
+ if (valueNames.length > 0 && hasLocaleType) {
120
+ return `import { ${valueNames.join(", ")}, type ${localeTypeName} } from '${typesImport}';\n`;
121
+ }
122
+ if (valueNames.length > 0) {
123
+ return `import { ${valueNames.join(", ")} } from '${typesImport}';\n`;
124
+ }
125
+ if (hasLocaleType) {
126
+ return `import type { ${localeTypeName} } from '${typesImport}';\n`;
127
+ }
128
+ return "";
129
+ }
130
+
131
+ function formatCreateI18nFactory(options: {
137
132
  providerClass: string;
138
- providerTypeArgs: string;
139
- providerOptions: string;
140
- factoryName: string;
141
- dictionaryParamType: string;
142
133
  schemaTypeName: string;
143
134
  paramsTypeName: string;
144
135
  localeTypeName: string;
145
- namespaceNames: string[];
146
- loadersImport: string | null;
136
+ localeFallbackConstName: string;
137
+ factoryName: string;
138
+ hasLocaleFallback: boolean;
147
139
  delivery: DeliveryMode;
148
- deliveryAreaTypeName?: string;
149
- deliveryArtifactsTypeName?: string;
140
+ localeDeliveryAreaConstName: string;
141
+ loaderStrategy: LoaderStrategy;
150
142
  }): string {
151
143
  const {
152
- isSingle,
153
- hasLazy,
154
144
  providerClass,
155
- providerTypeArgs,
156
- providerOptions,
157
- factoryName,
158
- dictionaryParamType,
159
145
  schemaTypeName,
160
146
  paramsTypeName,
161
147
  localeTypeName,
162
- namespaceNames,
163
- loadersImport,
148
+ localeFallbackConstName,
149
+ factoryName,
150
+ hasLocaleFallback,
164
151
  delivery,
165
- deliveryAreaTypeName,
166
- deliveryArtifactsTypeName,
152
+ localeDeliveryAreaConstName,
153
+ loaderStrategy,
167
154
  } = options;
168
155
 
169
- if (isSingle) {
170
- return (
171
- `export function ${factoryName}(\n` +
172
- ` dictionary: ${dictionaryParamType},\n` +
173
- ` options?: { onMissing?: OnMissingTranslation },\n` +
174
- `): I18nScopeSingle<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}> {\n` +
175
- ` return new ${providerClass}<${providerTypeArgs}>(dictionary${providerOptions}).toScope();\n` +
176
- `}\n`
177
- );
178
- }
156
+ const providerTypeArgs = hasLocaleFallback
157
+ ? `${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}, typeof ${localeFallbackConstName}`
158
+ : `${schemaTypeName}, ${paramsTypeName}`;
159
+ const handleReturnType = `I18nHandle<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}>`;
160
+ const handleTypeArgs = `<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}>`;
179
161
 
180
- if (!hasLazy) {
181
- const namespacesLiteral = `[${namespaceNames
182
- .slice()
183
- .sort()
184
- .map((ns) => JSON.stringify(ns))
185
- .join(", ")}] as const`;
186
- return (
187
- `export function ${factoryName}(\n` +
188
- ` dictionary: ${dictionaryParamType},\n` +
189
- ` options?: { onMissing?: OnMissingTranslation },\n` +
190
- `): I18nScopeMulti<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}> {\n` +
191
- ` const engine = new ${providerClass}<${providerTypeArgs}>(dictionary${providerOptions});\n` +
192
- ` return engine.toScope({ namespaces: ${namespacesLiteral} });\n` +
193
- `}\n`
194
- );
195
- }
162
+ const partitionForLocale =
163
+ delivery === "custom"
164
+ ? ` partitionForLocale: (locale) => ${localeDeliveryAreaConstName}[locale],\n`
165
+ : ` partitionForLocale: (locale) => locale,\n`;
196
166
 
197
- if (!loadersImport) {
198
- throw new Error("[Codegen Error] namespaceLoadersOutputPath is required when hasLazy is true.");
199
- }
167
+ const optionsType =
168
+ loaderStrategy === "fetch"
169
+ ? `{ fetchImpl: FetchArtifact; state?: ${STATE_TYPE}; onMissing?: OnMissingTranslation }`
170
+ : `{ state?: ${STATE_TYPE}; onMissing?: OnMissingTranslation }`;
200
171
 
201
- const builderReturnType =
202
- delivery === "custom" && deliveryAreaTypeName && deliveryArtifactsTypeName
203
- ? `I18nBuilderMultiInitial<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}, ${localeTypeName}, ${deliveryAreaTypeName}, ${deliveryArtifactsTypeName}>`
204
- : `I18nBuilderMultiInitial<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}>`;
172
+ const optionsParam =
173
+ loaderStrategy === "fetch" ? ` options: ${optionsType},\n` : ` options?: ${optionsType},\n`;
205
174
 
206
- const multiBuilderTypeArgs =
207
- delivery === "custom" && deliveryAreaTypeName && deliveryArtifactsTypeName
208
- ? `<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}, ${deliveryAreaTypeName}, ${deliveryArtifactsTypeName}>`
209
- : `<${schemaTypeName}, ${paramsTypeName}, ${localeTypeName}>`;
175
+ const namespaceLoadersLine =
176
+ loaderStrategy === "fetch"
177
+ ? ` namespaceLoaders: createNamespaceLoaders(fetchImpl),\n`
178
+ : ` namespaceLoaders,\n`;
210
179
 
211
180
  return (
212
181
  `export function ${factoryName}(\n` +
213
- ` dictionary: ${dictionaryParamType},\n` +
214
- ` options?: { onMissing?: OnMissingTranslation },\n` +
215
- `): ${builderReturnType} {\n` +
216
- ` const engine = new ${providerClass}<${providerTypeArgs}>(dictionary${providerOptions});\n` +
217
- ` return createI18nMultiBuilder${multiBuilderTypeArgs}(engine, {\n` +
218
- ` namespaceLoaders,\n` +
219
- ` } as I18nBuilderMultiOptions<${schemaTypeName}, ${localeTypeName}>);\n` +
182
+ optionsParam +
183
+ `): ${handleReturnType} {\n` +
184
+ formatBody({
185
+ providerClass,
186
+ providerTypeArgs,
187
+ hasLocaleFallback,
188
+ localeFallbackConstName,
189
+ loaderStrategy,
190
+ }) +
191
+ ` engine.seedBuilderResources(normalized.resources);\n` +
192
+ ` return createI18nHandle${handleTypeArgs}(engine, {\n` +
193
+ namespaceLoadersLine +
194
+ partitionForLocale +
195
+ ` } as I18nHandleOptions<${schemaTypeName}, ${localeTypeName}>);\n` +
220
196
  `}\n`
221
197
  );
222
198
  }
223
199
 
224
- function formatPackageImports(
225
- providerClass: string,
226
- isSingle: boolean,
227
- hasLazy: boolean,
228
- emitDeliveryAreaHelpers: boolean
229
- ): string {
230
- const imports = [providerClass];
231
-
232
- if (isSingle) {
233
- imports.push("projectNamespaceLocalesCore");
234
- if (emitDeliveryAreaHelpers) {
235
- imports.push("projectNamespaceForDeliveryAreaCore");
236
- }
237
- imports.push("type I18nScopeSingle");
238
- } else {
239
- imports.push("projectNamespaceLocalesCore", "projectDictionaryLocalesCore");
240
- if (emitDeliveryAreaHelpers) {
241
- imports.push("projectNamespaceForDeliveryAreaCore", "projectDictionaryForDeliveryAreaCore");
242
- }
243
- if (hasLazy) {
244
- imports.push(
245
- "createI18nMultiBuilder",
246
- "type I18nBuilderMultiInitial",
247
- "type I18nBuilderMultiOptions"
248
- );
249
- } else {
250
- imports.push("type I18nScopeMulti");
251
- }
252
- }
253
-
254
- imports.push("type OnMissingTranslation");
255
- return imports.join(",\n ");
256
- }
200
+ function formatBody(options: {
201
+ providerClass: string;
202
+ providerTypeArgs: string;
203
+ hasLocaleFallback: boolean;
204
+ localeFallbackConstName: string;
205
+ loaderStrategy: LoaderStrategy;
206
+ }): string {
207
+ const {
208
+ providerClass,
209
+ providerTypeArgs,
210
+ hasLocaleFallback,
211
+ localeFallbackConstName,
212
+ loaderStrategy,
213
+ } = options;
257
214
 
258
- function formatSingleProjectionBlock(
259
- schemaTypeName: string,
260
- localesParamType: string,
261
- fallbackArg: string,
262
- emitDeliveryAreaHelpers: boolean
263
- ): string {
264
- let block =
265
- `\n` +
266
- `export function projectDictionaryLocales(\n` +
267
- ` dictionary: ${schemaTypeName},\n` +
268
- ` locales: ${localesParamType},\n` +
269
- `): ${schemaTypeName} {\n` +
270
- ` return projectNamespaceLocalesCore(dictionary, locales${fallbackArg});\n` +
271
- `}\n`;
215
+ if (loaderStrategy === "fetch") {
216
+ const engineBlock = hasLocaleFallback
217
+ ? ` const engine = new ${providerClass}<${providerTypeArgs}>(normalized.dictionary, {\n` +
218
+ ` localeFallback: ${localeFallbackConstName},\n` +
219
+ ` ...providerOptions,\n` +
220
+ ` });\n`
221
+ : ` const engine = new ${providerClass}<${providerTypeArgs}>(normalized.dictionary, providerOptions);\n`;
272
222
 
273
- if (emitDeliveryAreaHelpers) {
274
- block +=
275
- `\n` +
276
- `export function projectDictionaryForDeliveryArea(\n` +
277
- ` dictionary: ${schemaTypeName},\n` +
278
- ` areaLocales: ${localesParamType},\n` +
279
- `): ${schemaTypeName} {\n` +
280
- ` return projectNamespaceForDeliveryAreaCore(dictionary, areaLocales${fallbackArg});\n` +
281
- `}\n`;
223
+ return (
224
+ ` const { fetchImpl, state, ...providerOptions } = options;\n` +
225
+ ` const normalized = normalizeI18nCreateInput(state);\n` +
226
+ engineBlock
227
+ );
282
228
  }
283
229
 
284
- return block;
285
- }
286
-
287
- function formatMultiProjectionBlock(
288
- schemaTypeName: string,
289
- namespaceNames: string[],
290
- localesParamType: string,
291
- fallbackArg: string,
292
- emitDeliveryAreaHelpers: boolean
293
- ): string {
294
- const namespaceLocaleOverloads = namespaceNames
295
- .map(
296
- (namespace) =>
297
- `export function projectNamespaceLocales(\n` +
298
- ` dictionary: ${schemaTypeName}["${namespace}"],\n` +
299
- ` locales: ${localesParamType},\n` +
300
- `): ${schemaTypeName}["${namespace}"];`
301
- )
302
- .join("\n");
303
-
304
- const namespaceDeliveryOverloads = emitDeliveryAreaHelpers
305
- ? namespaceNames
306
- .map(
307
- (namespace) =>
308
- `export function projectNamespaceForDeliveryArea(\n` +
309
- ` dictionary: ${schemaTypeName}["${namespace}"],\n` +
310
- ` areaLocales: ${localesParamType},\n` +
311
- `): ${schemaTypeName}["${namespace}"];`
312
- )
313
- .join("\n")
314
- : "";
230
+ const engineBlock = hasLocaleFallback
231
+ ? ` const engine = new ${providerClass}<${providerTypeArgs}>(normalized.dictionary, {\n` +
232
+ ` localeFallback: ${localeFallbackConstName},\n` +
233
+ ` ...providerOptions,\n` +
234
+ ` });\n`
235
+ : ` const engine = new ${providerClass}<${providerTypeArgs}>(normalized.dictionary, providerOptions);\n`;
315
236
 
316
- let block =
317
- `\n` +
318
- `export function projectDictionaryLocales(\n` +
319
- ` dictionary: ${schemaTypeName},\n` +
320
- ` locales: ${localesParamType},\n` +
321
- `): ${schemaTypeName} {\n` +
322
- ` return projectDictionaryLocalesCore(dictionary, locales${fallbackArg});\n` +
323
- `}\n` +
324
- `\n` +
325
- namespaceLocaleOverloads +
326
- `\n` +
327
- `export function projectNamespaceLocales(\n` +
328
- ` dictionary: ${schemaTypeName}[keyof ${schemaTypeName}],\n` +
329
- ` locales: ${localesParamType},\n` +
330
- `): ${schemaTypeName}[keyof ${schemaTypeName}] {\n` +
331
- ` return projectNamespaceLocalesCore(dictionary, locales${fallbackArg});\n` +
332
- `}\n`;
237
+ return (
238
+ ` const { state, ...providerOptions } = options ?? {};\n` +
239
+ ` const normalized = normalizeI18nCreateInput(state);\n` +
240
+ engineBlock
241
+ );
242
+ }
333
243
 
334
- if (emitDeliveryAreaHelpers) {
335
- block +=
336
- `\n` +
337
- `export function projectDictionaryForDeliveryArea(\n` +
338
- ` dictionary: ${schemaTypeName},\n` +
339
- ` areaLocales: ${localesParamType},\n` +
340
- `): ${schemaTypeName} {\n` +
341
- ` return projectDictionaryForDeliveryAreaCore(dictionary, areaLocales${fallbackArg});\n` +
342
- `}\n` +
343
- `\n` +
344
- namespaceDeliveryOverloads +
345
- `\n` +
346
- `export function projectNamespaceForDeliveryArea(\n` +
347
- ` dictionary: ${schemaTypeName}[keyof ${schemaTypeName}],\n` +
348
- ` areaLocales: ${localesParamType},\n` +
349
- `): ${schemaTypeName}[keyof ${schemaTypeName}] {\n` +
350
- ` return projectNamespaceForDeliveryAreaCore(dictionary, areaLocales${fallbackArg});\n` +
351
- `}\n`;
244
+ function formatPackageImports(providerClass: string, loaderStrategy: LoaderStrategy): string {
245
+ const names = [
246
+ providerClass,
247
+ "createI18nHandle",
248
+ "normalizeI18nCreateInput",
249
+ "type I18nHandle",
250
+ "type I18nHandleOptions",
251
+ "type OnMissingTranslation",
252
+ ];
253
+ if (loaderStrategy === "fetch") {
254
+ names.push("type FetchArtifact");
352
255
  }
353
-
354
- return block;
256
+ return names.join(",\n ");
355
257
  }