@funkai/models 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +9 -8
- package/CHANGELOG.md +42 -0
- package/README.md +99 -74
- package/dist/index.d.mts +18 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +27 -1
- package/dist/index.mjs.map +1 -1
- package/docs/catalog/providers.md +1 -1
- package/docs/catalog.md +302 -0
- package/docs/cost-tracking.md +144 -0
- package/docs/guides/setup-resolver.md +15 -30
- package/docs/overview.md +16 -72
- package/docs/provider/configuration.md +20 -43
- package/docs/provider/openrouter.md +22 -41
- package/docs/provider/overview.md +19 -33
- package/docs/provider-resolution.md +210 -0
- package/docs/troubleshooting.md +12 -16
- package/package.json +2 -2
- package/scripts/generate-models.ts +108 -106
- package/src/catalog/index.ts +1 -0
- package/src/cost/calculate.ts +6 -0
- package/src/cost/types.ts +4 -0
- package/src/provider/registry.ts +35 -1
- package/src/provider/types.ts +6 -0
- package/tsconfig.json +12 -5
|
@@ -53,6 +53,8 @@ interface ApiProvider {
|
|
|
53
53
|
/**
|
|
54
54
|
* Convert a provider key to a TypeScript constant name.
|
|
55
55
|
* e.g. "openai" → "OPENAI_MODELS", "meta-llama" → "META_LLAMA_MODELS"
|
|
56
|
+
*
|
|
57
|
+
* @private
|
|
56
58
|
*/
|
|
57
59
|
function toConstName(provider: string): string {
|
|
58
60
|
return `${provider.toUpperCase().replaceAll(/[^A-Z0-9]/g, "_")}_MODELS`;
|
|
@@ -61,6 +63,8 @@ function toConstName(provider: string): string {
|
|
|
61
63
|
/**
|
|
62
64
|
* Lowercase the first character of a string, preserving the rest as-is.
|
|
63
65
|
* e.g. "OpenAI" → "openAI", "GoogleVertex" → "googleVertex", "XAI" → "xAI"
|
|
66
|
+
*
|
|
67
|
+
* @private
|
|
64
68
|
*/
|
|
65
69
|
function lowerFirst(s: string): string {
|
|
66
70
|
if (s.length === 0) {
|
|
@@ -75,6 +79,8 @@ function lowerFirst(s: string): string {
|
|
|
75
79
|
|
|
76
80
|
/**
|
|
77
81
|
* Return the correct indefinite article ("a" or "an") for a word.
|
|
82
|
+
*
|
|
83
|
+
* @private
|
|
78
84
|
*/
|
|
79
85
|
function article(word: string): string {
|
|
80
86
|
if (/^[aeiou]/i.test(word)) {
|
|
@@ -86,6 +92,8 @@ function article(word: string): string {
|
|
|
86
92
|
/**
|
|
87
93
|
* Convert per-million-token rate to per-token rate, rounding to
|
|
88
94
|
* eliminate floating-point noise (e.g. `8.000000000000001e-7`).
|
|
95
|
+
*
|
|
96
|
+
* @private
|
|
89
97
|
*/
|
|
90
98
|
function toPerToken(perMillion: number): number {
|
|
91
99
|
return parseFloat((perMillion / 1_000_000).toPrecision(6));
|
|
@@ -94,6 +102,8 @@ function toPerToken(perMillion: number): number {
|
|
|
94
102
|
/**
|
|
95
103
|
* Format a number for codegen output, using scientific notation for
|
|
96
104
|
* very small values.
|
|
105
|
+
*
|
|
106
|
+
* @private
|
|
97
107
|
*/
|
|
98
108
|
function fmtNum(n: number): string {
|
|
99
109
|
if (n === 0) {
|
|
@@ -105,22 +115,29 @@ function fmtNum(n: number): string {
|
|
|
105
115
|
return String(n);
|
|
106
116
|
}
|
|
107
117
|
|
|
118
|
+
/** @private */
|
|
119
|
+
function extractExampleId(model: ApiModel | undefined): string {
|
|
120
|
+
if (model !== undefined && model !== null) {
|
|
121
|
+
return model.id;
|
|
122
|
+
}
|
|
123
|
+
return "example-id";
|
|
124
|
+
}
|
|
125
|
+
|
|
108
126
|
/**
|
|
109
127
|
* Build the pricing object literal string for a model.
|
|
128
|
+
*
|
|
129
|
+
* @private
|
|
110
130
|
*/
|
|
131
|
+
function extractCostField(cost: ApiModel["cost"], field: "input" | "output"): number {
|
|
132
|
+
if (cost !== undefined && cost !== null) {
|
|
133
|
+
return cost[field] ?? 0;
|
|
134
|
+
}
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
111
138
|
function buildPricing(cost: ApiModel["cost"]): string {
|
|
112
|
-
const costInput
|
|
113
|
-
|
|
114
|
-
return cost.input;
|
|
115
|
-
}
|
|
116
|
-
return 0;
|
|
117
|
-
})();
|
|
118
|
-
const costOutput: number = (() => {
|
|
119
|
-
if (cost !== undefined && cost !== null && cost.output !== undefined && cost.output !== null) {
|
|
120
|
-
return cost.output;
|
|
121
|
-
}
|
|
122
|
-
return 0;
|
|
123
|
-
})();
|
|
139
|
+
const costInput = extractCostField(cost, "input");
|
|
140
|
+
const costOutput = extractCostField(cost, "output");
|
|
124
141
|
const input = toPerToken(costInput);
|
|
125
142
|
const output = toPerToken(costOutput);
|
|
126
143
|
const parts: string[] = [`input: ${fmtNum(input)}`, `output: ${fmtNum(output)}`];
|
|
@@ -142,30 +159,22 @@ function buildPricing(cost: ApiModel["cost"]): string {
|
|
|
142
159
|
|
|
143
160
|
/**
|
|
144
161
|
* Build the modalities object literal string.
|
|
162
|
+
*
|
|
163
|
+
* @private
|
|
145
164
|
*/
|
|
165
|
+
function extractModalityField(
|
|
166
|
+
modalities: ApiModel["modalities"],
|
|
167
|
+
field: "input" | "output",
|
|
168
|
+
): string[] {
|
|
169
|
+
if (modalities !== undefined && modalities !== null) {
|
|
170
|
+
return modalities[field] ?? ["text"];
|
|
171
|
+
}
|
|
172
|
+
return ["text"];
|
|
173
|
+
}
|
|
174
|
+
|
|
146
175
|
function buildModalities(modalities: ApiModel["modalities"]): string {
|
|
147
|
-
const modalInput
|
|
148
|
-
|
|
149
|
-
modalities !== undefined &&
|
|
150
|
-
modalities !== null &&
|
|
151
|
-
modalities.input !== undefined &&
|
|
152
|
-
modalities.input !== null
|
|
153
|
-
) {
|
|
154
|
-
return modalities.input;
|
|
155
|
-
}
|
|
156
|
-
return ["text"];
|
|
157
|
-
})();
|
|
158
|
-
const modalOutput: string[] = (() => {
|
|
159
|
-
if (
|
|
160
|
-
modalities !== undefined &&
|
|
161
|
-
modalities !== null &&
|
|
162
|
-
modalities.output !== undefined &&
|
|
163
|
-
modalities.output !== null
|
|
164
|
-
) {
|
|
165
|
-
return modalities.output;
|
|
166
|
-
}
|
|
167
|
-
return ["text"];
|
|
168
|
-
})();
|
|
176
|
+
const modalInput = extractModalityField(modalities, "input");
|
|
177
|
+
const modalOutput = extractModalityField(modalities, "output");
|
|
169
178
|
const input = JSON.stringify(modalInput);
|
|
170
179
|
const output = JSON.stringify(modalOutput);
|
|
171
180
|
return `{ input: ${input}, output: ${output} }`;
|
|
@@ -173,6 +182,8 @@ function buildModalities(modalities: ApiModel["modalities"]): string {
|
|
|
173
182
|
|
|
174
183
|
/**
|
|
175
184
|
* Build the capabilities object literal string.
|
|
185
|
+
*
|
|
186
|
+
* @private
|
|
176
187
|
*/
|
|
177
188
|
function buildCapabilities(m: ApiModel): string {
|
|
178
189
|
return [
|
|
@@ -185,28 +196,22 @@ function buildCapabilities(m: ApiModel): string {
|
|
|
185
196
|
|
|
186
197
|
/**
|
|
187
198
|
* Extract context window and max output from a model's limit field.
|
|
199
|
+
*
|
|
200
|
+
* @private
|
|
188
201
|
*/
|
|
189
202
|
function getModelLimits(limit: ApiModel["limit"]): { contextWindow: number; maxOutput: number } {
|
|
190
203
|
if (limit === undefined || limit === null) {
|
|
191
204
|
return { contextWindow: 0, maxOutput: 0 };
|
|
192
205
|
}
|
|
193
|
-
const contextWindow
|
|
194
|
-
|
|
195
|
-
return limit.context;
|
|
196
|
-
}
|
|
197
|
-
return 0;
|
|
198
|
-
})();
|
|
199
|
-
const maxOutput: number = (() => {
|
|
200
|
-
if (limit.output !== undefined && limit.output !== null) {
|
|
201
|
-
return limit.output;
|
|
202
|
-
}
|
|
203
|
-
return 0;
|
|
204
|
-
})();
|
|
206
|
+
const contextWindow = limit.context ?? 0;
|
|
207
|
+
const maxOutput = limit.output ?? 0;
|
|
205
208
|
return { contextWindow, maxOutput };
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
/**
|
|
209
212
|
* Escape a string for use in a TypeScript single-quoted string literal.
|
|
213
|
+
*
|
|
214
|
+
* @private
|
|
210
215
|
*/
|
|
211
216
|
function escapeStr(s: string): string {
|
|
212
217
|
return s
|
|
@@ -216,6 +221,11 @@ function escapeStr(s: string): string {
|
|
|
216
221
|
.replaceAll("\r", String.raw`\r`);
|
|
217
222
|
}
|
|
218
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Check whether the staleness cache file indicates a recent fetch.
|
|
226
|
+
*
|
|
227
|
+
* @private
|
|
228
|
+
*/
|
|
219
229
|
function isFresh(reqPath: string): boolean {
|
|
220
230
|
if (!existsSync(reqPath)) {
|
|
221
231
|
return false;
|
|
@@ -286,37 +296,33 @@ export default lauf({
|
|
|
286
296
|
rmSync(ENTRY_DIR, { recursive: true, force: true });
|
|
287
297
|
mkdirSync(ENTRY_DIR, { recursive: true });
|
|
288
298
|
|
|
289
|
-
const providerFiles
|
|
290
|
-
|
|
291
|
-
for (const providerKey of providerKeys) {
|
|
299
|
+
const providerFiles = providerKeys.flatMap((providerKey) => {
|
|
292
300
|
const apiProviderEntry = apiData[providerKey];
|
|
293
301
|
const providerEntry = providers[providerKey];
|
|
294
|
-
if (apiProviderEntry
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
// Write catalog provider file
|
|
319
|
-
const catalogContent = `${BANNER}
|
|
302
|
+
if (apiProviderEntry === undefined || providerEntry === undefined) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
if (apiProviderEntry.models === undefined || apiProviderEntry.models === null) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`models.dev API returned no models for configured provider: ${providerKey}`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
const apiModels = apiProviderEntry.models;
|
|
311
|
+
const constName = toConstName(providerKey);
|
|
312
|
+
const lines = Object.values(apiModels).map((m) => {
|
|
313
|
+
const id = escapeStr(m.id);
|
|
314
|
+
const name = escapeStr(m.name ?? m.id);
|
|
315
|
+
const family = escapeStr(m.family ?? "");
|
|
316
|
+
const pricing = buildPricing(m.cost);
|
|
317
|
+
const { contextWindow, maxOutput } = getModelLimits(m.limit);
|
|
318
|
+
const modalities = buildModalities(m.modalities);
|
|
319
|
+
const capabilities = buildCapabilities(m);
|
|
320
|
+
|
|
321
|
+
return ` { id: '${id}', name: '${name}', provider: '${providerKey}', family: '${family}', pricing: ${pricing}, contextWindow: ${contextWindow}, maxOutput: ${maxOutput}, modalities: ${modalities}, capabilities: { ${capabilities} } },`;
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// Write catalog provider file
|
|
325
|
+
const catalogContent = `${BANNER}
|
|
320
326
|
|
|
321
327
|
import type { ModelDefinition } from '../types.js'
|
|
322
328
|
|
|
@@ -325,24 +331,17 @@ ${lines.join("\n")}
|
|
|
325
331
|
] as const satisfies readonly ModelDefinition[]
|
|
326
332
|
`;
|
|
327
333
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
return "example-id";
|
|
341
|
-
})(),
|
|
342
|
-
);
|
|
343
|
-
const providerName = escapeStr(providerEntry.name);
|
|
344
|
-
const art = article(providerEntry.name);
|
|
345
|
-
const entryContent = `${BANNER}
|
|
334
|
+
const catalogPath = join(CATALOG_DIR, `${providerKey}.ts`);
|
|
335
|
+
writeFileSync(catalogPath, catalogContent, "utf8");
|
|
336
|
+
|
|
337
|
+
// Write per-provider entry point
|
|
338
|
+
const { prefix } = providerEntry;
|
|
339
|
+
const camel = lowerFirst(prefix);
|
|
340
|
+
const [firstModel] = Object.values(apiModels);
|
|
341
|
+
const exampleId = escapeStr(extractExampleId(firstModel));
|
|
342
|
+
const providerName = escapeStr(providerEntry.name);
|
|
343
|
+
const art = article(providerEntry.name);
|
|
344
|
+
const entryContent = `${BANNER}
|
|
346
345
|
|
|
347
346
|
import type { LiteralUnion } from 'type-fest'
|
|
348
347
|
import type { ModelDefinition } from '../catalog/types.js'
|
|
@@ -374,6 +373,7 @@ export type ${prefix}ModelId = (typeof ${constName})[number]['id']
|
|
|
374
373
|
*/
|
|
375
374
|
export const ${camel}Models = ${constName}
|
|
376
375
|
|
|
376
|
+
/** @private */
|
|
377
377
|
const MODEL_INDEX = new Map<string, ModelDefinition>(${constName}.map((m) => [m.id, m]))
|
|
378
378
|
|
|
379
379
|
/**
|
|
@@ -397,13 +397,12 @@ export function ${camel}Model(id: LiteralUnion<${prefix}ModelId, string>): Model
|
|
|
397
397
|
}
|
|
398
398
|
`;
|
|
399
399
|
|
|
400
|
-
|
|
401
|
-
|
|
400
|
+
const entryPath = join(ENTRY_DIR, `${providerKey}.ts`);
|
|
401
|
+
writeFileSync(entryPath, entryContent, "utf8");
|
|
402
402
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
403
|
+
ctx.logger.success(`${providerKey} (${lines.length} models)`);
|
|
404
|
+
return [{ provider: providerKey, constName, count: lines.length }];
|
|
405
|
+
});
|
|
407
406
|
|
|
408
407
|
// Catalog barrel
|
|
409
408
|
const imports = providerFiles
|
|
@@ -414,6 +413,7 @@ export function ${camel}Model(id: LiteralUnion<${prefix}ModelId, string>): Model
|
|
|
414
413
|
|
|
415
414
|
const catalogBarrel = `${BANNER}
|
|
416
415
|
|
|
416
|
+
// oxlint-disable eslint-plugin-import/max-dependencies
|
|
417
417
|
import type { ModelDefinition } from '../types.js'
|
|
418
418
|
${imports}
|
|
419
419
|
|
|
@@ -439,15 +439,17 @@ ${spreads}
|
|
|
439
439
|
types: "./dist/index.d.mts",
|
|
440
440
|
import: "./dist/index.mjs",
|
|
441
441
|
},
|
|
442
|
+
...Object.fromEntries(
|
|
443
|
+
providerFiles.map((p) => [
|
|
444
|
+
`./${p.provider}`,
|
|
445
|
+
{
|
|
446
|
+
types: `./dist/providers/${p.provider}.d.mts`,
|
|
447
|
+
import: `./dist/providers/${p.provider}.mjs`,
|
|
448
|
+
},
|
|
449
|
+
]),
|
|
450
|
+
),
|
|
442
451
|
};
|
|
443
452
|
|
|
444
|
-
for (const p of providerFiles) {
|
|
445
|
-
exportsMap[`./${p.provider}`] = {
|
|
446
|
-
types: `./dist/providers/${p.provider}.d.mts`,
|
|
447
|
-
import: `./dist/providers/${p.provider}.mjs`,
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
|
|
451
453
|
pkg.exports = exportsMap;
|
|
452
454
|
writeFileSync(PACKAGE_JSON_PATH, `${JSON.stringify(pkg, null, 2)}\n`, "utf8");
|
|
453
455
|
ctx.logger.success("package.json exports map updated");
|
package/src/catalog/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type ModelId = LiteralUnion<KnownModelId, string>;
|
|
|
23
23
|
*/
|
|
24
24
|
export const MODELS = GENERATED_MODELS satisfies readonly ModelDefinition[];
|
|
25
25
|
|
|
26
|
+
/** @private */
|
|
26
27
|
const MODEL_INDEX = new Map<string, ModelDefinition>(MODELS.map((m) => [m.id, m]));
|
|
27
28
|
|
|
28
29
|
/**
|
package/src/cost/calculate.ts
CHANGED
|
@@ -8,6 +8,12 @@ import type { TokenUsage } from "@/provider/types.js";
|
|
|
8
8
|
* Multiplies each token count by the corresponding per-token pricing rate.
|
|
9
9
|
* Optional pricing fields (cache) default to `0` when absent.
|
|
10
10
|
*
|
|
11
|
+
* **Reasoning token semantics**: `reasoningTokens` in {@link TokenUsage} are
|
|
12
|
+
* expected to be **exclusive** of `outputTokens` — they are billed separately.
|
|
13
|
+
* If your provider includes reasoning tokens _within_ the `outputTokens` count,
|
|
14
|
+
* you must deduct them before passing usage to this function to avoid
|
|
15
|
+
* double-counting output costs.
|
|
16
|
+
*
|
|
11
17
|
* @param usage - Token counts from a model invocation.
|
|
12
18
|
* @param pricing - Per-token pricing rates for the model.
|
|
13
19
|
* @returns A {@link UsageCost} with per-field and total costs in USD.
|
package/src/cost/types.ts
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each field is the dollar cost for that token category.
|
|
5
5
|
* All fields are non-negative numbers. Fields that don't apply are `0`.
|
|
6
|
+
*
|
|
7
|
+
* **Note**: Values may exhibit floating-point imprecision inherent to
|
|
8
|
+
* JavaScript `number` (IEEE 754 double-precision) arithmetic. Do not rely
|
|
9
|
+
* on exact equality comparisons against expected cost values.
|
|
6
10
|
*/
|
|
7
11
|
export interface UsageCost {
|
|
8
12
|
/** Cost for input tokens. */
|
package/src/provider/registry.ts
CHANGED
|
@@ -59,6 +59,8 @@ export type ProviderRegistry = (modelId: ModelId) => LanguageModel;
|
|
|
59
59
|
*
|
|
60
60
|
* @param config - Provider mappings.
|
|
61
61
|
* @returns A resolver function that maps model IDs to {@link LanguageModel} instances.
|
|
62
|
+
* @throws {Error} If the model ID is empty, missing the `provider/model` format,
|
|
63
|
+
* or the underlying AI SDK registry fails to resolve the provider or model.
|
|
62
64
|
*
|
|
63
65
|
* @example
|
|
64
66
|
* ```typescript
|
|
@@ -86,8 +88,40 @@ export function createProviderRegistry(config: ProviderRegistryConfig): Provider
|
|
|
86
88
|
if (!modelId.trim()) {
|
|
87
89
|
throw new Error("Cannot resolve model: model ID is empty");
|
|
88
90
|
}
|
|
91
|
+
if (!modelId.includes("/")) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Invalid model ID "${modelId}": expected "provider/model" format (e.g. "openai/gpt-4.1")`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
89
96
|
// Cast needed: AI SDK overloads expect `provider/model` template literal,
|
|
90
97
|
// But our ModelId is a branded string union. The runtime validates the format.
|
|
91
|
-
|
|
98
|
+
try {
|
|
99
|
+
// SAFETY: The first cast (`as \`${string}/${string}\``) is safe because we
|
|
100
|
+
// Validated above that `modelId` contains `/`. The second cast (`as
|
|
101
|
+
// LanguageModel`) narrows from the AI SDK's broader LanguageModel union to
|
|
102
|
+
// The v3 specification, which is the only version we support.
|
|
103
|
+
return inner.languageModel(modelId as `${string}/${string}`) as LanguageModel;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error(`Failed to resolve model "${modelId}": ${errorMessage(error)}`, {
|
|
106
|
+
cause: error,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
92
109
|
};
|
|
93
110
|
}
|
|
111
|
+
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Extract a human-readable message from an unknown error value.
|
|
116
|
+
*
|
|
117
|
+
* @param error - The caught error value.
|
|
118
|
+
* @returns The error message string.
|
|
119
|
+
*
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
function errorMessage(error: unknown): string {
|
|
123
|
+
if (error instanceof Error) {
|
|
124
|
+
return error.message;
|
|
125
|
+
}
|
|
126
|
+
return String(error);
|
|
127
|
+
}
|
package/src/provider/types.ts
CHANGED
|
@@ -17,6 +17,12 @@ export type LanguageModel = Extract<BaseLanguageModel, { specificationVersion: "
|
|
|
17
17
|
* Base token counts shared by raw tracking records and final output.
|
|
18
18
|
*
|
|
19
19
|
* All fields are resolved `number` (0 when absent).
|
|
20
|
+
*
|
|
21
|
+
* **Reasoning token semantics**: `reasoningTokens` must be **exclusive** of
|
|
22
|
+
* `outputTokens`. Some providers include reasoning tokens inside the output
|
|
23
|
+
* token count — if so, callers must deduct reasoning tokens from
|
|
24
|
+
* `outputTokens` before constructing this type to avoid double-counting in
|
|
25
|
+
* cost calculations.
|
|
20
26
|
*/
|
|
21
27
|
export interface TokenUsage {
|
|
22
28
|
/** Number of input (prompt) tokens. */
|
package/tsconfig.json
CHANGED
|
@@ -5,21 +5,28 @@
|
|
|
5
5
|
"module": "NodeNext",
|
|
6
6
|
"moduleResolution": "NodeNext",
|
|
7
7
|
"lib": ["ES2024"],
|
|
8
|
+
"types": ["node"],
|
|
9
|
+
|
|
8
10
|
"strict": true,
|
|
9
|
-
"
|
|
11
|
+
"noUncheckedIndexedAccess": true,
|
|
12
|
+
"exactOptionalPropertyTypes": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
15
|
+
|
|
16
|
+
"verbatimModuleSyntax": true,
|
|
17
|
+
"resolveJsonModule": true,
|
|
10
18
|
"skipLibCheck": true,
|
|
11
19
|
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
|
|
13
|
-
"isolatedModules": true,
|
|
20
|
+
|
|
14
21
|
"declaration": true,
|
|
15
22
|
"declarationMap": true,
|
|
16
23
|
"sourceMap": true,
|
|
24
|
+
|
|
17
25
|
"outDir": "./dist",
|
|
18
26
|
"rootDir": ".",
|
|
19
27
|
"paths": {
|
|
20
28
|
"@/*": ["./src/*"]
|
|
21
|
-
}
|
|
22
|
-
"types": ["node"]
|
|
29
|
+
}
|
|
23
30
|
},
|
|
24
31
|
"include": ["src"],
|
|
25
32
|
"exclude": ["node_modules", "dist"]
|