git-coco 0.16.2 → 0.17.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.
- package/dist/index.d.ts +15 -6
- package/dist/index.esm.mjs +1281 -1279
- package/dist/index.js +1280 -1278
- package/package.json +3 -3
package/dist/index.esm.mjs
CHANGED
|
@@ -18,22 +18,22 @@ import prettyMilliseconds from 'pretty-ms';
|
|
|
18
18
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
19
19
|
import { ChatOllama } from '@langchain/ollama';
|
|
20
20
|
import { ChatOpenAI } from '@langchain/openai';
|
|
21
|
-
import { StructuredOutputParser, BaseOutputParser } from '@langchain/core/output_parsers';
|
|
21
|
+
import { StructuredOutputParser, BaseOutputParser, OutputParserException, StringOutputParser } from '@langchain/core/output_parsers';
|
|
22
22
|
import { simpleGit } from 'simple-git';
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
23
|
+
import { BaseLangChain, BaseLanguageModel } from '@langchain/core/language_models/base';
|
|
24
|
+
import { ensureConfig, Runnable } from '@langchain/core/runnables';
|
|
25
25
|
import { RUN_KEY } from '@langchain/core/outputs';
|
|
26
26
|
import { CallbackManager, parseCallbackConfigArg } from '@langchain/core/callbacks/manager';
|
|
27
|
-
import
|
|
28
|
-
import
|
|
27
|
+
import '@langchain/core/utils/json_patch';
|
|
28
|
+
import pQueue from 'p-queue';
|
|
29
|
+
import { Document, BaseDocumentTransformer } from '@langchain/core/documents';
|
|
30
|
+
import { createTwoFilesPatch } from 'diff';
|
|
29
31
|
import '@langchain/core/messages';
|
|
30
32
|
import '@langchain/core/memory';
|
|
31
33
|
import '@langchain/core/chat_history';
|
|
32
34
|
import '@langchain/core/utils/tiktoken';
|
|
33
35
|
import '@langchain/core/utils/async_caller';
|
|
34
36
|
import '@langchain/core/utils/env';
|
|
35
|
-
import '@langchain/core/utils/json_patch';
|
|
36
|
-
import { createTwoFilesPatch } from 'diff';
|
|
37
37
|
import { minimatch } from 'minimatch';
|
|
38
38
|
import { encoding_for_model } from 'tiktoken';
|
|
39
39
|
import { exec } from 'child_process';
|
|
@@ -46,7 +46,7 @@ import * as readline from 'readline';
|
|
|
46
46
|
/**
|
|
47
47
|
* Current build version from package.json
|
|
48
48
|
*/
|
|
49
|
-
const BUILD_VERSION = "0.
|
|
49
|
+
const BUILD_VERSION = "0.17.0";
|
|
50
50
|
|
|
51
51
|
const isInteractive = (config) => {
|
|
52
52
|
return config?.mode === 'interactive' || !!config?.interactive;
|
|
@@ -173,51 +173,175 @@ const SUMMARIZE_PROMPT = new PromptTemplate({
|
|
|
173
173
|
template: template$5,
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Base class for all LangChain-related errors
|
|
178
|
+
*/
|
|
179
|
+
class LangChainError extends Error {
|
|
180
|
+
constructor(message, context) {
|
|
181
|
+
super(message);
|
|
182
|
+
this.context = context;
|
|
183
|
+
this.name = this.constructor.name;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Configuration-related errors (invalid service configs, missing settings, etc.)
|
|
188
|
+
*/
|
|
189
|
+
class LangChainConfigurationError extends LangChainError {
|
|
190
|
+
constructor(message, context) {
|
|
191
|
+
super(message, context);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Input validation errors (missing required parameters, invalid types, etc.)
|
|
196
|
+
*/
|
|
197
|
+
class LangChainValidationError extends LangChainError {
|
|
198
|
+
constructor(message, context) {
|
|
199
|
+
super(message, context);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Runtime execution errors (LLM failures, parsing errors, etc.)
|
|
204
|
+
*/
|
|
205
|
+
class LangChainExecutionError extends LangChainError {
|
|
206
|
+
constructor(message, context) {
|
|
207
|
+
super(message, context);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Authentication-related errors (missing API keys, invalid credentials, etc.)
|
|
212
|
+
*/
|
|
213
|
+
class LangChainAuthenticationError extends LangChainError {
|
|
214
|
+
constructor(message, context) {
|
|
215
|
+
super(message, context);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Validates that a required parameter is not null or undefined
|
|
221
|
+
*/
|
|
222
|
+
function validateRequired(value, paramName, functionName) {
|
|
223
|
+
if (value === null || value === undefined) {
|
|
224
|
+
throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Required parameter '${paramName}' is missing`, { paramName, functionName, value });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Validates that a string parameter is not empty
|
|
229
|
+
*/
|
|
230
|
+
function validateNonEmptyString(value, paramName, functionName) {
|
|
231
|
+
validateRequired(value, paramName, functionName);
|
|
232
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
233
|
+
throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty string`, { paramName, functionName, value, type: typeof value });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Validates that an array parameter is not empty
|
|
238
|
+
*/
|
|
239
|
+
function validateNonEmptyArray(value, paramName, functionName) {
|
|
240
|
+
validateRequired(value, paramName, functionName);
|
|
241
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
242
|
+
throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty array`, { paramName, functionName, value, isArray: Array.isArray(value), length: Array.isArray(value) ? value.length : undefined });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Validates that a provider is supported
|
|
247
|
+
*/
|
|
248
|
+
function validateProvider(provider, functionName) {
|
|
249
|
+
const validProviders = ['openai', 'anthropic', 'ollama'];
|
|
250
|
+
if (!validProviders.includes(provider)) {
|
|
251
|
+
throw new LangChainConfigurationError(`${functionName ? `${functionName}: ` : ''}Invalid provider '${provider}'. Supported providers: ${validProviders.join(', ')}`, { provider, validProviders, functionName });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Validates that a model is valid for the given provider
|
|
256
|
+
*/
|
|
257
|
+
function validateModel(model, provider, functionName) {
|
|
258
|
+
validateRequired(model, 'model', functionName);
|
|
259
|
+
if (typeof model !== 'string' || model.trim() === '') {
|
|
260
|
+
throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Model must be a non-empty string`, { model, provider, functionName });
|
|
261
|
+
}
|
|
262
|
+
// Additional provider-specific validation could be added here
|
|
263
|
+
// For now, we trust the TypeScript types
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Validates that a service configuration is complete and valid
|
|
267
|
+
*/
|
|
268
|
+
function validateServiceConfig(service, functionName) {
|
|
269
|
+
validateRequired(service, 'service', functionName);
|
|
270
|
+
if (typeof service !== 'object') {
|
|
271
|
+
throw new LangChainConfigurationError(`${functionName ? `${functionName}: ` : ''}Service configuration must be an object`, { service, functionName });
|
|
272
|
+
}
|
|
273
|
+
const serviceObj = service;
|
|
274
|
+
validateProvider(serviceObj.provider, functionName);
|
|
275
|
+
validateModel(serviceObj.model, serviceObj.provider, functionName);
|
|
276
|
+
// Validate authentication
|
|
277
|
+
if (!serviceObj.authentication || typeof serviceObj.authentication !== 'object') {
|
|
278
|
+
throw new LangChainConfigurationError(`${functionName ? `${functionName}: ` : ''}Service configuration must include authentication`, { service, functionName });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
176
282
|
/**
|
|
177
283
|
* Retrieves the provider and model from the given configuration object.
|
|
178
284
|
* @param config The configuration object.
|
|
179
285
|
* @returns An object containing the provider and model.
|
|
180
|
-
* @throws
|
|
286
|
+
* @throws LangChainConfigurationError if the configuration is invalid or missing required properties.
|
|
181
287
|
*/
|
|
182
288
|
function getModelAndProviderFromConfig(config) {
|
|
289
|
+
validateRequired(config, 'config', 'getModelAndProviderFromConfig');
|
|
183
290
|
if (!config.service) {
|
|
184
|
-
throw new
|
|
291
|
+
throw new LangChainConfigurationError('getModelAndProviderFromConfig: Service configuration is missing', { config });
|
|
185
292
|
}
|
|
293
|
+
validateServiceConfig(config.service, 'getModelAndProviderFromConfig');
|
|
186
294
|
const { provider, model } = config.service;
|
|
187
|
-
if (!model || !provider) {
|
|
188
|
-
throw new Error(`Invalid service: ${config.service}`);
|
|
189
|
-
}
|
|
190
295
|
return { provider, model };
|
|
191
296
|
}
|
|
192
297
|
/**
|
|
193
298
|
* Retrieve appropriate API key based on selected model
|
|
194
|
-
* @param
|
|
195
|
-
* @
|
|
196
|
-
* @
|
|
299
|
+
* @param config The configuration object
|
|
300
|
+
* @returns API Key or empty string if no authentication required
|
|
301
|
+
* @throws LangChainAuthenticationError if authentication is required but missing
|
|
197
302
|
*/
|
|
198
303
|
function getApiKeyForModel(config) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
default:
|
|
204
|
-
return getDefaultServiceApiKey(config);
|
|
205
|
-
}
|
|
304
|
+
validateRequired(config, 'config', 'getApiKeyForModel');
|
|
305
|
+
// This function now simply delegates to getDefaultServiceApiKey
|
|
306
|
+
// The switch statement was unnecessary since all providers use the same logic
|
|
307
|
+
return getDefaultServiceApiKey(config);
|
|
206
308
|
}
|
|
207
309
|
/**
|
|
208
310
|
* Retrieves the default service API key from the given configuration.
|
|
209
311
|
* @param config The configuration object.
|
|
210
|
-
* @returns The default service API key.
|
|
312
|
+
* @returns The default service API key or empty string for services that don't require authentication.
|
|
313
|
+
* @throws LangChainAuthenticationError if authentication is required but invalid.
|
|
211
314
|
*/
|
|
212
315
|
function getDefaultServiceApiKey(config) {
|
|
316
|
+
validateRequired(config, 'config', 'getDefaultServiceApiKey');
|
|
317
|
+
validateServiceConfig(config.service, 'getDefaultServiceApiKey');
|
|
213
318
|
const service = config.service;
|
|
319
|
+
const { provider } = service;
|
|
320
|
+
// Check if authentication is required for this provider
|
|
321
|
+
const requiresAuth = provider === 'openai' || provider === 'anthropic';
|
|
214
322
|
if (service.authentication.type === 'APIKey') {
|
|
215
|
-
|
|
323
|
+
const apiKey = service.authentication.credentials?.apiKey;
|
|
324
|
+
if (requiresAuth && (!apiKey || apiKey.trim() === '')) {
|
|
325
|
+
throw new LangChainAuthenticationError(`getDefaultServiceApiKey: API key is required for ${provider} provider but not provided`, { provider, authenticationType: service.authentication.type });
|
|
326
|
+
}
|
|
327
|
+
return apiKey || '';
|
|
328
|
+
}
|
|
329
|
+
if (service.authentication.type === 'OAuth') {
|
|
330
|
+
const token = service.authentication.credentials?.token;
|
|
331
|
+
if (requiresAuth && (!token || token.trim() === '')) {
|
|
332
|
+
throw new LangChainAuthenticationError(`getDefaultServiceApiKey: OAuth token is required for ${provider} provider but not provided`, { provider, authenticationType: service.authentication.type });
|
|
333
|
+
}
|
|
334
|
+
return token || '';
|
|
216
335
|
}
|
|
217
|
-
|
|
218
|
-
|
|
336
|
+
if (service.authentication.type === 'None') {
|
|
337
|
+
if (requiresAuth) {
|
|
338
|
+
throw new LangChainAuthenticationError(`getDefaultServiceApiKey: ${provider} provider requires authentication but 'None' was configured`, { provider, authenticationType: service.authentication.type });
|
|
339
|
+
}
|
|
340
|
+
return '';
|
|
219
341
|
}
|
|
220
|
-
|
|
342
|
+
// This should never be reached due to TypeScript type checking, but included for safety
|
|
343
|
+
const authType = service.authentication.type;
|
|
344
|
+
throw new LangChainConfigurationError(`getDefaultServiceApiKey: Unknown authentication type '${authType}'`, { provider, authentication: service.authentication });
|
|
221
345
|
}
|
|
222
346
|
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
223
347
|
provider: 'openai',
|
|
@@ -231,6 +355,17 @@ const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
|
231
355
|
},
|
|
232
356
|
},
|
|
233
357
|
};
|
|
358
|
+
const DEFAULT_ANTHROPIC_LLM_SERVICE = {
|
|
359
|
+
provider: 'anthropic',
|
|
360
|
+
model: 'claude-3-5-sonnet-20240620',
|
|
361
|
+
temperature: 0.32,
|
|
362
|
+
authentication: {
|
|
363
|
+
type: 'APIKey',
|
|
364
|
+
credentials: {
|
|
365
|
+
apiKey: '',
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
};
|
|
234
369
|
const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
235
370
|
provider: 'ollama',
|
|
236
371
|
model: 'llama3',
|
|
@@ -238,24 +373,33 @@ const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
|
238
373
|
maxConcurrent: 1,
|
|
239
374
|
tokenLimit: 2024,
|
|
240
375
|
temperature: 0.4,
|
|
376
|
+
maxParsingAttempts: 3,
|
|
241
377
|
authentication: {
|
|
242
378
|
type: 'None',
|
|
243
379
|
credentials: undefined,
|
|
244
380
|
},
|
|
245
381
|
};
|
|
246
382
|
/**
|
|
247
|
-
* Retrieves the default service configuration based on the provided
|
|
248
|
-
* @param provider - The
|
|
249
|
-
* @param model - The optional model to be used.
|
|
250
|
-
* @returns The default service configuration.
|
|
251
|
-
* @throws
|
|
383
|
+
* Retrieves the default service configuration based on the provided provider and optional model.
|
|
384
|
+
* @param provider - The LLM provider (openai, anthropic, ollama).
|
|
385
|
+
* @param model - The optional model to be used. If not provided, uses the default model for the provider.
|
|
386
|
+
* @returns The default service configuration for the specified provider.
|
|
387
|
+
* @throws LangChainConfigurationError if the provider is invalid or unsupported.
|
|
252
388
|
*/
|
|
253
389
|
function getDefaultServiceConfigFromAlias(provider, model) {
|
|
390
|
+
validateRequired(provider, 'provider', 'getDefaultServiceConfigFromAlias');
|
|
391
|
+
// Validate model if provided
|
|
392
|
+
if (model !== undefined) {
|
|
393
|
+
validateRequired(model, 'model', 'getDefaultServiceConfigFromAlias');
|
|
394
|
+
if (typeof model !== 'string' || model.trim() === '') {
|
|
395
|
+
throw new LangChainConfigurationError('getDefaultServiceConfigFromAlias: Model must be a non-empty string when provided', { provider, model });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
254
398
|
switch (provider) {
|
|
255
399
|
case 'anthropic':
|
|
256
400
|
return {
|
|
257
|
-
...
|
|
258
|
-
model: model ||
|
|
401
|
+
...DEFAULT_ANTHROPIC_LLM_SERVICE,
|
|
402
|
+
model: model || DEFAULT_ANTHROPIC_LLM_SERVICE.model,
|
|
259
403
|
};
|
|
260
404
|
case 'ollama':
|
|
261
405
|
return {
|
|
@@ -263,11 +407,12 @@ function getDefaultServiceConfigFromAlias(provider, model) {
|
|
|
263
407
|
model: model || DEFAULT_OLLAMA_LLM_SERVICE.model,
|
|
264
408
|
};
|
|
265
409
|
case 'openai':
|
|
266
|
-
default:
|
|
267
410
|
return {
|
|
268
411
|
...DEFAULT_OPENAI_LLM_SERVICE,
|
|
269
412
|
model: model || DEFAULT_OPENAI_LLM_SERVICE.model,
|
|
270
413
|
};
|
|
414
|
+
default:
|
|
415
|
+
throw new LangChainConfigurationError(`getDefaultServiceConfigFromAlias: Unsupported provider '${provider}'. Supported providers: openai, anthropic, ollama`, { provider, supportedProviders: ['openai', 'anthropic', 'ollama'] });
|
|
271
416
|
}
|
|
272
417
|
}
|
|
273
418
|
|
|
@@ -893,6 +1038,11 @@ const schema$1 = {
|
|
|
893
1038
|
}
|
|
894
1039
|
},
|
|
895
1040
|
"additionalProperties": false
|
|
1041
|
+
},
|
|
1042
|
+
"maxParsingAttempts": {
|
|
1043
|
+
"type": "number",
|
|
1044
|
+
"description": "The maximum number of attempts for schema parsing with retry logic.",
|
|
1045
|
+
"default": 3
|
|
896
1046
|
}
|
|
897
1047
|
},
|
|
898
1048
|
"required": [
|
|
@@ -983,6 +1133,9 @@ const schema$1 = {
|
|
|
983
1133
|
"OllamaModel": {
|
|
984
1134
|
"type": "string",
|
|
985
1135
|
"enum": [
|
|
1136
|
+
"deepseek-r1:1.5b",
|
|
1137
|
+
"deepseek-r1:8b",
|
|
1138
|
+
"deepseek-r1:32b",
|
|
986
1139
|
"codegemma:2b",
|
|
987
1140
|
"codegemma:7b-code",
|
|
988
1141
|
"codegemma",
|
|
@@ -1014,9 +1167,11 @@ const schema$1 = {
|
|
|
1014
1167
|
"llama3.2:latest",
|
|
1015
1168
|
"llama3.2:1b",
|
|
1016
1169
|
"llama3.2:3b",
|
|
1017
|
-
"llama3.2:1b-instruct-fp16",
|
|
1018
|
-
"llama3.2:1b-instruct-q3_K_M",
|
|
1019
1170
|
"llama3",
|
|
1171
|
+
"llava-llama3:latest",
|
|
1172
|
+
"dolphin-llama3:latest",
|
|
1173
|
+
"dolphin-llama3:8b",
|
|
1174
|
+
"dolphin-llama3:70b",
|
|
1020
1175
|
"mistral:7b",
|
|
1021
1176
|
"mistral:latest",
|
|
1022
1177
|
"mistral:text",
|
|
@@ -1032,18 +1187,28 @@ const schema$1 = {
|
|
|
1032
1187
|
"qwen2:1.5b",
|
|
1033
1188
|
"qwen2:72b-text",
|
|
1034
1189
|
"qwen2:72b",
|
|
1035
|
-
"qwen2"
|
|
1190
|
+
"qwen2",
|
|
1191
|
+
"qwen2.5-coder:latest",
|
|
1192
|
+
"qwen2.5-coder:0.5b",
|
|
1193
|
+
"qwen2.5-coder:1.5b",
|
|
1194
|
+
"qwen2.5-coder:3b",
|
|
1195
|
+
"qwen2.5-coder:7b",
|
|
1196
|
+
"qwen2.5-coder:14b",
|
|
1197
|
+
"qwen2.5-coder:32b"
|
|
1036
1198
|
]
|
|
1037
1199
|
},
|
|
1038
1200
|
"AnthropicModel": {
|
|
1039
1201
|
"type": "string",
|
|
1040
1202
|
"enum": [
|
|
1203
|
+
"claude-sonnet-4-0",
|
|
1204
|
+
"claude-3-7-sonnet-latest",
|
|
1205
|
+
"claude-3-5-haiku-latest",
|
|
1206
|
+
"claude-3-5-sonnet-latest",
|
|
1207
|
+
"claude-3-5-sonnet-20241022",
|
|
1041
1208
|
"claude-3-5-sonnet-20240620",
|
|
1042
1209
|
"claude-3-opus-20240229",
|
|
1043
1210
|
"claude-3-sonnet-20240229",
|
|
1044
|
-
"claude-3-haiku-20240307"
|
|
1045
|
-
"claude-2.1",
|
|
1046
|
-
"claude-2.0"
|
|
1211
|
+
"claude-3-haiku-20240307"
|
|
1047
1212
|
]
|
|
1048
1213
|
},
|
|
1049
1214
|
"Callbacks": {
|
|
@@ -1488,6 +1653,11 @@ const schema$1 = {
|
|
|
1488
1653
|
}
|
|
1489
1654
|
},
|
|
1490
1655
|
"additionalProperties": false
|
|
1656
|
+
},
|
|
1657
|
+
"maxParsingAttempts": {
|
|
1658
|
+
"type": "number",
|
|
1659
|
+
"description": "The maximum number of attempts for schema parsing with retry logic.",
|
|
1660
|
+
"default": 3
|
|
1491
1661
|
}
|
|
1492
1662
|
},
|
|
1493
1663
|
"required": [
|
|
@@ -1634,6 +1804,11 @@ const schema$1 = {
|
|
|
1634
1804
|
}
|
|
1635
1805
|
},
|
|
1636
1806
|
"additionalProperties": false
|
|
1807
|
+
},
|
|
1808
|
+
"maxParsingAttempts": {
|
|
1809
|
+
"type": "number",
|
|
1810
|
+
"description": "The maximum number of attempts for schema parsing with retry logic.",
|
|
1811
|
+
"default": 3
|
|
1637
1812
|
}
|
|
1638
1813
|
},
|
|
1639
1814
|
"required": [
|
|
@@ -1853,7 +2028,7 @@ function commandExecutor(handler) {
|
|
|
1853
2028
|
|
|
1854
2029
|
var util;
|
|
1855
2030
|
(function (util) {
|
|
1856
|
-
util.assertEqual = (
|
|
2031
|
+
util.assertEqual = (_) => { };
|
|
1857
2032
|
function assertIs(_arg) { }
|
|
1858
2033
|
util.assertIs = assertIs;
|
|
1859
2034
|
function assertNever(_x) {
|
|
@@ -1900,11 +2075,9 @@ var util;
|
|
|
1900
2075
|
};
|
|
1901
2076
|
util.isInteger = typeof Number.isInteger === "function"
|
|
1902
2077
|
? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
|
|
1903
|
-
: (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
|
|
2078
|
+
: (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
|
|
1904
2079
|
function joinValues(array, separator = " | ") {
|
|
1905
|
-
return array
|
|
1906
|
-
.map((val) => (typeof val === "string" ? `'${val}'` : val))
|
|
1907
|
-
.join(separator);
|
|
2080
|
+
return array.map((val) => (typeof val === "string" ? `'${val}'` : val)).join(separator);
|
|
1908
2081
|
}
|
|
1909
2082
|
util.joinValues = joinValues;
|
|
1910
2083
|
util.jsonStringifyReplacer = (_, value) => {
|
|
@@ -1953,7 +2126,7 @@ const getParsedType = (data) => {
|
|
|
1953
2126
|
case "string":
|
|
1954
2127
|
return ZodParsedType.string;
|
|
1955
2128
|
case "number":
|
|
1956
|
-
return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
|
|
2129
|
+
return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
|
|
1957
2130
|
case "boolean":
|
|
1958
2131
|
return ZodParsedType.boolean;
|
|
1959
2132
|
case "function":
|
|
@@ -1969,10 +2142,7 @@ const getParsedType = (data) => {
|
|
|
1969
2142
|
if (data === null) {
|
|
1970
2143
|
return ZodParsedType.null;
|
|
1971
2144
|
}
|
|
1972
|
-
if (data.then &&
|
|
1973
|
-
typeof data.then === "function" &&
|
|
1974
|
-
data.catch &&
|
|
1975
|
-
typeof data.catch === "function") {
|
|
2145
|
+
if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
|
|
1976
2146
|
return ZodParsedType.promise;
|
|
1977
2147
|
}
|
|
1978
2148
|
if (typeof Map !== "undefined" && data instanceof Map) {
|
|
@@ -2008,10 +2178,6 @@ const ZodIssueCode = util.arrayToEnum([
|
|
|
2008
2178
|
"not_multiple_of",
|
|
2009
2179
|
"not_finite",
|
|
2010
2180
|
]);
|
|
2011
|
-
const quotelessJson = (obj) => {
|
|
2012
|
-
const json = JSON.stringify(obj, null, 2);
|
|
2013
|
-
return json.replace(/"([^"]+)":/g, "$1:");
|
|
2014
|
-
};
|
|
2015
2181
|
class ZodError extends Error {
|
|
2016
2182
|
get errors() {
|
|
2017
2183
|
return this.issues;
|
|
@@ -2104,8 +2270,9 @@ class ZodError extends Error {
|
|
|
2104
2270
|
const formErrors = [];
|
|
2105
2271
|
for (const sub of this.issues) {
|
|
2106
2272
|
if (sub.path.length > 0) {
|
|
2107
|
-
|
|
2108
|
-
fieldErrors[
|
|
2273
|
+
const firstEl = sub.path[0];
|
|
2274
|
+
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
|
2275
|
+
fieldErrors[firstEl].push(mapper(sub));
|
|
2109
2276
|
}
|
|
2110
2277
|
else {
|
|
2111
2278
|
formErrors.push(mapper(sub));
|
|
@@ -2188,17 +2355,11 @@ const errorMap = (issue, _ctx) => {
|
|
|
2188
2355
|
else if (issue.type === "string")
|
|
2189
2356
|
message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
|
|
2190
2357
|
else if (issue.type === "number")
|
|
2191
|
-
message = `Number must be ${issue.exact
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
? `greater than or equal to `
|
|
2195
|
-
: `greater than `}${issue.minimum}`;
|
|
2358
|
+
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
|
|
2359
|
+
else if (issue.type === "bigint")
|
|
2360
|
+
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
|
|
2196
2361
|
else if (issue.type === "date")
|
|
2197
|
-
message = `Date must be ${issue.exact
|
|
2198
|
-
? `exactly equal to `
|
|
2199
|
-
: issue.inclusive
|
|
2200
|
-
? `greater than or equal to `
|
|
2201
|
-
: `greater than `}${new Date(Number(issue.minimum))}`;
|
|
2362
|
+
message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
|
|
2202
2363
|
else
|
|
2203
2364
|
message = "Invalid input";
|
|
2204
2365
|
break;
|
|
@@ -2208,23 +2369,11 @@ const errorMap = (issue, _ctx) => {
|
|
|
2208
2369
|
else if (issue.type === "string")
|
|
2209
2370
|
message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
|
|
2210
2371
|
else if (issue.type === "number")
|
|
2211
|
-
message = `Number must be ${issue.exact
|
|
2212
|
-
? `exactly`
|
|
2213
|
-
: issue.inclusive
|
|
2214
|
-
? `less than or equal to`
|
|
2215
|
-
: `less than`} ${issue.maximum}`;
|
|
2372
|
+
message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
|
|
2216
2373
|
else if (issue.type === "bigint")
|
|
2217
|
-
message = `BigInt must be ${issue.exact
|
|
2218
|
-
? `exactly`
|
|
2219
|
-
: issue.inclusive
|
|
2220
|
-
? `less than or equal to`
|
|
2221
|
-
: `less than`} ${issue.maximum}`;
|
|
2374
|
+
message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
|
|
2222
2375
|
else if (issue.type === "date")
|
|
2223
|
-
message = `Date must be ${issue.exact
|
|
2224
|
-
? `exactly`
|
|
2225
|
-
: issue.inclusive
|
|
2226
|
-
? `smaller than or equal to`
|
|
2227
|
-
: `smaller than`} ${new Date(Number(issue.maximum))}`;
|
|
2376
|
+
message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
|
|
2228
2377
|
else
|
|
2229
2378
|
message = "Invalid input";
|
|
2230
2379
|
break;
|
|
@@ -2246,11 +2395,9 @@ const errorMap = (issue, _ctx) => {
|
|
|
2246
2395
|
}
|
|
2247
2396
|
return { message };
|
|
2248
2397
|
};
|
|
2398
|
+
var defaultErrorMap = errorMap;
|
|
2249
2399
|
|
|
2250
|
-
let overrideErrorMap =
|
|
2251
|
-
function setErrorMap(map) {
|
|
2252
|
-
overrideErrorMap = map;
|
|
2253
|
-
}
|
|
2400
|
+
let overrideErrorMap = defaultErrorMap;
|
|
2254
2401
|
function getErrorMap() {
|
|
2255
2402
|
return overrideErrorMap;
|
|
2256
2403
|
}
|
|
@@ -2283,7 +2430,6 @@ const makeIssue = (params) => {
|
|
|
2283
2430
|
message: errorMessage,
|
|
2284
2431
|
};
|
|
2285
2432
|
};
|
|
2286
|
-
const EMPTY_PATH = [];
|
|
2287
2433
|
function addIssueToContext(ctx, issueData) {
|
|
2288
2434
|
const overrideMap = getErrorMap();
|
|
2289
2435
|
const issue = makeIssue({
|
|
@@ -2294,7 +2440,7 @@ function addIssueToContext(ctx, issueData) {
|
|
|
2294
2440
|
ctx.common.contextualErrorMap, // contextual error map is first priority
|
|
2295
2441
|
ctx.schemaErrorMap, // then schema-bound map if available
|
|
2296
2442
|
overrideMap, // then global override map
|
|
2297
|
-
overrideMap ===
|
|
2443
|
+
overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map
|
|
2298
2444
|
].filter((x) => !!x),
|
|
2299
2445
|
});
|
|
2300
2446
|
ctx.common.issues.push(issue);
|
|
@@ -2346,8 +2492,7 @@ class ParseStatus {
|
|
|
2346
2492
|
status.dirty();
|
|
2347
2493
|
if (value.status === "dirty")
|
|
2348
2494
|
status.dirty();
|
|
2349
|
-
if (key.value !== "__proto__" &&
|
|
2350
|
-
(typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
2495
|
+
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
2351
2496
|
finalObject[key.value] = value.value;
|
|
2352
2497
|
}
|
|
2353
2498
|
}
|
|
@@ -2364,46 +2509,13 @@ const isDirty = (x) => x.status === "dirty";
|
|
|
2364
2509
|
const isValid = (x) => x.status === "valid";
|
|
2365
2510
|
const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
2366
2511
|
|
|
2367
|
-
/******************************************************************************
|
|
2368
|
-
Copyright (c) Microsoft Corporation.
|
|
2369
|
-
|
|
2370
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
2371
|
-
purpose with or without fee is hereby granted.
|
|
2372
|
-
|
|
2373
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
2374
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
2375
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
2376
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
2377
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
2378
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
2379
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
2380
|
-
***************************************************************************** */
|
|
2381
|
-
|
|
2382
|
-
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
2383
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
2384
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
2385
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
2389
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
2390
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
2391
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
2392
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
2396
|
-
var e = new Error(message);
|
|
2397
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
2398
|
-
};
|
|
2399
|
-
|
|
2400
2512
|
var errorUtil;
|
|
2401
2513
|
(function (errorUtil) {
|
|
2402
2514
|
errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
|
2403
|
-
|
|
2515
|
+
// biome-ignore lint:
|
|
2516
|
+
errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
|
|
2404
2517
|
})(errorUtil || (errorUtil = {}));
|
|
2405
2518
|
|
|
2406
|
-
var _ZodEnum_cache, _ZodNativeEnum_cache;
|
|
2407
2519
|
class ParseInputLazyPath {
|
|
2408
2520
|
constructor(parent, value, path, key) {
|
|
2409
2521
|
this._cachedPath = [];
|
|
@@ -2414,7 +2526,7 @@ class ParseInputLazyPath {
|
|
|
2414
2526
|
}
|
|
2415
2527
|
get path() {
|
|
2416
2528
|
if (!this._cachedPath.length) {
|
|
2417
|
-
if (this._key
|
|
2529
|
+
if (Array.isArray(this._key)) {
|
|
2418
2530
|
this._cachedPath.push(...this._path, ...this._key);
|
|
2419
2531
|
}
|
|
2420
2532
|
else {
|
|
@@ -2454,17 +2566,16 @@ function processCreateParams(params) {
|
|
|
2454
2566
|
if (errorMap)
|
|
2455
2567
|
return { errorMap: errorMap, description };
|
|
2456
2568
|
const customMap = (iss, ctx) => {
|
|
2457
|
-
var _a, _b;
|
|
2458
2569
|
const { message } = params;
|
|
2459
2570
|
if (iss.code === "invalid_enum_value") {
|
|
2460
|
-
return { message: message
|
|
2571
|
+
return { message: message ?? ctx.defaultError };
|
|
2461
2572
|
}
|
|
2462
2573
|
if (typeof ctx.data === "undefined") {
|
|
2463
|
-
return { message:
|
|
2574
|
+
return { message: message ?? required_error ?? ctx.defaultError };
|
|
2464
2575
|
}
|
|
2465
2576
|
if (iss.code !== "invalid_type")
|
|
2466
2577
|
return { message: ctx.defaultError };
|
|
2467
|
-
return { message:
|
|
2578
|
+
return { message: message ?? invalid_type_error ?? ctx.defaultError };
|
|
2468
2579
|
};
|
|
2469
2580
|
return { errorMap: customMap, description };
|
|
2470
2581
|
}
|
|
@@ -2516,14 +2627,13 @@ class ZodType {
|
|
|
2516
2627
|
throw result.error;
|
|
2517
2628
|
}
|
|
2518
2629
|
safeParse(data, params) {
|
|
2519
|
-
var _a;
|
|
2520
2630
|
const ctx = {
|
|
2521
2631
|
common: {
|
|
2522
2632
|
issues: [],
|
|
2523
|
-
async:
|
|
2524
|
-
contextualErrorMap: params
|
|
2633
|
+
async: params?.async ?? false,
|
|
2634
|
+
contextualErrorMap: params?.errorMap,
|
|
2525
2635
|
},
|
|
2526
|
-
path:
|
|
2636
|
+
path: params?.path || [],
|
|
2527
2637
|
schemaErrorMap: this._def.errorMap,
|
|
2528
2638
|
parent: null,
|
|
2529
2639
|
data,
|
|
@@ -2533,7 +2643,6 @@ class ZodType {
|
|
|
2533
2643
|
return handleResult$1(ctx, result);
|
|
2534
2644
|
}
|
|
2535
2645
|
"~validate"(data) {
|
|
2536
|
-
var _a, _b;
|
|
2537
2646
|
const ctx = {
|
|
2538
2647
|
common: {
|
|
2539
2648
|
issues: [],
|
|
@@ -2557,7 +2666,7 @@ class ZodType {
|
|
|
2557
2666
|
};
|
|
2558
2667
|
}
|
|
2559
2668
|
catch (err) {
|
|
2560
|
-
if (
|
|
2669
|
+
if (err?.message?.toLowerCase()?.includes("encountered")) {
|
|
2561
2670
|
this["~standard"].async = true;
|
|
2562
2671
|
}
|
|
2563
2672
|
ctx.common = {
|
|
@@ -2584,19 +2693,17 @@ class ZodType {
|
|
|
2584
2693
|
const ctx = {
|
|
2585
2694
|
common: {
|
|
2586
2695
|
issues: [],
|
|
2587
|
-
contextualErrorMap: params
|
|
2696
|
+
contextualErrorMap: params?.errorMap,
|
|
2588
2697
|
async: true,
|
|
2589
2698
|
},
|
|
2590
|
-
path:
|
|
2699
|
+
path: params?.path || [],
|
|
2591
2700
|
schemaErrorMap: this._def.errorMap,
|
|
2592
2701
|
parent: null,
|
|
2593
2702
|
data,
|
|
2594
2703
|
parsedType: getParsedType(data),
|
|
2595
2704
|
};
|
|
2596
2705
|
const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
|
|
2597
|
-
const result = await (isAsync(maybeAsyncResult)
|
|
2598
|
-
? maybeAsyncResult
|
|
2599
|
-
: Promise.resolve(maybeAsyncResult));
|
|
2706
|
+
const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
|
|
2600
2707
|
return handleResult$1(ctx, result);
|
|
2601
2708
|
}
|
|
2602
2709
|
refine(check, message) {
|
|
@@ -2640,9 +2747,7 @@ class ZodType {
|
|
|
2640
2747
|
refinement(check, refinementData) {
|
|
2641
2748
|
return this._refinement((val, ctx) => {
|
|
2642
2749
|
if (!check(val)) {
|
|
2643
|
-
ctx.addIssue(typeof refinementData === "function"
|
|
2644
|
-
? refinementData(val, ctx)
|
|
2645
|
-
: refinementData);
|
|
2750
|
+
ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
|
|
2646
2751
|
return false;
|
|
2647
2752
|
}
|
|
2648
2753
|
else {
|
|
@@ -2814,15 +2919,15 @@ const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z
|
|
|
2814
2919
|
const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
|
|
2815
2920
|
const dateRegex = new RegExp(`^${dateRegexSource}$`);
|
|
2816
2921
|
function timeRegexSource(args) {
|
|
2817
|
-
|
|
2818
|
-
let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
|
|
2922
|
+
let secondsRegexSource = `[0-5]\\d`;
|
|
2819
2923
|
if (args.precision) {
|
|
2820
|
-
|
|
2924
|
+
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
|
|
2821
2925
|
}
|
|
2822
2926
|
else if (args.precision == null) {
|
|
2823
|
-
|
|
2927
|
+
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
|
|
2824
2928
|
}
|
|
2825
|
-
|
|
2929
|
+
const secondsQuantifier = args.precision ? "+" : "?"; // require seconds if precision is nonzero
|
|
2930
|
+
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
|
|
2826
2931
|
}
|
|
2827
2932
|
function timeRegex(args) {
|
|
2828
2933
|
return new RegExp(`^${timeRegexSource(args)}$`);
|
|
@@ -2851,6 +2956,8 @@ function isValidJWT(jwt, alg) {
|
|
|
2851
2956
|
return false;
|
|
2852
2957
|
try {
|
|
2853
2958
|
const [header] = jwt.split(".");
|
|
2959
|
+
if (!header)
|
|
2960
|
+
return false;
|
|
2854
2961
|
// Convert base64url to base64
|
|
2855
2962
|
const base64 = header
|
|
2856
2963
|
.replace(/-/g, "+")
|
|
@@ -2859,13 +2966,15 @@ function isValidJWT(jwt, alg) {
|
|
|
2859
2966
|
const decoded = JSON.parse(atob(base64));
|
|
2860
2967
|
if (typeof decoded !== "object" || decoded === null)
|
|
2861
2968
|
return false;
|
|
2862
|
-
if (
|
|
2969
|
+
if ("typ" in decoded && decoded?.typ !== "JWT")
|
|
2970
|
+
return false;
|
|
2971
|
+
if (!decoded.alg)
|
|
2863
2972
|
return false;
|
|
2864
2973
|
if (alg && decoded.alg !== alg)
|
|
2865
2974
|
return false;
|
|
2866
2975
|
return true;
|
|
2867
2976
|
}
|
|
2868
|
-
catch
|
|
2977
|
+
catch {
|
|
2869
2978
|
return false;
|
|
2870
2979
|
}
|
|
2871
2980
|
}
|
|
@@ -3036,7 +3145,7 @@ class ZodString extends ZodType {
|
|
|
3036
3145
|
try {
|
|
3037
3146
|
new URL(input.data);
|
|
3038
3147
|
}
|
|
3039
|
-
catch
|
|
3148
|
+
catch {
|
|
3040
3149
|
ctx = this._getOrReturnCtx(input, ctx);
|
|
3041
3150
|
addIssueToContext(ctx, {
|
|
3042
3151
|
validation: "url",
|
|
@@ -3266,7 +3375,6 @@ class ZodString extends ZodType {
|
|
|
3266
3375
|
return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
|
|
3267
3376
|
}
|
|
3268
3377
|
datetime(options) {
|
|
3269
|
-
var _a, _b;
|
|
3270
3378
|
if (typeof options === "string") {
|
|
3271
3379
|
return this._addCheck({
|
|
3272
3380
|
kind: "datetime",
|
|
@@ -3278,10 +3386,10 @@ class ZodString extends ZodType {
|
|
|
3278
3386
|
}
|
|
3279
3387
|
return this._addCheck({
|
|
3280
3388
|
kind: "datetime",
|
|
3281
|
-
precision: typeof
|
|
3282
|
-
offset:
|
|
3283
|
-
local:
|
|
3284
|
-
...errorUtil.errToObj(options
|
|
3389
|
+
precision: typeof options?.precision === "undefined" ? null : options?.precision,
|
|
3390
|
+
offset: options?.offset ?? false,
|
|
3391
|
+
local: options?.local ?? false,
|
|
3392
|
+
...errorUtil.errToObj(options?.message),
|
|
3285
3393
|
});
|
|
3286
3394
|
}
|
|
3287
3395
|
date(message) {
|
|
@@ -3297,8 +3405,8 @@ class ZodString extends ZodType {
|
|
|
3297
3405
|
}
|
|
3298
3406
|
return this._addCheck({
|
|
3299
3407
|
kind: "time",
|
|
3300
|
-
precision: typeof
|
|
3301
|
-
...errorUtil.errToObj(options
|
|
3408
|
+
precision: typeof options?.precision === "undefined" ? null : options?.precision,
|
|
3409
|
+
...errorUtil.errToObj(options?.message),
|
|
3302
3410
|
});
|
|
3303
3411
|
}
|
|
3304
3412
|
duration(message) {
|
|
@@ -3315,8 +3423,8 @@ class ZodString extends ZodType {
|
|
|
3315
3423
|
return this._addCheck({
|
|
3316
3424
|
kind: "includes",
|
|
3317
3425
|
value: value,
|
|
3318
|
-
position: options
|
|
3319
|
-
...errorUtil.errToObj(options
|
|
3426
|
+
position: options?.position,
|
|
3427
|
+
...errorUtil.errToObj(options?.message),
|
|
3320
3428
|
});
|
|
3321
3429
|
}
|
|
3322
3430
|
startsWith(value, message) {
|
|
@@ -3449,11 +3557,10 @@ class ZodString extends ZodType {
|
|
|
3449
3557
|
}
|
|
3450
3558
|
}
|
|
3451
3559
|
ZodString.create = (params) => {
|
|
3452
|
-
var _a;
|
|
3453
3560
|
return new ZodString({
|
|
3454
3561
|
checks: [],
|
|
3455
3562
|
typeName: ZodFirstPartyTypeKind.ZodString,
|
|
3456
|
-
coerce:
|
|
3563
|
+
coerce: params?.coerce ?? false,
|
|
3457
3564
|
...processCreateParams(params),
|
|
3458
3565
|
});
|
|
3459
3566
|
};
|
|
@@ -3462,9 +3569,9 @@ function floatSafeRemainder(val, step) {
|
|
|
3462
3569
|
const valDecCount = (val.toString().split(".")[1] || "").length;
|
|
3463
3570
|
const stepDecCount = (step.toString().split(".")[1] || "").length;
|
|
3464
3571
|
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
|
|
3465
|
-
const valInt = parseInt(val.toFixed(decCount).replace(".", ""));
|
|
3466
|
-
const stepInt = parseInt(step.toFixed(decCount).replace(".", ""));
|
|
3467
|
-
return (valInt % stepInt) /
|
|
3572
|
+
const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
|
|
3573
|
+
const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
|
|
3574
|
+
return (valInt % stepInt) / 10 ** decCount;
|
|
3468
3575
|
}
|
|
3469
3576
|
class ZodNumber extends ZodType {
|
|
3470
3577
|
constructor() {
|
|
@@ -3503,9 +3610,7 @@ class ZodNumber extends ZodType {
|
|
|
3503
3610
|
}
|
|
3504
3611
|
}
|
|
3505
3612
|
else if (check.kind === "min") {
|
|
3506
|
-
const tooSmall = check.inclusive
|
|
3507
|
-
? input.data < check.value
|
|
3508
|
-
: input.data <= check.value;
|
|
3613
|
+
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
|
|
3509
3614
|
if (tooSmall) {
|
|
3510
3615
|
ctx = this._getOrReturnCtx(input, ctx);
|
|
3511
3616
|
addIssueToContext(ctx, {
|
|
@@ -3520,9 +3625,7 @@ class ZodNumber extends ZodType {
|
|
|
3520
3625
|
}
|
|
3521
3626
|
}
|
|
3522
3627
|
else if (check.kind === "max") {
|
|
3523
|
-
const tooBig = check.inclusive
|
|
3524
|
-
? input.data > check.value
|
|
3525
|
-
: input.data >= check.value;
|
|
3628
|
+
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
|
|
3526
3629
|
if (tooBig) {
|
|
3527
3630
|
ctx = this._getOrReturnCtx(input, ctx);
|
|
3528
3631
|
addIssueToContext(ctx, {
|
|
@@ -3680,15 +3783,13 @@ class ZodNumber extends ZodType {
|
|
|
3680
3783
|
return max;
|
|
3681
3784
|
}
|
|
3682
3785
|
get isInt() {
|
|
3683
|
-
return !!this._def.checks.find((ch) => ch.kind === "int" ||
|
|
3684
|
-
(ch.kind === "multipleOf" && util.isInteger(ch.value)));
|
|
3786
|
+
return !!this._def.checks.find((ch) => ch.kind === "int" || (ch.kind === "multipleOf" && util.isInteger(ch.value)));
|
|
3685
3787
|
}
|
|
3686
3788
|
get isFinite() {
|
|
3687
|
-
let max = null
|
|
3789
|
+
let max = null;
|
|
3790
|
+
let min = null;
|
|
3688
3791
|
for (const ch of this._def.checks) {
|
|
3689
|
-
if (ch.kind === "finite" ||
|
|
3690
|
-
ch.kind === "int" ||
|
|
3691
|
-
ch.kind === "multipleOf") {
|
|
3792
|
+
if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
|
|
3692
3793
|
return true;
|
|
3693
3794
|
}
|
|
3694
3795
|
else if (ch.kind === "min") {
|
|
@@ -3707,7 +3808,7 @@ ZodNumber.create = (params) => {
|
|
|
3707
3808
|
return new ZodNumber({
|
|
3708
3809
|
checks: [],
|
|
3709
3810
|
typeName: ZodFirstPartyTypeKind.ZodNumber,
|
|
3710
|
-
coerce:
|
|
3811
|
+
coerce: params?.coerce || false,
|
|
3711
3812
|
...processCreateParams(params),
|
|
3712
3813
|
});
|
|
3713
3814
|
};
|
|
@@ -3722,7 +3823,7 @@ class ZodBigInt extends ZodType {
|
|
|
3722
3823
|
try {
|
|
3723
3824
|
input.data = BigInt(input.data);
|
|
3724
3825
|
}
|
|
3725
|
-
catch
|
|
3826
|
+
catch {
|
|
3726
3827
|
return this._getInvalidInput(input);
|
|
3727
3828
|
}
|
|
3728
3829
|
}
|
|
@@ -3734,9 +3835,7 @@ class ZodBigInt extends ZodType {
|
|
|
3734
3835
|
const status = new ParseStatus();
|
|
3735
3836
|
for (const check of this._def.checks) {
|
|
3736
3837
|
if (check.kind === "min") {
|
|
3737
|
-
const tooSmall = check.inclusive
|
|
3738
|
-
? input.data < check.value
|
|
3739
|
-
: input.data <= check.value;
|
|
3838
|
+
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
|
|
3740
3839
|
if (tooSmall) {
|
|
3741
3840
|
ctx = this._getOrReturnCtx(input, ctx);
|
|
3742
3841
|
addIssueToContext(ctx, {
|
|
@@ -3750,9 +3849,7 @@ class ZodBigInt extends ZodType {
|
|
|
3750
3849
|
}
|
|
3751
3850
|
}
|
|
3752
3851
|
else if (check.kind === "max") {
|
|
3753
|
-
const tooBig = check.inclusive
|
|
3754
|
-
? input.data > check.value
|
|
3755
|
-
: input.data >= check.value;
|
|
3852
|
+
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
|
|
3756
3853
|
if (tooBig) {
|
|
3757
3854
|
ctx = this._getOrReturnCtx(input, ctx);
|
|
3758
3855
|
addIssueToContext(ctx, {
|
|
@@ -3884,11 +3981,10 @@ class ZodBigInt extends ZodType {
|
|
|
3884
3981
|
}
|
|
3885
3982
|
}
|
|
3886
3983
|
ZodBigInt.create = (params) => {
|
|
3887
|
-
var _a;
|
|
3888
3984
|
return new ZodBigInt({
|
|
3889
3985
|
checks: [],
|
|
3890
3986
|
typeName: ZodFirstPartyTypeKind.ZodBigInt,
|
|
3891
|
-
coerce:
|
|
3987
|
+
coerce: params?.coerce ?? false,
|
|
3892
3988
|
...processCreateParams(params),
|
|
3893
3989
|
});
|
|
3894
3990
|
};
|
|
@@ -3913,7 +4009,7 @@ class ZodBoolean extends ZodType {
|
|
|
3913
4009
|
ZodBoolean.create = (params) => {
|
|
3914
4010
|
return new ZodBoolean({
|
|
3915
4011
|
typeName: ZodFirstPartyTypeKind.ZodBoolean,
|
|
3916
|
-
coerce:
|
|
4012
|
+
coerce: params?.coerce || false,
|
|
3917
4013
|
...processCreateParams(params),
|
|
3918
4014
|
});
|
|
3919
4015
|
};
|
|
@@ -3932,7 +4028,7 @@ class ZodDate extends ZodType {
|
|
|
3932
4028
|
});
|
|
3933
4029
|
return INVALID;
|
|
3934
4030
|
}
|
|
3935
|
-
if (isNaN(input.data.getTime())) {
|
|
4031
|
+
if (Number.isNaN(input.data.getTime())) {
|
|
3936
4032
|
const ctx = this._getOrReturnCtx(input);
|
|
3937
4033
|
addIssueToContext(ctx, {
|
|
3938
4034
|
code: ZodIssueCode.invalid_date,
|
|
@@ -4023,7 +4119,7 @@ class ZodDate extends ZodType {
|
|
|
4023
4119
|
ZodDate.create = (params) => {
|
|
4024
4120
|
return new ZodDate({
|
|
4025
4121
|
checks: [],
|
|
4026
|
-
coerce:
|
|
4122
|
+
coerce: params?.coerce || false,
|
|
4027
4123
|
typeName: ZodFirstPartyTypeKind.ZodDate,
|
|
4028
4124
|
...processCreateParams(params),
|
|
4029
4125
|
});
|
|
@@ -4345,7 +4441,8 @@ class ZodObject extends ZodType {
|
|
|
4345
4441
|
return this._cached;
|
|
4346
4442
|
const shape = this._def.shape();
|
|
4347
4443
|
const keys = util.objectKeys(shape);
|
|
4348
|
-
|
|
4444
|
+
this._cached = { shape, keys };
|
|
4445
|
+
return this._cached;
|
|
4349
4446
|
}
|
|
4350
4447
|
_parse(input) {
|
|
4351
4448
|
const parsedType = this._getType(input);
|
|
@@ -4361,8 +4458,7 @@ class ZodObject extends ZodType {
|
|
|
4361
4458
|
const { status, ctx } = this._processInputParams(input);
|
|
4362
4459
|
const { shape, keys: shapeKeys } = this._getCached();
|
|
4363
4460
|
const extraKeys = [];
|
|
4364
|
-
if (!(this._def.catchall instanceof ZodNever &&
|
|
4365
|
-
this._def.unknownKeys === "strip")) {
|
|
4461
|
+
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
4366
4462
|
for (const key in ctx.data) {
|
|
4367
4463
|
if (!shapeKeys.includes(key)) {
|
|
4368
4464
|
extraKeys.push(key);
|
|
@@ -4450,11 +4546,10 @@ class ZodObject extends ZodType {
|
|
|
4450
4546
|
...(message !== undefined
|
|
4451
4547
|
? {
|
|
4452
4548
|
errorMap: (issue, ctx) => {
|
|
4453
|
-
|
|
4454
|
-
const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;
|
|
4549
|
+
const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
|
|
4455
4550
|
if (issue.code === "unrecognized_keys")
|
|
4456
4551
|
return {
|
|
4457
|
-
message:
|
|
4552
|
+
message: errorUtil.errToObj(message).message ?? defaultError,
|
|
4458
4553
|
};
|
|
4459
4554
|
return {
|
|
4460
4555
|
message: defaultError,
|
|
@@ -4586,11 +4681,11 @@ class ZodObject extends ZodType {
|
|
|
4586
4681
|
}
|
|
4587
4682
|
pick(mask) {
|
|
4588
4683
|
const shape = {};
|
|
4589
|
-
util.objectKeys(mask)
|
|
4684
|
+
for (const key of util.objectKeys(mask)) {
|
|
4590
4685
|
if (mask[key] && this.shape[key]) {
|
|
4591
4686
|
shape[key] = this.shape[key];
|
|
4592
4687
|
}
|
|
4593
|
-
}
|
|
4688
|
+
}
|
|
4594
4689
|
return new ZodObject({
|
|
4595
4690
|
...this._def,
|
|
4596
4691
|
shape: () => shape,
|
|
@@ -4598,11 +4693,11 @@ class ZodObject extends ZodType {
|
|
|
4598
4693
|
}
|
|
4599
4694
|
omit(mask) {
|
|
4600
4695
|
const shape = {};
|
|
4601
|
-
util.objectKeys(this.shape)
|
|
4696
|
+
for (const key of util.objectKeys(this.shape)) {
|
|
4602
4697
|
if (!mask[key]) {
|
|
4603
4698
|
shape[key] = this.shape[key];
|
|
4604
4699
|
}
|
|
4605
|
-
}
|
|
4700
|
+
}
|
|
4606
4701
|
return new ZodObject({
|
|
4607
4702
|
...this._def,
|
|
4608
4703
|
shape: () => shape,
|
|
@@ -4616,7 +4711,7 @@ class ZodObject extends ZodType {
|
|
|
4616
4711
|
}
|
|
4617
4712
|
partial(mask) {
|
|
4618
4713
|
const newShape = {};
|
|
4619
|
-
util.objectKeys(this.shape)
|
|
4714
|
+
for (const key of util.objectKeys(this.shape)) {
|
|
4620
4715
|
const fieldSchema = this.shape[key];
|
|
4621
4716
|
if (mask && !mask[key]) {
|
|
4622
4717
|
newShape[key] = fieldSchema;
|
|
@@ -4624,7 +4719,7 @@ class ZodObject extends ZodType {
|
|
|
4624
4719
|
else {
|
|
4625
4720
|
newShape[key] = fieldSchema.optional();
|
|
4626
4721
|
}
|
|
4627
|
-
}
|
|
4722
|
+
}
|
|
4628
4723
|
return new ZodObject({
|
|
4629
4724
|
...this._def,
|
|
4630
4725
|
shape: () => newShape,
|
|
@@ -4632,7 +4727,7 @@ class ZodObject extends ZodType {
|
|
|
4632
4727
|
}
|
|
4633
4728
|
required(mask) {
|
|
4634
4729
|
const newShape = {};
|
|
4635
|
-
util.objectKeys(this.shape)
|
|
4730
|
+
for (const key of util.objectKeys(this.shape)) {
|
|
4636
4731
|
if (mask && !mask[key]) {
|
|
4637
4732
|
newShape[key] = this.shape[key];
|
|
4638
4733
|
}
|
|
@@ -4644,7 +4739,7 @@ class ZodObject extends ZodType {
|
|
|
4644
4739
|
}
|
|
4645
4740
|
newShape[key] = newField;
|
|
4646
4741
|
}
|
|
4647
|
-
}
|
|
4742
|
+
}
|
|
4648
4743
|
return new ZodObject({
|
|
4649
4744
|
...this._def,
|
|
4650
4745
|
shape: () => newShape,
|
|
@@ -4777,137 +4872,6 @@ ZodUnion.create = (types, params) => {
|
|
|
4777
4872
|
...processCreateParams(params),
|
|
4778
4873
|
});
|
|
4779
4874
|
};
|
|
4780
|
-
/////////////////////////////////////////////////////
|
|
4781
|
-
/////////////////////////////////////////////////////
|
|
4782
|
-
////////// //////////
|
|
4783
|
-
////////// ZodDiscriminatedUnion //////////
|
|
4784
|
-
////////// //////////
|
|
4785
|
-
/////////////////////////////////////////////////////
|
|
4786
|
-
/////////////////////////////////////////////////////
|
|
4787
|
-
const getDiscriminator = (type) => {
|
|
4788
|
-
if (type instanceof ZodLazy) {
|
|
4789
|
-
return getDiscriminator(type.schema);
|
|
4790
|
-
}
|
|
4791
|
-
else if (type instanceof ZodEffects) {
|
|
4792
|
-
return getDiscriminator(type.innerType());
|
|
4793
|
-
}
|
|
4794
|
-
else if (type instanceof ZodLiteral) {
|
|
4795
|
-
return [type.value];
|
|
4796
|
-
}
|
|
4797
|
-
else if (type instanceof ZodEnum) {
|
|
4798
|
-
return type.options;
|
|
4799
|
-
}
|
|
4800
|
-
else if (type instanceof ZodNativeEnum) {
|
|
4801
|
-
// eslint-disable-next-line ban/ban
|
|
4802
|
-
return util.objectValues(type.enum);
|
|
4803
|
-
}
|
|
4804
|
-
else if (type instanceof ZodDefault) {
|
|
4805
|
-
return getDiscriminator(type._def.innerType);
|
|
4806
|
-
}
|
|
4807
|
-
else if (type instanceof ZodUndefined) {
|
|
4808
|
-
return [undefined];
|
|
4809
|
-
}
|
|
4810
|
-
else if (type instanceof ZodNull) {
|
|
4811
|
-
return [null];
|
|
4812
|
-
}
|
|
4813
|
-
else if (type instanceof ZodOptional) {
|
|
4814
|
-
return [undefined, ...getDiscriminator(type.unwrap())];
|
|
4815
|
-
}
|
|
4816
|
-
else if (type instanceof ZodNullable) {
|
|
4817
|
-
return [null, ...getDiscriminator(type.unwrap())];
|
|
4818
|
-
}
|
|
4819
|
-
else if (type instanceof ZodBranded) {
|
|
4820
|
-
return getDiscriminator(type.unwrap());
|
|
4821
|
-
}
|
|
4822
|
-
else if (type instanceof ZodReadonly) {
|
|
4823
|
-
return getDiscriminator(type.unwrap());
|
|
4824
|
-
}
|
|
4825
|
-
else if (type instanceof ZodCatch) {
|
|
4826
|
-
return getDiscriminator(type._def.innerType);
|
|
4827
|
-
}
|
|
4828
|
-
else {
|
|
4829
|
-
return [];
|
|
4830
|
-
}
|
|
4831
|
-
};
|
|
4832
|
-
class ZodDiscriminatedUnion extends ZodType {
|
|
4833
|
-
_parse(input) {
|
|
4834
|
-
const { ctx } = this._processInputParams(input);
|
|
4835
|
-
if (ctx.parsedType !== ZodParsedType.object) {
|
|
4836
|
-
addIssueToContext(ctx, {
|
|
4837
|
-
code: ZodIssueCode.invalid_type,
|
|
4838
|
-
expected: ZodParsedType.object,
|
|
4839
|
-
received: ctx.parsedType,
|
|
4840
|
-
});
|
|
4841
|
-
return INVALID;
|
|
4842
|
-
}
|
|
4843
|
-
const discriminator = this.discriminator;
|
|
4844
|
-
const discriminatorValue = ctx.data[discriminator];
|
|
4845
|
-
const option = this.optionsMap.get(discriminatorValue);
|
|
4846
|
-
if (!option) {
|
|
4847
|
-
addIssueToContext(ctx, {
|
|
4848
|
-
code: ZodIssueCode.invalid_union_discriminator,
|
|
4849
|
-
options: Array.from(this.optionsMap.keys()),
|
|
4850
|
-
path: [discriminator],
|
|
4851
|
-
});
|
|
4852
|
-
return INVALID;
|
|
4853
|
-
}
|
|
4854
|
-
if (ctx.common.async) {
|
|
4855
|
-
return option._parseAsync({
|
|
4856
|
-
data: ctx.data,
|
|
4857
|
-
path: ctx.path,
|
|
4858
|
-
parent: ctx,
|
|
4859
|
-
});
|
|
4860
|
-
}
|
|
4861
|
-
else {
|
|
4862
|
-
return option._parseSync({
|
|
4863
|
-
data: ctx.data,
|
|
4864
|
-
path: ctx.path,
|
|
4865
|
-
parent: ctx,
|
|
4866
|
-
});
|
|
4867
|
-
}
|
|
4868
|
-
}
|
|
4869
|
-
get discriminator() {
|
|
4870
|
-
return this._def.discriminator;
|
|
4871
|
-
}
|
|
4872
|
-
get options() {
|
|
4873
|
-
return this._def.options;
|
|
4874
|
-
}
|
|
4875
|
-
get optionsMap() {
|
|
4876
|
-
return this._def.optionsMap;
|
|
4877
|
-
}
|
|
4878
|
-
/**
|
|
4879
|
-
* The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.
|
|
4880
|
-
* However, it only allows a union of objects, all of which need to share a discriminator property. This property must
|
|
4881
|
-
* have a different value for each object in the union.
|
|
4882
|
-
* @param discriminator the name of the discriminator property
|
|
4883
|
-
* @param types an array of object schemas
|
|
4884
|
-
* @param params
|
|
4885
|
-
*/
|
|
4886
|
-
static create(discriminator, options, params) {
|
|
4887
|
-
// Get all the valid discriminator values
|
|
4888
|
-
const optionsMap = new Map();
|
|
4889
|
-
// try {
|
|
4890
|
-
for (const type of options) {
|
|
4891
|
-
const discriminatorValues = getDiscriminator(type.shape[discriminator]);
|
|
4892
|
-
if (!discriminatorValues.length) {
|
|
4893
|
-
throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
|
|
4894
|
-
}
|
|
4895
|
-
for (const value of discriminatorValues) {
|
|
4896
|
-
if (optionsMap.has(value)) {
|
|
4897
|
-
throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
|
|
4898
|
-
}
|
|
4899
|
-
optionsMap.set(value, type);
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
return new ZodDiscriminatedUnion({
|
|
4903
|
-
typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
|
|
4904
|
-
discriminator,
|
|
4905
|
-
options,
|
|
4906
|
-
optionsMap,
|
|
4907
|
-
...processCreateParams(params),
|
|
4908
|
-
});
|
|
4909
|
-
}
|
|
4910
|
-
}
|
|
4911
4875
|
function mergeValues(a, b) {
|
|
4912
4876
|
const aType = getParsedType(a);
|
|
4913
4877
|
const bType = getParsedType(b);
|
|
@@ -4916,9 +4880,7 @@ function mergeValues(a, b) {
|
|
|
4916
4880
|
}
|
|
4917
4881
|
else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
|
|
4918
4882
|
const bKeys = util.objectKeys(b);
|
|
4919
|
-
const sharedKeys = util
|
|
4920
|
-
.objectKeys(a)
|
|
4921
|
-
.filter((key) => bKeys.indexOf(key) !== -1);
|
|
4883
|
+
const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
4922
4884
|
const newObj = { ...a, ...b };
|
|
4923
4885
|
for (const key of sharedKeys) {
|
|
4924
4886
|
const sharedValue = mergeValues(a[key], b[key]);
|
|
@@ -4945,9 +4907,7 @@ function mergeValues(a, b) {
|
|
|
4945
4907
|
}
|
|
4946
4908
|
return { valid: true, data: newArray };
|
|
4947
4909
|
}
|
|
4948
|
-
else if (aType === ZodParsedType.date &&
|
|
4949
|
-
bType === ZodParsedType.date &&
|
|
4950
|
-
+a === +b) {
|
|
4910
|
+
else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {
|
|
4951
4911
|
return { valid: true, data: a };
|
|
4952
4912
|
}
|
|
4953
4913
|
else {
|
|
@@ -5008,6 +4968,7 @@ ZodIntersection.create = (left, right, params) => {
|
|
|
5008
4968
|
...processCreateParams(params),
|
|
5009
4969
|
});
|
|
5010
4970
|
};
|
|
4971
|
+
// type ZodTupleItems = [ZodTypeAny, ...ZodTypeAny[]];
|
|
5011
4972
|
class ZodTuple extends ZodType {
|
|
5012
4973
|
_parse(input) {
|
|
5013
4974
|
const { status, ctx } = this._processInputParams(input);
|
|
@@ -5078,60 +5039,6 @@ ZodTuple.create = (schemas, params) => {
|
|
|
5078
5039
|
...processCreateParams(params),
|
|
5079
5040
|
});
|
|
5080
5041
|
};
|
|
5081
|
-
class ZodRecord extends ZodType {
|
|
5082
|
-
get keySchema() {
|
|
5083
|
-
return this._def.keyType;
|
|
5084
|
-
}
|
|
5085
|
-
get valueSchema() {
|
|
5086
|
-
return this._def.valueType;
|
|
5087
|
-
}
|
|
5088
|
-
_parse(input) {
|
|
5089
|
-
const { status, ctx } = this._processInputParams(input);
|
|
5090
|
-
if (ctx.parsedType !== ZodParsedType.object) {
|
|
5091
|
-
addIssueToContext(ctx, {
|
|
5092
|
-
code: ZodIssueCode.invalid_type,
|
|
5093
|
-
expected: ZodParsedType.object,
|
|
5094
|
-
received: ctx.parsedType,
|
|
5095
|
-
});
|
|
5096
|
-
return INVALID;
|
|
5097
|
-
}
|
|
5098
|
-
const pairs = [];
|
|
5099
|
-
const keyType = this._def.keyType;
|
|
5100
|
-
const valueType = this._def.valueType;
|
|
5101
|
-
for (const key in ctx.data) {
|
|
5102
|
-
pairs.push({
|
|
5103
|
-
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
|
|
5104
|
-
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
|
|
5105
|
-
alwaysSet: key in ctx.data,
|
|
5106
|
-
});
|
|
5107
|
-
}
|
|
5108
|
-
if (ctx.common.async) {
|
|
5109
|
-
return ParseStatus.mergeObjectAsync(status, pairs);
|
|
5110
|
-
}
|
|
5111
|
-
else {
|
|
5112
|
-
return ParseStatus.mergeObjectSync(status, pairs);
|
|
5113
|
-
}
|
|
5114
|
-
}
|
|
5115
|
-
get element() {
|
|
5116
|
-
return this._def.valueType;
|
|
5117
|
-
}
|
|
5118
|
-
static create(first, second, third) {
|
|
5119
|
-
if (second instanceof ZodType) {
|
|
5120
|
-
return new ZodRecord({
|
|
5121
|
-
keyType: first,
|
|
5122
|
-
valueType: second,
|
|
5123
|
-
typeName: ZodFirstPartyTypeKind.ZodRecord,
|
|
5124
|
-
...processCreateParams(third),
|
|
5125
|
-
});
|
|
5126
|
-
}
|
|
5127
|
-
return new ZodRecord({
|
|
5128
|
-
keyType: ZodString.create(),
|
|
5129
|
-
valueType: first,
|
|
5130
|
-
typeName: ZodFirstPartyTypeKind.ZodRecord,
|
|
5131
|
-
...processCreateParams(second),
|
|
5132
|
-
});
|
|
5133
|
-
}
|
|
5134
|
-
}
|
|
5135
5042
|
class ZodMap extends ZodType {
|
|
5136
5043
|
get keySchema() {
|
|
5137
5044
|
return this._def.keyType;
|
|
@@ -5285,159 +5192,31 @@ ZodSet.create = (valueType, params) => {
|
|
|
5285
5192
|
...processCreateParams(params),
|
|
5286
5193
|
});
|
|
5287
5194
|
};
|
|
5288
|
-
class
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
this.validate = this.implement;
|
|
5195
|
+
class ZodLazy extends ZodType {
|
|
5196
|
+
get schema() {
|
|
5197
|
+
return this._def.getter();
|
|
5292
5198
|
}
|
|
5293
5199
|
_parse(input) {
|
|
5294
5200
|
const { ctx } = this._processInputParams(input);
|
|
5295
|
-
|
|
5201
|
+
const lazySchema = this._def.getter();
|
|
5202
|
+
return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
|
|
5203
|
+
}
|
|
5204
|
+
}
|
|
5205
|
+
ZodLazy.create = (getter, params) => {
|
|
5206
|
+
return new ZodLazy({
|
|
5207
|
+
getter: getter,
|
|
5208
|
+
typeName: ZodFirstPartyTypeKind.ZodLazy,
|
|
5209
|
+
...processCreateParams(params),
|
|
5210
|
+
});
|
|
5211
|
+
};
|
|
5212
|
+
class ZodLiteral extends ZodType {
|
|
5213
|
+
_parse(input) {
|
|
5214
|
+
if (input.data !== this._def.value) {
|
|
5215
|
+
const ctx = this._getOrReturnCtx(input);
|
|
5296
5216
|
addIssueToContext(ctx, {
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
});
|
|
5301
|
-
return INVALID;
|
|
5302
|
-
}
|
|
5303
|
-
function makeArgsIssue(args, error) {
|
|
5304
|
-
return makeIssue({
|
|
5305
|
-
data: args,
|
|
5306
|
-
path: ctx.path,
|
|
5307
|
-
errorMaps: [
|
|
5308
|
-
ctx.common.contextualErrorMap,
|
|
5309
|
-
ctx.schemaErrorMap,
|
|
5310
|
-
getErrorMap(),
|
|
5311
|
-
errorMap,
|
|
5312
|
-
].filter((x) => !!x),
|
|
5313
|
-
issueData: {
|
|
5314
|
-
code: ZodIssueCode.invalid_arguments,
|
|
5315
|
-
argumentsError: error,
|
|
5316
|
-
},
|
|
5317
|
-
});
|
|
5318
|
-
}
|
|
5319
|
-
function makeReturnsIssue(returns, error) {
|
|
5320
|
-
return makeIssue({
|
|
5321
|
-
data: returns,
|
|
5322
|
-
path: ctx.path,
|
|
5323
|
-
errorMaps: [
|
|
5324
|
-
ctx.common.contextualErrorMap,
|
|
5325
|
-
ctx.schemaErrorMap,
|
|
5326
|
-
getErrorMap(),
|
|
5327
|
-
errorMap,
|
|
5328
|
-
].filter((x) => !!x),
|
|
5329
|
-
issueData: {
|
|
5330
|
-
code: ZodIssueCode.invalid_return_type,
|
|
5331
|
-
returnTypeError: error,
|
|
5332
|
-
},
|
|
5333
|
-
});
|
|
5334
|
-
}
|
|
5335
|
-
const params = { errorMap: ctx.common.contextualErrorMap };
|
|
5336
|
-
const fn = ctx.data;
|
|
5337
|
-
if (this._def.returns instanceof ZodPromise) {
|
|
5338
|
-
// Would love a way to avoid disabling this rule, but we need
|
|
5339
|
-
// an alias (using an arrow function was what caused 2651).
|
|
5340
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
5341
|
-
const me = this;
|
|
5342
|
-
return OK(async function (...args) {
|
|
5343
|
-
const error = new ZodError([]);
|
|
5344
|
-
const parsedArgs = await me._def.args
|
|
5345
|
-
.parseAsync(args, params)
|
|
5346
|
-
.catch((e) => {
|
|
5347
|
-
error.addIssue(makeArgsIssue(args, e));
|
|
5348
|
-
throw error;
|
|
5349
|
-
});
|
|
5350
|
-
const result = await Reflect.apply(fn, this, parsedArgs);
|
|
5351
|
-
const parsedReturns = await me._def.returns._def.type
|
|
5352
|
-
.parseAsync(result, params)
|
|
5353
|
-
.catch((e) => {
|
|
5354
|
-
error.addIssue(makeReturnsIssue(result, e));
|
|
5355
|
-
throw error;
|
|
5356
|
-
});
|
|
5357
|
-
return parsedReturns;
|
|
5358
|
-
});
|
|
5359
|
-
}
|
|
5360
|
-
else {
|
|
5361
|
-
// Would love a way to avoid disabling this rule, but we need
|
|
5362
|
-
// an alias (using an arrow function was what caused 2651).
|
|
5363
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
5364
|
-
const me = this;
|
|
5365
|
-
return OK(function (...args) {
|
|
5366
|
-
const parsedArgs = me._def.args.safeParse(args, params);
|
|
5367
|
-
if (!parsedArgs.success) {
|
|
5368
|
-
throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
|
|
5369
|
-
}
|
|
5370
|
-
const result = Reflect.apply(fn, this, parsedArgs.data);
|
|
5371
|
-
const parsedReturns = me._def.returns.safeParse(result, params);
|
|
5372
|
-
if (!parsedReturns.success) {
|
|
5373
|
-
throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
|
|
5374
|
-
}
|
|
5375
|
-
return parsedReturns.data;
|
|
5376
|
-
});
|
|
5377
|
-
}
|
|
5378
|
-
}
|
|
5379
|
-
parameters() {
|
|
5380
|
-
return this._def.args;
|
|
5381
|
-
}
|
|
5382
|
-
returnType() {
|
|
5383
|
-
return this._def.returns;
|
|
5384
|
-
}
|
|
5385
|
-
args(...items) {
|
|
5386
|
-
return new ZodFunction({
|
|
5387
|
-
...this._def,
|
|
5388
|
-
args: ZodTuple.create(items).rest(ZodUnknown.create()),
|
|
5389
|
-
});
|
|
5390
|
-
}
|
|
5391
|
-
returns(returnType) {
|
|
5392
|
-
return new ZodFunction({
|
|
5393
|
-
...this._def,
|
|
5394
|
-
returns: returnType,
|
|
5395
|
-
});
|
|
5396
|
-
}
|
|
5397
|
-
implement(func) {
|
|
5398
|
-
const validatedFunc = this.parse(func);
|
|
5399
|
-
return validatedFunc;
|
|
5400
|
-
}
|
|
5401
|
-
strictImplement(func) {
|
|
5402
|
-
const validatedFunc = this.parse(func);
|
|
5403
|
-
return validatedFunc;
|
|
5404
|
-
}
|
|
5405
|
-
static create(args, returns, params) {
|
|
5406
|
-
return new ZodFunction({
|
|
5407
|
-
args: (args
|
|
5408
|
-
? args
|
|
5409
|
-
: ZodTuple.create([]).rest(ZodUnknown.create())),
|
|
5410
|
-
returns: returns || ZodUnknown.create(),
|
|
5411
|
-
typeName: ZodFirstPartyTypeKind.ZodFunction,
|
|
5412
|
-
...processCreateParams(params),
|
|
5413
|
-
});
|
|
5414
|
-
}
|
|
5415
|
-
}
|
|
5416
|
-
class ZodLazy extends ZodType {
|
|
5417
|
-
get schema() {
|
|
5418
|
-
return this._def.getter();
|
|
5419
|
-
}
|
|
5420
|
-
_parse(input) {
|
|
5421
|
-
const { ctx } = this._processInputParams(input);
|
|
5422
|
-
const lazySchema = this._def.getter();
|
|
5423
|
-
return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
|
|
5424
|
-
}
|
|
5425
|
-
}
|
|
5426
|
-
ZodLazy.create = (getter, params) => {
|
|
5427
|
-
return new ZodLazy({
|
|
5428
|
-
getter: getter,
|
|
5429
|
-
typeName: ZodFirstPartyTypeKind.ZodLazy,
|
|
5430
|
-
...processCreateParams(params),
|
|
5431
|
-
});
|
|
5432
|
-
};
|
|
5433
|
-
class ZodLiteral extends ZodType {
|
|
5434
|
-
_parse(input) {
|
|
5435
|
-
if (input.data !== this._def.value) {
|
|
5436
|
-
const ctx = this._getOrReturnCtx(input);
|
|
5437
|
-
addIssueToContext(ctx, {
|
|
5438
|
-
received: ctx.data,
|
|
5439
|
-
code: ZodIssueCode.invalid_literal,
|
|
5440
|
-
expected: this._def.value,
|
|
5217
|
+
received: ctx.data,
|
|
5218
|
+
code: ZodIssueCode.invalid_literal,
|
|
5219
|
+
expected: this._def.value,
|
|
5441
5220
|
});
|
|
5442
5221
|
return INVALID;
|
|
5443
5222
|
}
|
|
@@ -5462,10 +5241,6 @@ function createZodEnum(values, params) {
|
|
|
5462
5241
|
});
|
|
5463
5242
|
}
|
|
5464
5243
|
class ZodEnum extends ZodType {
|
|
5465
|
-
constructor() {
|
|
5466
|
-
super(...arguments);
|
|
5467
|
-
_ZodEnum_cache.set(this, void 0);
|
|
5468
|
-
}
|
|
5469
5244
|
_parse(input) {
|
|
5470
5245
|
if (typeof input.data !== "string") {
|
|
5471
5246
|
const ctx = this._getOrReturnCtx(input);
|
|
@@ -5477,10 +5252,10 @@ class ZodEnum extends ZodType {
|
|
|
5477
5252
|
});
|
|
5478
5253
|
return INVALID;
|
|
5479
5254
|
}
|
|
5480
|
-
if (!
|
|
5481
|
-
|
|
5255
|
+
if (!this._cache) {
|
|
5256
|
+
this._cache = new Set(this._def.values);
|
|
5482
5257
|
}
|
|
5483
|
-
if (!
|
|
5258
|
+
if (!this._cache.has(input.data)) {
|
|
5484
5259
|
const ctx = this._getOrReturnCtx(input);
|
|
5485
5260
|
const expectedValues = this._def.values;
|
|
5486
5261
|
addIssueToContext(ctx, {
|
|
@@ -5529,18 +5304,12 @@ class ZodEnum extends ZodType {
|
|
|
5529
5304
|
});
|
|
5530
5305
|
}
|
|
5531
5306
|
}
|
|
5532
|
-
_ZodEnum_cache = new WeakMap();
|
|
5533
5307
|
ZodEnum.create = createZodEnum;
|
|
5534
5308
|
class ZodNativeEnum extends ZodType {
|
|
5535
|
-
constructor() {
|
|
5536
|
-
super(...arguments);
|
|
5537
|
-
_ZodNativeEnum_cache.set(this, void 0);
|
|
5538
|
-
}
|
|
5539
5309
|
_parse(input) {
|
|
5540
5310
|
const nativeEnumValues = util.getValidEnumValues(this._def.values);
|
|
5541
5311
|
const ctx = this._getOrReturnCtx(input);
|
|
5542
|
-
if (ctx.parsedType !== ZodParsedType.string &&
|
|
5543
|
-
ctx.parsedType !== ZodParsedType.number) {
|
|
5312
|
+
if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {
|
|
5544
5313
|
const expectedValues = util.objectValues(nativeEnumValues);
|
|
5545
5314
|
addIssueToContext(ctx, {
|
|
5546
5315
|
expected: util.joinValues(expectedValues),
|
|
@@ -5549,10 +5318,10 @@ class ZodNativeEnum extends ZodType {
|
|
|
5549
5318
|
});
|
|
5550
5319
|
return INVALID;
|
|
5551
5320
|
}
|
|
5552
|
-
if (!
|
|
5553
|
-
|
|
5321
|
+
if (!this._cache) {
|
|
5322
|
+
this._cache = new Set(util.getValidEnumValues(this._def.values));
|
|
5554
5323
|
}
|
|
5555
|
-
if (!
|
|
5324
|
+
if (!this._cache.has(input.data)) {
|
|
5556
5325
|
const expectedValues = util.objectValues(nativeEnumValues);
|
|
5557
5326
|
addIssueToContext(ctx, {
|
|
5558
5327
|
received: ctx.data,
|
|
@@ -5567,7 +5336,6 @@ class ZodNativeEnum extends ZodType {
|
|
|
5567
5336
|
return this._def.values;
|
|
5568
5337
|
}
|
|
5569
5338
|
}
|
|
5570
|
-
_ZodNativeEnum_cache = new WeakMap();
|
|
5571
5339
|
ZodNativeEnum.create = (values, params) => {
|
|
5572
5340
|
return new ZodNativeEnum({
|
|
5573
5341
|
values: values,
|
|
@@ -5581,8 +5349,7 @@ class ZodPromise extends ZodType {
|
|
|
5581
5349
|
}
|
|
5582
5350
|
_parse(input) {
|
|
5583
5351
|
const { ctx } = this._processInputParams(input);
|
|
5584
|
-
if (ctx.parsedType !== ZodParsedType.promise &&
|
|
5585
|
-
ctx.common.async === false) {
|
|
5352
|
+
if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {
|
|
5586
5353
|
addIssueToContext(ctx, {
|
|
5587
5354
|
code: ZodIssueCode.invalid_type,
|
|
5588
5355
|
expected: ZodParsedType.promise,
|
|
@@ -5590,9 +5357,7 @@ class ZodPromise extends ZodType {
|
|
|
5590
5357
|
});
|
|
5591
5358
|
return INVALID;
|
|
5592
5359
|
}
|
|
5593
|
-
const promisified = ctx.parsedType === ZodParsedType.promise
|
|
5594
|
-
? ctx.data
|
|
5595
|
-
: Promise.resolve(ctx.data);
|
|
5360
|
+
const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
|
|
5596
5361
|
return OK(promisified.then((data) => {
|
|
5597
5362
|
return this._def.type.parseAsync(data, {
|
|
5598
5363
|
path: ctx.path,
|
|
@@ -5698,9 +5463,7 @@ class ZodEffects extends ZodType {
|
|
|
5698
5463
|
return { status: status.value, value: inner.value };
|
|
5699
5464
|
}
|
|
5700
5465
|
else {
|
|
5701
|
-
return this._def.schema
|
|
5702
|
-
._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })
|
|
5703
|
-
.then((inner) => {
|
|
5466
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
|
|
5704
5467
|
if (inner.status === "aborted")
|
|
5705
5468
|
return INVALID;
|
|
5706
5469
|
if (inner.status === "dirty")
|
|
@@ -5719,7 +5482,7 @@ class ZodEffects extends ZodType {
|
|
|
5719
5482
|
parent: ctx,
|
|
5720
5483
|
});
|
|
5721
5484
|
if (!isValid(base))
|
|
5722
|
-
return
|
|
5485
|
+
return INVALID;
|
|
5723
5486
|
const result = effect.transform(base.value, checkCtx);
|
|
5724
5487
|
if (result instanceof Promise) {
|
|
5725
5488
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
@@ -5727,12 +5490,13 @@ class ZodEffects extends ZodType {
|
|
|
5727
5490
|
return { status: status.value, value: result };
|
|
5728
5491
|
}
|
|
5729
5492
|
else {
|
|
5730
|
-
return this._def.schema
|
|
5731
|
-
._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })
|
|
5732
|
-
.then((base) => {
|
|
5493
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
|
|
5733
5494
|
if (!isValid(base))
|
|
5734
|
-
return
|
|
5735
|
-
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
5495
|
+
return INVALID;
|
|
5496
|
+
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
5497
|
+
status: status.value,
|
|
5498
|
+
value: result,
|
|
5499
|
+
}));
|
|
5736
5500
|
});
|
|
5737
5501
|
}
|
|
5738
5502
|
}
|
|
@@ -5814,9 +5578,7 @@ ZodDefault.create = (type, params) => {
|
|
|
5814
5578
|
return new ZodDefault({
|
|
5815
5579
|
innerType: type,
|
|
5816
5580
|
typeName: ZodFirstPartyTypeKind.ZodDefault,
|
|
5817
|
-
defaultValue: typeof params.default === "function"
|
|
5818
|
-
? params.default
|
|
5819
|
-
: () => params.default,
|
|
5581
|
+
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
|
|
5820
5582
|
...processCreateParams(params),
|
|
5821
5583
|
});
|
|
5822
5584
|
};
|
|
@@ -5900,7 +5662,6 @@ ZodNaN.create = (params) => {
|
|
|
5900
5662
|
...processCreateParams(params),
|
|
5901
5663
|
});
|
|
5902
5664
|
};
|
|
5903
|
-
const BRAND = Symbol("zod_brand");
|
|
5904
5665
|
class ZodBranded extends ZodType {
|
|
5905
5666
|
_parse(input) {
|
|
5906
5667
|
const { ctx } = this._processInputParams(input);
|
|
@@ -5982,9 +5743,7 @@ class ZodReadonly extends ZodType {
|
|
|
5982
5743
|
}
|
|
5983
5744
|
return data;
|
|
5984
5745
|
};
|
|
5985
|
-
return isAsync(result)
|
|
5986
|
-
? result.then((data) => freeze(data))
|
|
5987
|
-
: freeze(result);
|
|
5746
|
+
return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
|
|
5988
5747
|
}
|
|
5989
5748
|
unwrap() {
|
|
5990
5749
|
return this._def.innerType;
|
|
@@ -5997,60 +5756,9 @@ ZodReadonly.create = (type, params) => {
|
|
|
5997
5756
|
...processCreateParams(params),
|
|
5998
5757
|
});
|
|
5999
5758
|
};
|
|
6000
|
-
|
|
6001
|
-
////////////////////////////////////////
|
|
6002
|
-
////////// //////////
|
|
6003
|
-
////////// z.custom //////////
|
|
6004
|
-
////////// //////////
|
|
6005
|
-
////////////////////////////////////////
|
|
6006
|
-
////////////////////////////////////////
|
|
6007
|
-
function cleanParams(params, data) {
|
|
6008
|
-
const p = typeof params === "function"
|
|
6009
|
-
? params(data)
|
|
6010
|
-
: typeof params === "string"
|
|
6011
|
-
? { message: params }
|
|
6012
|
-
: params;
|
|
6013
|
-
const p2 = typeof p === "string" ? { message: p } : p;
|
|
6014
|
-
return p2;
|
|
6015
|
-
}
|
|
6016
|
-
function custom(check, _params = {},
|
|
6017
|
-
/**
|
|
6018
|
-
* @deprecated
|
|
6019
|
-
*
|
|
6020
|
-
* Pass `fatal` into the params object instead:
|
|
6021
|
-
*
|
|
6022
|
-
* ```ts
|
|
6023
|
-
* z.string().custom((val) => val.length > 5, { fatal: false })
|
|
6024
|
-
* ```
|
|
6025
|
-
*
|
|
6026
|
-
*/
|
|
6027
|
-
fatal) {
|
|
6028
|
-
if (check)
|
|
6029
|
-
return ZodAny.create().superRefine((data, ctx) => {
|
|
6030
|
-
var _a, _b;
|
|
6031
|
-
const r = check(data);
|
|
6032
|
-
if (r instanceof Promise) {
|
|
6033
|
-
return r.then((r) => {
|
|
6034
|
-
var _a, _b;
|
|
6035
|
-
if (!r) {
|
|
6036
|
-
const params = cleanParams(_params, data);
|
|
6037
|
-
const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
|
|
6038
|
-
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
6039
|
-
}
|
|
6040
|
-
});
|
|
6041
|
-
}
|
|
6042
|
-
if (!r) {
|
|
6043
|
-
const params = cleanParams(_params, data);
|
|
6044
|
-
const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
|
|
6045
|
-
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
6046
|
-
}
|
|
6047
|
-
return;
|
|
6048
|
-
});
|
|
6049
|
-
return ZodAny.create();
|
|
6050
|
-
}
|
|
6051
|
-
const late = {
|
|
5759
|
+
({
|
|
6052
5760
|
object: ZodObject.lazycreate,
|
|
6053
|
-
};
|
|
5761
|
+
});
|
|
6054
5762
|
var ZodFirstPartyTypeKind;
|
|
6055
5763
|
(function (ZodFirstPartyTypeKind) {
|
|
6056
5764
|
ZodFirstPartyTypeKind["ZodString"] = "ZodString";
|
|
@@ -6090,174 +5798,23 @@ var ZodFirstPartyTypeKind;
|
|
|
6090
5798
|
ZodFirstPartyTypeKind["ZodPipeline"] = "ZodPipeline";
|
|
6091
5799
|
ZodFirstPartyTypeKind["ZodReadonly"] = "ZodReadonly";
|
|
6092
5800
|
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
|
6093
|
-
const instanceOfType = (
|
|
6094
|
-
// const instanceOfType = <T extends new (...args: any[]) => any>(
|
|
6095
|
-
cls, params = {
|
|
6096
|
-
message: `Input not instance of ${cls.name}`,
|
|
6097
|
-
}) => custom((data) => data instanceof cls, params);
|
|
6098
5801
|
const stringType = ZodString.create;
|
|
6099
|
-
|
|
6100
|
-
const nanType = ZodNaN.create;
|
|
6101
|
-
const bigIntType = ZodBigInt.create;
|
|
6102
|
-
const booleanType = ZodBoolean.create;
|
|
6103
|
-
const dateType = ZodDate.create;
|
|
6104
|
-
const symbolType = ZodSymbol.create;
|
|
6105
|
-
const undefinedType = ZodUndefined.create;
|
|
6106
|
-
const nullType = ZodNull.create;
|
|
6107
|
-
const anyType = ZodAny.create;
|
|
6108
|
-
const unknownType = ZodUnknown.create;
|
|
6109
|
-
const neverType = ZodNever.create;
|
|
6110
|
-
const voidType = ZodVoid.create;
|
|
5802
|
+
ZodNever.create;
|
|
6111
5803
|
const arrayType = ZodArray.create;
|
|
6112
5804
|
const objectType = ZodObject.create;
|
|
6113
|
-
|
|
5805
|
+
ZodObject.strictCreate;
|
|
6114
5806
|
const unionType = ZodUnion.create;
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
const tupleType = ZodTuple.create;
|
|
6118
|
-
const recordType = ZodRecord.create;
|
|
6119
|
-
const mapType = ZodMap.create;
|
|
6120
|
-
const setType = ZodSet.create;
|
|
6121
|
-
const functionType = ZodFunction.create;
|
|
6122
|
-
const lazyType = ZodLazy.create;
|
|
5807
|
+
ZodIntersection.create;
|
|
5808
|
+
ZodTuple.create;
|
|
6123
5809
|
const literalType = ZodLiteral.create;
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
const
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
const ostring = () => stringType().optional();
|
|
6133
|
-
const onumber = () => numberType().optional();
|
|
6134
|
-
const oboolean = () => booleanType().optional();
|
|
6135
|
-
const coerce = {
|
|
6136
|
-
string: ((arg) => ZodString.create({ ...arg, coerce: true })),
|
|
6137
|
-
number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
|
|
6138
|
-
boolean: ((arg) => ZodBoolean.create({
|
|
6139
|
-
...arg,
|
|
6140
|
-
coerce: true,
|
|
6141
|
-
})),
|
|
6142
|
-
bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
|
|
6143
|
-
date: ((arg) => ZodDate.create({ ...arg, coerce: true })),
|
|
6144
|
-
};
|
|
6145
|
-
const NEVER = INVALID;
|
|
6146
|
-
|
|
6147
|
-
var z = /*#__PURE__*/Object.freeze({
|
|
6148
|
-
__proto__: null,
|
|
6149
|
-
defaultErrorMap: errorMap,
|
|
6150
|
-
setErrorMap: setErrorMap,
|
|
6151
|
-
getErrorMap: getErrorMap,
|
|
6152
|
-
makeIssue: makeIssue,
|
|
6153
|
-
EMPTY_PATH: EMPTY_PATH,
|
|
6154
|
-
addIssueToContext: addIssueToContext,
|
|
6155
|
-
ParseStatus: ParseStatus,
|
|
6156
|
-
INVALID: INVALID,
|
|
6157
|
-
DIRTY: DIRTY,
|
|
6158
|
-
OK: OK,
|
|
6159
|
-
isAborted: isAborted,
|
|
6160
|
-
isDirty: isDirty,
|
|
6161
|
-
isValid: isValid,
|
|
6162
|
-
isAsync: isAsync,
|
|
6163
|
-
get util () { return util; },
|
|
6164
|
-
get objectUtil () { return objectUtil; },
|
|
6165
|
-
ZodParsedType: ZodParsedType,
|
|
6166
|
-
getParsedType: getParsedType,
|
|
6167
|
-
ZodType: ZodType,
|
|
6168
|
-
datetimeRegex: datetimeRegex,
|
|
6169
|
-
ZodString: ZodString,
|
|
6170
|
-
ZodNumber: ZodNumber,
|
|
6171
|
-
ZodBigInt: ZodBigInt,
|
|
6172
|
-
ZodBoolean: ZodBoolean,
|
|
6173
|
-
ZodDate: ZodDate,
|
|
6174
|
-
ZodSymbol: ZodSymbol,
|
|
6175
|
-
ZodUndefined: ZodUndefined,
|
|
6176
|
-
ZodNull: ZodNull,
|
|
6177
|
-
ZodAny: ZodAny,
|
|
6178
|
-
ZodUnknown: ZodUnknown,
|
|
6179
|
-
ZodNever: ZodNever,
|
|
6180
|
-
ZodVoid: ZodVoid,
|
|
6181
|
-
ZodArray: ZodArray,
|
|
6182
|
-
ZodObject: ZodObject,
|
|
6183
|
-
ZodUnion: ZodUnion,
|
|
6184
|
-
ZodDiscriminatedUnion: ZodDiscriminatedUnion,
|
|
6185
|
-
ZodIntersection: ZodIntersection,
|
|
6186
|
-
ZodTuple: ZodTuple,
|
|
6187
|
-
ZodRecord: ZodRecord,
|
|
6188
|
-
ZodMap: ZodMap,
|
|
6189
|
-
ZodSet: ZodSet,
|
|
6190
|
-
ZodFunction: ZodFunction,
|
|
6191
|
-
ZodLazy: ZodLazy,
|
|
6192
|
-
ZodLiteral: ZodLiteral,
|
|
6193
|
-
ZodEnum: ZodEnum,
|
|
6194
|
-
ZodNativeEnum: ZodNativeEnum,
|
|
6195
|
-
ZodPromise: ZodPromise,
|
|
6196
|
-
ZodEffects: ZodEffects,
|
|
6197
|
-
ZodTransformer: ZodEffects,
|
|
6198
|
-
ZodOptional: ZodOptional,
|
|
6199
|
-
ZodNullable: ZodNullable,
|
|
6200
|
-
ZodDefault: ZodDefault,
|
|
6201
|
-
ZodCatch: ZodCatch,
|
|
6202
|
-
ZodNaN: ZodNaN,
|
|
6203
|
-
BRAND: BRAND,
|
|
6204
|
-
ZodBranded: ZodBranded,
|
|
6205
|
-
ZodPipeline: ZodPipeline,
|
|
6206
|
-
ZodReadonly: ZodReadonly,
|
|
6207
|
-
custom: custom,
|
|
6208
|
-
Schema: ZodType,
|
|
6209
|
-
ZodSchema: ZodType,
|
|
6210
|
-
late: late,
|
|
6211
|
-
get ZodFirstPartyTypeKind () { return ZodFirstPartyTypeKind; },
|
|
6212
|
-
coerce: coerce,
|
|
6213
|
-
any: anyType,
|
|
6214
|
-
array: arrayType,
|
|
6215
|
-
bigint: bigIntType,
|
|
6216
|
-
boolean: booleanType,
|
|
6217
|
-
date: dateType,
|
|
6218
|
-
discriminatedUnion: discriminatedUnionType,
|
|
6219
|
-
effect: effectsType,
|
|
6220
|
-
'enum': enumType,
|
|
6221
|
-
'function': functionType,
|
|
6222
|
-
'instanceof': instanceOfType,
|
|
6223
|
-
intersection: intersectionType,
|
|
6224
|
-
lazy: lazyType,
|
|
6225
|
-
literal: literalType,
|
|
6226
|
-
map: mapType,
|
|
6227
|
-
nan: nanType,
|
|
6228
|
-
nativeEnum: nativeEnumType,
|
|
6229
|
-
never: neverType,
|
|
6230
|
-
'null': nullType,
|
|
6231
|
-
nullable: nullableType,
|
|
6232
|
-
number: numberType,
|
|
6233
|
-
object: objectType,
|
|
6234
|
-
oboolean: oboolean,
|
|
6235
|
-
onumber: onumber,
|
|
6236
|
-
optional: optionalType,
|
|
6237
|
-
ostring: ostring,
|
|
6238
|
-
pipeline: pipelineType,
|
|
6239
|
-
preprocess: preprocessType,
|
|
6240
|
-
promise: promiseType,
|
|
6241
|
-
record: recordType,
|
|
6242
|
-
set: setType,
|
|
6243
|
-
strictObject: strictObjectType,
|
|
6244
|
-
string: stringType,
|
|
6245
|
-
symbol: symbolType,
|
|
6246
|
-
transformer: effectsType,
|
|
6247
|
-
tuple: tupleType,
|
|
6248
|
-
'undefined': undefinedType,
|
|
6249
|
-
union: unionType,
|
|
6250
|
-
unknown: unknownType,
|
|
6251
|
-
'void': voidType,
|
|
6252
|
-
NEVER: NEVER,
|
|
6253
|
-
ZodIssueCode: ZodIssueCode,
|
|
6254
|
-
quotelessJson: quotelessJson,
|
|
6255
|
-
ZodError: ZodError
|
|
6256
|
-
});
|
|
6257
|
-
|
|
6258
|
-
const ChangelogResponseSchema = z.object({
|
|
6259
|
-
title: z.string(),
|
|
6260
|
-
content: z.string(),
|
|
5810
|
+
ZodEnum.create;
|
|
5811
|
+
ZodPromise.create;
|
|
5812
|
+
ZodOptional.create;
|
|
5813
|
+
ZodNullable.create;
|
|
5814
|
+
|
|
5815
|
+
const ChangelogResponseSchema = objectType({
|
|
5816
|
+
title: stringType(),
|
|
5817
|
+
content: stringType(),
|
|
6261
5818
|
});
|
|
6262
5819
|
const command$4 = 'changelog';
|
|
6263
5820
|
/**
|
|
@@ -6291,70 +5848,234 @@ const builder$4 = (yargs) => {
|
|
|
6291
5848
|
};
|
|
6292
5849
|
|
|
6293
5850
|
/**
|
|
6294
|
-
*
|
|
5851
|
+
* Default retry predicate - retries on non-validation errors
|
|
5852
|
+
*/
|
|
5853
|
+
function defaultShouldRetry(error) {
|
|
5854
|
+
// Don't retry validation errors or configuration errors
|
|
5855
|
+
if (error.name.includes('Validation') || error.name.includes('Configuration')) {
|
|
5856
|
+
return false;
|
|
5857
|
+
}
|
|
5858
|
+
// Don't retry authentication errors
|
|
5859
|
+
if (error.name.includes('Authentication')) {
|
|
5860
|
+
return false;
|
|
5861
|
+
}
|
|
5862
|
+
// Retry execution errors and timeouts
|
|
5863
|
+
return true;
|
|
5864
|
+
}
|
|
5865
|
+
/**
|
|
5866
|
+
* Executes an operation with retry logic
|
|
5867
|
+
*/
|
|
5868
|
+
async function withRetry(operation, options = {}) {
|
|
5869
|
+
const { maxAttempts = 3, backoffMs = 1000, backoffMultiplier = 2, maxBackoffMs = 10000, onRetry, shouldRetry = defaultShouldRetry } = options;
|
|
5870
|
+
let lastError = new Error('No attempts made');
|
|
5871
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
5872
|
+
try {
|
|
5873
|
+
return await operation();
|
|
5874
|
+
}
|
|
5875
|
+
catch (error) {
|
|
5876
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
5877
|
+
// If this is the last attempt or we shouldn't retry, throw the error
|
|
5878
|
+
if (attempt === maxAttempts || !shouldRetry(lastError)) {
|
|
5879
|
+
throw lastError;
|
|
5880
|
+
}
|
|
5881
|
+
// Calculate delay with exponential backoff
|
|
5882
|
+
const delay = Math.min(backoffMs * Math.pow(backoffMultiplier, attempt - 1), maxBackoffMs);
|
|
5883
|
+
// Call retry callback if provided
|
|
5884
|
+
if (onRetry) {
|
|
5885
|
+
onRetry(attempt, lastError, delay);
|
|
5886
|
+
}
|
|
5887
|
+
// Wait before retrying
|
|
5888
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
5889
|
+
}
|
|
5890
|
+
}
|
|
5891
|
+
// This should never be reached, but TypeScript requires it
|
|
5892
|
+
throw new Error(`Operation failed after ${maxAttempts} attempts. Last error: ${lastError.message}`);
|
|
5893
|
+
}
|
|
5894
|
+
|
|
5895
|
+
/**
|
|
5896
|
+
* Wraps errors with additional context and converts them to LangChain errors
|
|
5897
|
+
*/
|
|
5898
|
+
function handleLangChainError(error, context, additionalContext) {
|
|
5899
|
+
// If it's already a LangChain error, re-throw with additional context
|
|
5900
|
+
if (error instanceof LangChainError) {
|
|
5901
|
+
throw new LangChainExecutionError(`${context}: ${error.message}`, {
|
|
5902
|
+
...error.context,
|
|
5903
|
+
...additionalContext,
|
|
5904
|
+
originalError: error.name,
|
|
5905
|
+
context
|
|
5906
|
+
});
|
|
5907
|
+
}
|
|
5908
|
+
// If it's a regular Error, wrap it
|
|
5909
|
+
if (error instanceof Error) {
|
|
5910
|
+
throw new LangChainExecutionError(`${context}: ${error.message}`, {
|
|
5911
|
+
originalError: error.name,
|
|
5912
|
+
originalMessage: error.message,
|
|
5913
|
+
stack: error.stack,
|
|
5914
|
+
context,
|
|
5915
|
+
...additionalContext
|
|
5916
|
+
});
|
|
5917
|
+
}
|
|
5918
|
+
// For unknown error types
|
|
5919
|
+
throw new LangChainExecutionError(`${context}: Unknown error occurred`, {
|
|
5920
|
+
originalError: typeof error,
|
|
5921
|
+
originalValue: String(error),
|
|
5922
|
+
context,
|
|
5923
|
+
...additionalContext
|
|
5924
|
+
});
|
|
5925
|
+
}
|
|
5926
|
+
|
|
5927
|
+
/**
|
|
5928
|
+
* Creates and configures an LLM instance based on the provider and configuration.
|
|
6295
5929
|
*
|
|
6296
|
-
* @param
|
|
6297
|
-
* @param
|
|
6298
|
-
* @
|
|
5930
|
+
* @param provider - The LLM provider (openai, anthropic, ollama)
|
|
5931
|
+
* @param model - The specific model to use
|
|
5932
|
+
* @param config - The configuration object containing service settings
|
|
5933
|
+
* @returns Configured LLM instance
|
|
5934
|
+
* @throws LangChainConfigurationError if the provider/model combination is invalid
|
|
5935
|
+
* @throws LangChainExecutionError if LLM instantiation fails
|
|
6299
5936
|
*/
|
|
6300
5937
|
function getLlm(provider, model, config) {
|
|
6301
|
-
|
|
6302
|
-
|
|
5938
|
+
// Validate input parameters
|
|
5939
|
+
validateProvider(provider, 'getLlm');
|
|
5940
|
+
validateModel(model, provider, 'getLlm');
|
|
5941
|
+
validateRequired(config, 'config', 'getLlm');
|
|
5942
|
+
// Get the API key once and validate it
|
|
5943
|
+
let apiKey;
|
|
5944
|
+
try {
|
|
5945
|
+
apiKey = getApiKeyForModel(config);
|
|
6303
5946
|
}
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
5947
|
+
catch (error) {
|
|
5948
|
+
handleLangChainError(error, 'getLlm: Failed to retrieve API key', { provider, model });
|
|
5949
|
+
}
|
|
5950
|
+
try {
|
|
5951
|
+
switch (provider) {
|
|
5952
|
+
case 'anthropic':
|
|
5953
|
+
return new ChatAnthropic({
|
|
5954
|
+
anthropicApiKey: apiKey,
|
|
5955
|
+
maxConcurrency: config.service.maxConcurrent,
|
|
5956
|
+
model,
|
|
5957
|
+
});
|
|
5958
|
+
case 'ollama':
|
|
5959
|
+
// Use endpoint from service config if available, otherwise fall back to default
|
|
5960
|
+
const endpoint = 'endpoint' in config.service
|
|
5961
|
+
? config.service.endpoint
|
|
5962
|
+
: DEFAULT_OLLAMA_LLM_SERVICE.endpoint;
|
|
5963
|
+
return new ChatOllama({
|
|
5964
|
+
baseUrl: endpoint,
|
|
5965
|
+
maxConcurrency: config.service.maxConcurrent,
|
|
5966
|
+
model,
|
|
5967
|
+
});
|
|
5968
|
+
case 'openai':
|
|
5969
|
+
return new ChatOpenAI({
|
|
5970
|
+
openAIApiKey: apiKey,
|
|
5971
|
+
model,
|
|
5972
|
+
temperature: config.service.temperature || 0.2,
|
|
5973
|
+
});
|
|
5974
|
+
default:
|
|
5975
|
+
throw new LangChainConfigurationError(`getLlm: Unsupported provider '${provider}'`, { provider, model, supportedProviders: ['openai', 'anthropic', 'ollama'] });
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
catch (error) {
|
|
5979
|
+
// If it's already a LangChain error, re-throw it
|
|
5980
|
+
if (error instanceof LangChainConfigurationError || error instanceof LangChainExecutionError) {
|
|
5981
|
+
throw error;
|
|
5982
|
+
}
|
|
5983
|
+
// Wrap other errors
|
|
5984
|
+
handleLangChainError(error, `getLlm: Failed to instantiate ${provider} LLM`, {
|
|
5985
|
+
provider,
|
|
5986
|
+
model,
|
|
5987
|
+
hasApiKey: !!apiKey,
|
|
5988
|
+
serviceConfig: {
|
|
6314
5989
|
maxConcurrency: config.service.maxConcurrent,
|
|
6315
|
-
|
|
6316
|
-
}
|
|
6317
|
-
|
|
6318
|
-
default:
|
|
6319
|
-
const openAiModel = new ChatOpenAI({
|
|
6320
|
-
openAIApiKey: getApiKeyForModel(config),
|
|
6321
|
-
model,
|
|
6322
|
-
temperature: config.service.temperature || 0.2,
|
|
6323
|
-
});
|
|
6324
|
-
return openAiModel;
|
|
5990
|
+
temperature: config.service.temperature
|
|
5991
|
+
}
|
|
5992
|
+
});
|
|
6325
5993
|
}
|
|
6326
5994
|
}
|
|
6327
5995
|
|
|
5996
|
+
/**
|
|
5997
|
+
* Creates a PromptTemplate from a template string or returns a fallback template.
|
|
5998
|
+
*
|
|
5999
|
+
* @param params - The prompt creation parameters
|
|
6000
|
+
* @returns A configured PromptTemplate instance
|
|
6001
|
+
* @throws LangChainValidationError if neither template nor fallback is provided or if parameters are invalid
|
|
6002
|
+
* @throws LangChainExecutionError if PromptTemplate instantiation fails
|
|
6003
|
+
*/
|
|
6328
6004
|
function getPrompt({ template, variables, fallback }) {
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6005
|
+
// Validate that we have either a template or fallback
|
|
6006
|
+
if (!template && !fallback) {
|
|
6007
|
+
throw new LangChainValidationError('getPrompt: Must provide either a template string or a fallback PromptTemplate', { hasTemplate: !!template, hasFallback: !!fallback, variables });
|
|
6008
|
+
}
|
|
6009
|
+
// Validate variables array
|
|
6010
|
+
validateRequired(variables, 'variables', 'getPrompt');
|
|
6011
|
+
validateNonEmptyArray(variables, 'variables', 'getPrompt');
|
|
6012
|
+
// If using template, validate it and create PromptTemplate
|
|
6013
|
+
if (template) {
|
|
6014
|
+
validateNonEmptyString(template, 'template', 'getPrompt');
|
|
6015
|
+
try {
|
|
6016
|
+
return new PromptTemplate({
|
|
6017
|
+
template,
|
|
6018
|
+
inputVariables: variables,
|
|
6019
|
+
templateFormat: 'mustache',
|
|
6020
|
+
});
|
|
6021
|
+
}
|
|
6022
|
+
catch (error) {
|
|
6023
|
+
handleLangChainError(error, 'getPrompt: Failed to create PromptTemplate', {
|
|
6024
|
+
template: template.substring(0, 100) + (template.length > 100 ? '...' : ''),
|
|
6025
|
+
variables,
|
|
6026
|
+
templateFormat: 'mustache'
|
|
6027
|
+
});
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
6030
|
+
// Validate fallback if using it
|
|
6031
|
+
if (fallback) {
|
|
6032
|
+
validateRequired(fallback, 'fallback', 'getPrompt');
|
|
6033
|
+
if (!(fallback instanceof PromptTemplate)) {
|
|
6034
|
+
throw new LangChainValidationError('getPrompt: Fallback must be a PromptTemplate instance', { fallbackType: typeof fallback, fallbackConstructor: fallback.constructor?.name });
|
|
6035
|
+
}
|
|
6036
|
+
return fallback;
|
|
6037
|
+
}
|
|
6038
|
+
// This should never be reached, but TypeScript requires it
|
|
6039
|
+
throw new LangChainExecutionError('getPrompt: Unexpected execution path - neither template nor fallback available', { template, fallback, variables });
|
|
6338
6040
|
}
|
|
6339
6041
|
|
|
6042
|
+
/**
|
|
6043
|
+
* Executes a LangChain pipeline with the provided LLM, prompt, variables, and parser.
|
|
6044
|
+
* @param params - The execution parameters
|
|
6045
|
+
* @returns The parsed result from the LLM chain
|
|
6046
|
+
* @throws LangChainExecutionError if the chain execution fails or returns empty results
|
|
6047
|
+
*/
|
|
6340
6048
|
const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
6341
|
-
|
|
6342
|
-
|
|
6049
|
+
// Validate all required parameters
|
|
6050
|
+
validateRequired(llm, 'llm', 'executeChain');
|
|
6051
|
+
validateRequired(prompt, 'prompt', 'executeChain');
|
|
6052
|
+
validateRequired(variables, 'variables', 'executeChain');
|
|
6053
|
+
validateRequired(parser, 'parser', 'executeChain');
|
|
6054
|
+
// Validate that variables is an object
|
|
6055
|
+
if (typeof variables !== 'object' || Array.isArray(variables)) {
|
|
6056
|
+
throw new LangChainExecutionError('executeChain: Variables must be a non-array object', { variables, type: typeof variables, isArray: Array.isArray(variables) });
|
|
6343
6057
|
}
|
|
6344
|
-
const chain = prompt.pipe(llm).pipe(parser);
|
|
6345
|
-
let res;
|
|
6346
6058
|
try {
|
|
6347
|
-
|
|
6059
|
+
const chain = prompt.pipe(llm).pipe(parser);
|
|
6060
|
+
const result = await chain.invoke(variables);
|
|
6061
|
+
console.debug('LLMChain call result:', result);
|
|
6062
|
+
if (result === null || result === undefined) {
|
|
6063
|
+
throw new LangChainExecutionError('executeChain: Chain execution returned null or undefined result', { variables, promptInputVariables: prompt.inputVariables });
|
|
6064
|
+
}
|
|
6065
|
+
return result;
|
|
6348
6066
|
}
|
|
6349
6067
|
catch (error) {
|
|
6350
|
-
|
|
6351
|
-
|
|
6068
|
+
// Re-throw LangChain errors as-is
|
|
6069
|
+
if (error instanceof LangChainExecutionError) {
|
|
6070
|
+
throw error;
|
|
6352
6071
|
}
|
|
6072
|
+
// Wrap other errors with context
|
|
6073
|
+
handleLangChainError(error, 'executeChain: Chain execution failed', {
|
|
6074
|
+
promptInputVariables: prompt.inputVariables,
|
|
6075
|
+
variableKeys: Object.keys(variables),
|
|
6076
|
+
parserType: parser.constructor.name
|
|
6077
|
+
});
|
|
6353
6078
|
}
|
|
6354
|
-
if (!res) {
|
|
6355
|
-
throw new Error('Empty response from LLMChain call');
|
|
6356
|
-
}
|
|
6357
|
-
return res;
|
|
6358
6079
|
};
|
|
6359
6080
|
|
|
6360
6081
|
function extractTicketIdFromBranchName(branchName) {
|
|
@@ -6393,19 +6114,20 @@ const getChangesSinceLastTag = async ({ git }) => {
|
|
|
6393
6114
|
};
|
|
6394
6115
|
|
|
6395
6116
|
/**
|
|
6396
|
-
* Retrieves the commit log range between two specified commits.
|
|
6117
|
+
* Retrieves the commit log range between two specified commits (inclusive of both commits).
|
|
6397
6118
|
*
|
|
6398
|
-
* @param from - The starting commit (can be a commit hash, HEAD reference, or branch name).
|
|
6399
|
-
* @param to - The ending commit (can be a commit hash, HEAD reference, or branch name).
|
|
6119
|
+
* @param from - The starting commit (can be a commit hash, HEAD reference, or branch name). This commit will be included in the results.
|
|
6120
|
+
* @param to - The ending commit (can be a commit hash, HEAD reference, or branch name). This commit will be included in the results.
|
|
6400
6121
|
* @param options - Additional options for retrieving the commit log range.
|
|
6401
|
-
* @returns A promise that resolves to an array of commit log messages.
|
|
6122
|
+
* @returns A promise that resolves to an array of commit log messages, including both the 'from' and 'to' commits.
|
|
6402
6123
|
* @throws If there is an error retrieving the commit log range.
|
|
6403
6124
|
*/
|
|
6404
6125
|
async function getCommitLogRange(from, to, { noMerges, git }) {
|
|
6405
6126
|
try {
|
|
6406
|
-
// Use
|
|
6127
|
+
// Use from^..to to include the 'from' commit in the range
|
|
6128
|
+
// This works because from^..to means "commits reachable from 'to' but not from the parent of 'from'"
|
|
6407
6129
|
const logOptions = {
|
|
6408
|
-
from
|
|
6130
|
+
from: `${from}^`,
|
|
6409
6131
|
to,
|
|
6410
6132
|
'--no-merges': noMerges
|
|
6411
6133
|
};
|
|
@@ -6413,7 +6135,29 @@ async function getCommitLogRange(from, to, { noMerges, git }) {
|
|
|
6413
6135
|
return commitLog.all.map(({ message, date, body, author_name, hash, author_email }) => `[${date}] ${message}\n${body}\n(${hash}) - ${author_name}<${author_email}>`);
|
|
6414
6136
|
}
|
|
6415
6137
|
catch (error) {
|
|
6416
|
-
// If
|
|
6138
|
+
// If from^ fails (e.g., 'from' is the first commit), fall back to using from..to and manually adding the 'from' commit
|
|
6139
|
+
if (error instanceof Error && error.message.includes('unknown revision')) {
|
|
6140
|
+
try {
|
|
6141
|
+
// Get the 'from' commit separately
|
|
6142
|
+
const fromCommitLog = await git.log({ from: from, maxCount: 1 });
|
|
6143
|
+
const fromCommit = fromCommitLog.latest;
|
|
6144
|
+
// Get the range from..to (excluding 'from')
|
|
6145
|
+
const rangeLogOptions = {
|
|
6146
|
+
from,
|
|
6147
|
+
to,
|
|
6148
|
+
'--no-merges': noMerges
|
|
6149
|
+
};
|
|
6150
|
+
const rangeCommitLog = await git.log(rangeLogOptions);
|
|
6151
|
+
// Combine the 'from' commit with the range commits
|
|
6152
|
+
const allCommits = fromCommit
|
|
6153
|
+
? [fromCommit, ...rangeCommitLog.all]
|
|
6154
|
+
: rangeCommitLog.all;
|
|
6155
|
+
return allCommits.map(({ message, date, body, author_name, hash, author_email }) => `[${date}] ${message}\n${body}\n(${hash}) - ${author_name}<${author_email}>`);
|
|
6156
|
+
}
|
|
6157
|
+
catch (fallbackError) {
|
|
6158
|
+
throw fallbackError;
|
|
6159
|
+
}
|
|
6160
|
+
}
|
|
6417
6161
|
throw error;
|
|
6418
6162
|
}
|
|
6419
6163
|
}
|
|
@@ -6474,38 +6218,38 @@ async function getCommitLogAgainstBranch({ git, logger, targetBranch, }) {
|
|
|
6474
6218
|
*/
|
|
6475
6219
|
async function getCommitLogCurrentBranch({ git, logger, comparisonBranch = 'main', comparisonRemote = 'origin', }) {
|
|
6476
6220
|
try {
|
|
6477
|
-
|
|
6478
|
-
const
|
|
6479
|
-
// Check if the current branch has any commits
|
|
6480
|
-
const hasCommits = (await git.raw(['rev-list', '--count', branch])) !== '0';
|
|
6221
|
+
const branchName = await getCurrentBranchName({ git });
|
|
6222
|
+
const hasCommits = (await git.raw(['rev-list', '--count', branchName])) !== '0';
|
|
6481
6223
|
if (!hasCommits) {
|
|
6482
6224
|
logger?.log('No commits on the current branch.');
|
|
6483
6225
|
return [];
|
|
6484
6226
|
}
|
|
6485
|
-
// Get the list of commits that are unique to the current branch
|
|
6486
6227
|
let uniqueCommits;
|
|
6487
|
-
if (comparisonBranch ===
|
|
6228
|
+
if (comparisonBranch === branchName) {
|
|
6488
6229
|
// If the comparison branch is the same as the current branch, we compare against the remote.
|
|
6489
|
-
uniqueCommits = (await git.raw(['rev-list', `${comparisonRemote}/${comparisonBranch}..${
|
|
6230
|
+
uniqueCommits = (await git.raw(['rev-list', `${comparisonRemote}/${comparisonBranch}..${branchName}`]))
|
|
6490
6231
|
.split('\n')
|
|
6491
6232
|
.filter(Boolean)
|
|
6492
6233
|
.reverse();
|
|
6493
6234
|
}
|
|
6494
6235
|
else {
|
|
6495
6236
|
// Your existing code for different branches
|
|
6496
|
-
uniqueCommits = (await git.raw(['rev-list', `${comparisonBranch}..${
|
|
6237
|
+
uniqueCommits = (await git.raw(['rev-list', `${comparisonBranch}..${branchName}`]))
|
|
6497
6238
|
.split('\n')
|
|
6498
6239
|
.filter(Boolean)
|
|
6499
6240
|
.reverse();
|
|
6500
6241
|
}
|
|
6501
|
-
logger?.verbose(`Found ${uniqueCommits.length} unique commits on "${
|
|
6242
|
+
logger?.verbose(`Found ${uniqueCommits.length} unique commits on "${branchName}"`, {
|
|
6243
|
+
color: 'blue',
|
|
6244
|
+
});
|
|
6502
6245
|
const firstCommit = uniqueCommits[0];
|
|
6503
6246
|
const lastCommit = uniqueCommits[uniqueCommits.length - 1];
|
|
6504
6247
|
if (!firstCommit || !lastCommit) {
|
|
6505
|
-
logger?.log('Unable to determine first and last commit on the current branch', {
|
|
6248
|
+
logger?.log('Unable to determine first and last commit on the current branch', {
|
|
6249
|
+
color: 'yellow',
|
|
6250
|
+
});
|
|
6506
6251
|
return [];
|
|
6507
6252
|
}
|
|
6508
|
-
// Retrieve commit log with messages
|
|
6509
6253
|
return await getCommitLogRange(firstCommit, lastCommit, { git, noMerges: true });
|
|
6510
6254
|
}
|
|
6511
6255
|
catch (error) {
|
|
@@ -6634,17 +6378,35 @@ const CONVENTIONAL_COMMIT_PROMPT = new PromptTemplate({
|
|
|
6634
6378
|
*
|
|
6635
6379
|
* @param text template string
|
|
6636
6380
|
* @param inputVariables template variables
|
|
6637
|
-
* @
|
|
6381
|
+
* @throws Error if validation fails
|
|
6638
6382
|
*/
|
|
6639
6383
|
function validatePromptTemplate(text, inputVariables) {
|
|
6640
|
-
if (!text) {
|
|
6641
|
-
|
|
6384
|
+
if (!text || text.trim() === '') {
|
|
6385
|
+
throw new Error('Prompt template cannot be empty');
|
|
6642
6386
|
}
|
|
6643
|
-
if (!inputVariables.
|
|
6644
|
-
return
|
|
6645
|
-
|
|
6387
|
+
if (!inputVariables || inputVariables.length === 0) {
|
|
6388
|
+
return; // No variables to validate
|
|
6389
|
+
}
|
|
6390
|
+
// Extract variables from template using regex to find {variable} patterns
|
|
6391
|
+
// This regex matches {variable_name} with no whitespace inside braces
|
|
6392
|
+
// Excludes JSON-like patterns with quotes, colons, or whitespace
|
|
6393
|
+
const templateVariableRegex = /\{([^}\s:"']+)\}/g;
|
|
6394
|
+
const foundVariables = new Set();
|
|
6395
|
+
let match;
|
|
6396
|
+
while ((match = templateVariableRegex.exec(text)) !== null) {
|
|
6397
|
+
foundVariables.add(match[1]);
|
|
6398
|
+
}
|
|
6399
|
+
// Check if all required variables are present in template
|
|
6400
|
+
const missingVariables = inputVariables.filter(variable => !foundVariables.has(variable));
|
|
6401
|
+
if (missingVariables.length > 0) {
|
|
6402
|
+
throw new Error(`Prompt template is missing required variables: ${missingVariables.map(v => `{${v}}`).join(', ')}. ` +
|
|
6403
|
+
`Found variables: ${Array.from(foundVariables).map(v => `{${v}}`).join(', ') || 'none'}`);
|
|
6404
|
+
}
|
|
6405
|
+
// Warn about unused variables in template (optional check)
|
|
6406
|
+
const unusedVariables = Array.from(foundVariables).filter(variable => !inputVariables.includes(variable));
|
|
6407
|
+
if (unusedVariables.length > 0) {
|
|
6408
|
+
console.warn(`Prompt template contains undefined variables: ${unusedVariables.map(v => `{${v}}`).join(', ')}`);
|
|
6646
6409
|
}
|
|
6647
|
-
return true;
|
|
6648
6410
|
}
|
|
6649
6411
|
|
|
6650
6412
|
async function editPrompt(options) {
|
|
@@ -6653,7 +6415,15 @@ async function editPrompt(options) {
|
|
|
6653
6415
|
default: options.prompt?.length ? options.prompt : COMMIT_PROMPT.template,
|
|
6654
6416
|
waitForUseInput: false,
|
|
6655
6417
|
postfix: 'Press ENTER to continue',
|
|
6656
|
-
validate: (text) =>
|
|
6418
|
+
validate: (text) => {
|
|
6419
|
+
try {
|
|
6420
|
+
validatePromptTemplate(text, COMMIT_PROMPT.inputVariables);
|
|
6421
|
+
return true;
|
|
6422
|
+
}
|
|
6423
|
+
catch (error) {
|
|
6424
|
+
return error instanceof Error ? error.message : 'Invalid prompt template';
|
|
6425
|
+
}
|
|
6426
|
+
},
|
|
6657
6427
|
});
|
|
6658
6428
|
}
|
|
6659
6429
|
|
|
@@ -6872,7 +6642,9 @@ const handler$4 = async (argv, logger) => {
|
|
|
6872
6642
|
const llm = getLlm(provider, model, config);
|
|
6873
6643
|
const INTERACTIVE = isInteractive(config);
|
|
6874
6644
|
if (INTERACTIVE) {
|
|
6875
|
-
|
|
6645
|
+
if (!config.hideCocoBanner) {
|
|
6646
|
+
logger.log(LOGO);
|
|
6647
|
+
}
|
|
6876
6648
|
}
|
|
6877
6649
|
async function factory() {
|
|
6878
6650
|
const branchName = await getCurrentBranchName({ git });
|
|
@@ -6904,9 +6676,10 @@ const handler$4 = async (argv, logger) => {
|
|
|
6904
6676
|
logger.verbose(`No range, branch, or tag option provided. Defaulting to current branch`, {
|
|
6905
6677
|
color: 'yellow',
|
|
6906
6678
|
});
|
|
6679
|
+
const commits = await getCommitLogCurrentBranch({ git, logger });
|
|
6907
6680
|
return {
|
|
6908
6681
|
branch: branchName,
|
|
6909
|
-
commits
|
|
6682
|
+
commits,
|
|
6910
6683
|
};
|
|
6911
6684
|
}
|
|
6912
6685
|
async function parser({ branch, commits }) {
|
|
@@ -6983,16 +6756,16 @@ var changelog = {
|
|
|
6983
6756
|
|
|
6984
6757
|
const conventionalTypeRegex = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?:/;
|
|
6985
6758
|
// Regular commit message schema with basic validation
|
|
6986
|
-
const CommitMessageResponseSchema =
|
|
6987
|
-
title:
|
|
6988
|
-
body:
|
|
6759
|
+
const CommitMessageResponseSchema = objectType({
|
|
6760
|
+
title: stringType(),
|
|
6761
|
+
body: stringType(),
|
|
6989
6762
|
});
|
|
6990
6763
|
// Conventional commit message schema with strict formatting rules
|
|
6991
|
-
const ConventionalCommitMessageResponseSchema =
|
|
6992
|
-
title:
|
|
6764
|
+
const ConventionalCommitMessageResponseSchema = objectType({
|
|
6765
|
+
title: stringType()
|
|
6993
6766
|
.max(50, "Title must be 50 characters or less")
|
|
6994
6767
|
.refine((title) => conventionalTypeRegex.test(title), "Title must follow Conventional Commits format (e.g., 'feat: add new feature' or 'fix(scope): fix bug')"),
|
|
6995
|
-
body:
|
|
6768
|
+
body: stringType()
|
|
6996
6769
|
// .max(280, "Body must be 280 characters or less"),
|
|
6997
6770
|
});
|
|
6998
6771
|
const command$3 = 'commit';
|
|
@@ -7049,152 +6822,33 @@ const builder$3 = (yargs) => {
|
|
|
7049
6822
|
return yargs.options(options$3).usage(getCommandUsageHeader(command$3));
|
|
7050
6823
|
};
|
|
7051
6824
|
|
|
7052
|
-
|
|
7053
|
-
* Extract the path from a file path string.
|
|
7054
|
-
* @param {string} filePath - The full file path.
|
|
7055
|
-
* @returns {string} The path portion of the file path.
|
|
7056
|
-
*/
|
|
7057
|
-
function getPathFromFilePath(filePath) {
|
|
7058
|
-
return filePath.split('/').slice(0, -1).join('/');
|
|
7059
|
-
}
|
|
7060
|
-
|
|
7061
|
-
async function summarize(documents, { chain, textSplitter, options }) {
|
|
7062
|
-
const { returnIntermediateSteps = false } = options || {};
|
|
7063
|
-
const docs = await textSplitter.splitDocuments(documents.map((doc) => new Document(doc)));
|
|
7064
|
-
const res = await chain.invoke({
|
|
7065
|
-
input_documents: docs,
|
|
7066
|
-
returnIntermediateSteps,
|
|
7067
|
-
});
|
|
7068
|
-
if (res.error)
|
|
7069
|
-
throw new Error(res.error);
|
|
7070
|
-
return res.text && res.text.trim();
|
|
7071
|
-
}
|
|
6825
|
+
new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
|
|
7072
6826
|
|
|
7073
6827
|
/**
|
|
7074
|
-
*
|
|
7075
|
-
* @param {DiffNode} node - The node info to start grouping.
|
|
7076
|
-
* @returns {DirectoryDiff[]} The groups created.
|
|
6828
|
+
* Base interface that all chains must implement.
|
|
7077
6829
|
*/
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
node.diffs.forEach((diff) => {
|
|
7082
|
-
const path = getPathFromFilePath(diff.file);
|
|
7083
|
-
if (!groupByPath[path]) {
|
|
7084
|
-
groupByPath[path] = { diffs: [], path, tokenCount: 0 };
|
|
7085
|
-
}
|
|
7086
|
-
groupByPath[path].diffs.push(diff);
|
|
7087
|
-
groupByPath[path].tokenCount += diff.tokenCount;
|
|
7088
|
-
});
|
|
7089
|
-
node.children.forEach(traverse);
|
|
6830
|
+
class BaseChain extends BaseLangChain {
|
|
6831
|
+
get lc_namespace() {
|
|
6832
|
+
return ["langchain", "chains", this._chainType()];
|
|
7090
6833
|
}
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
/**
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
returnIntermediateSteps: true,
|
|
7110
|
-
},
|
|
7111
|
-
});
|
|
7112
|
-
const newTokenTotal = tokenizer(directorySummary);
|
|
7113
|
-
return {
|
|
7114
|
-
diffs: directory.diffs,
|
|
7115
|
-
path: directory.path,
|
|
7116
|
-
summary: directorySummary,
|
|
7117
|
-
tokenCount: newTokenTotal,
|
|
7118
|
-
};
|
|
7119
|
-
}
|
|
7120
|
-
catch (error) {
|
|
7121
|
-
console.error(error);
|
|
7122
|
-
return directory;
|
|
7123
|
-
}
|
|
7124
|
-
}
|
|
7125
|
-
const defaultOutputCallback = (group) => {
|
|
7126
|
-
let output = `
|
|
7127
|
-
-------\n* changes in "/${group.path}"\n\n`;
|
|
7128
|
-
if (group.summary) {
|
|
7129
|
-
output += `${group.diffs.map((diff) => ` • ${diff.summary}`).join('\n')}\n\nSummary:\n\n${group.summary}\n\n`;
|
|
7130
|
-
}
|
|
7131
|
-
else {
|
|
7132
|
-
output += `${group.diffs.map((diff) => ` • ${diff.summary}\n\n${diff.diff}`).join('\n\n')}\n\n`;
|
|
7133
|
-
}
|
|
7134
|
-
return output;
|
|
7135
|
-
};
|
|
7136
|
-
async function summarizeDiffs(rootDiffNode, { tokenizer, logger, maxTokens = 2048, textSplitter, chain, handleOutput = defaultOutputCallback, }) {
|
|
7137
|
-
const queue = new pQueue({ concurrency: 8 });
|
|
7138
|
-
logger.startTimer().startSpinner(`Organizing Diffs...`, { color: 'blue' });
|
|
7139
|
-
const directoryDiffs = createDirectoryDiffs(rootDiffNode);
|
|
7140
|
-
// Sort by token count descending
|
|
7141
|
-
directoryDiffs.sort((a, b) => b.tokenCount - a.tokenCount);
|
|
7142
|
-
let totalTokenCount = directoryDiffs.reduce((sum, group) => sum + group.tokenCount, 0);
|
|
7143
|
-
logger.stopSpinner('Diffs Organized').stopTimer();
|
|
7144
|
-
logger.startSpinner(`Consolidating Diffs`, { color: 'blue' });
|
|
7145
|
-
const processingTasks = directoryDiffs.map((group, i) => {
|
|
7146
|
-
return queue.add(async () => {
|
|
7147
|
-
// If the diff token count is already less than the average req, we can skip summarizing.
|
|
7148
|
-
const isLessThanAvgTokenReq = group.tokenCount <= maxTokens / directoryDiffs.length;
|
|
7149
|
-
if (totalTokenCount <= maxTokens || isLessThanAvgTokenReq) {
|
|
7150
|
-
return group;
|
|
7151
|
-
}
|
|
7152
|
-
group = await summarizeDirectoryDiff(group, {
|
|
7153
|
-
chain,
|
|
7154
|
-
textSplitter,
|
|
7155
|
-
tokenizer,
|
|
7156
|
-
});
|
|
7157
|
-
// We need to subtract the old token count and add the new one
|
|
7158
|
-
totalTokenCount = totalTokenCount - directoryDiffs[i].tokenCount + group.tokenCount;
|
|
7159
|
-
directoryDiffs[i] = group;
|
|
7160
|
-
logger
|
|
7161
|
-
.verbose(`\n • Summarized diffs in "/${group.path}" `, { color: 'blue' })
|
|
7162
|
-
.verbose(`\nTotal token count: ${totalTokenCount}`, {
|
|
7163
|
-
color: totalTokenCount > maxTokens ? 'yellow' : 'green',
|
|
7164
|
-
});
|
|
7165
|
-
return group;
|
|
7166
|
-
}, { priority: group.tokenCount });
|
|
7167
|
-
});
|
|
7168
|
-
await Promise.all(processingTasks);
|
|
7169
|
-
logger.stopSpinner(`Summarized Diffs`);
|
|
7170
|
-
return directoryDiffs.map(handleOutput).join('');
|
|
7171
|
-
}
|
|
7172
|
-
|
|
7173
|
-
/**
|
|
7174
|
-
* Base interface that all chains must implement.
|
|
7175
|
-
*/
|
|
7176
|
-
class BaseChain extends BaseLangChain {
|
|
7177
|
-
get lc_namespace() {
|
|
7178
|
-
return ["langchain", "chains", this._chainType()];
|
|
7179
|
-
}
|
|
7180
|
-
constructor(fields,
|
|
7181
|
-
/** @deprecated */
|
|
7182
|
-
verbose,
|
|
7183
|
-
/** @deprecated */
|
|
7184
|
-
callbacks) {
|
|
7185
|
-
if (arguments.length === 1 &&
|
|
7186
|
-
typeof fields === "object" &&
|
|
7187
|
-
!("saveContext" in fields)) {
|
|
7188
|
-
// fields is not a BaseMemory
|
|
7189
|
-
const { memory, callbackManager, ...rest } = fields;
|
|
7190
|
-
super({ ...rest, callbacks: callbackManager ?? rest.callbacks });
|
|
7191
|
-
this.memory = memory;
|
|
7192
|
-
}
|
|
7193
|
-
else {
|
|
7194
|
-
// fields is a BaseMemory
|
|
7195
|
-
super({ verbose, callbacks });
|
|
7196
|
-
this.memory = fields;
|
|
7197
|
-
}
|
|
6834
|
+
constructor(fields,
|
|
6835
|
+
/** @deprecated */
|
|
6836
|
+
verbose,
|
|
6837
|
+
/** @deprecated */
|
|
6838
|
+
callbacks) {
|
|
6839
|
+
if (arguments.length === 1 &&
|
|
6840
|
+
typeof fields === "object" &&
|
|
6841
|
+
!("saveContext" in fields)) {
|
|
6842
|
+
// fields is not a BaseMemory
|
|
6843
|
+
const { memory, callbackManager, ...rest } = fields;
|
|
6844
|
+
super({ ...rest, callbacks: callbackManager ?? rest.callbacks });
|
|
6845
|
+
this.memory = memory;
|
|
6846
|
+
}
|
|
6847
|
+
else {
|
|
6848
|
+
// fields is a BaseMemory
|
|
6849
|
+
super({ verbose, callbacks });
|
|
6850
|
+
this.memory = fields;
|
|
6851
|
+
}
|
|
7198
6852
|
}
|
|
7199
6853
|
/** @ignore */
|
|
7200
6854
|
_selectMemoryInputs(values) {
|
|
@@ -7616,15 +7270,550 @@ class LLMChain extends BaseChain {
|
|
|
7616
7270
|
prompt: this.prompt.serialize(),
|
|
7617
7271
|
};
|
|
7618
7272
|
}
|
|
7619
|
-
_getNumTokens(text) {
|
|
7620
|
-
return _getLanguageModel(this.llm).getNumTokens(text);
|
|
7273
|
+
_getNumTokens(text) {
|
|
7274
|
+
return _getLanguageModel(this.llm).getNumTokens(text);
|
|
7275
|
+
}
|
|
7276
|
+
}
|
|
7277
|
+
|
|
7278
|
+
var llm_chain = /*#__PURE__*/Object.freeze({
|
|
7279
|
+
__proto__: null,
|
|
7280
|
+
LLMChain: LLMChain
|
|
7281
|
+
});
|
|
7282
|
+
|
|
7283
|
+
const NAIVE_FIX_TEMPLATE = `Instructions:
|
|
7284
|
+
--------------
|
|
7285
|
+
{instructions}
|
|
7286
|
+
--------------
|
|
7287
|
+
Completion:
|
|
7288
|
+
--------------
|
|
7289
|
+
{completion}
|
|
7290
|
+
--------------
|
|
7291
|
+
|
|
7292
|
+
Above, the Completion did not satisfy the constraints given in the Instructions.
|
|
7293
|
+
Error:
|
|
7294
|
+
--------------
|
|
7295
|
+
{error}
|
|
7296
|
+
--------------
|
|
7297
|
+
|
|
7298
|
+
Please try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:`;
|
|
7299
|
+
const NAIVE_FIX_PROMPT =
|
|
7300
|
+
/* #__PURE__ */ PromptTemplate.fromTemplate(NAIVE_FIX_TEMPLATE);
|
|
7301
|
+
|
|
7302
|
+
function isLLMChain(x) {
|
|
7303
|
+
return (x.prompt !== undefined && x.llm !== undefined);
|
|
7304
|
+
}
|
|
7305
|
+
/**
|
|
7306
|
+
* Class that extends the BaseOutputParser to handle situations where the
|
|
7307
|
+
* initial parsing attempt fails. It contains a retryChain for retrying
|
|
7308
|
+
* the parsing process in case of a failure.
|
|
7309
|
+
*/
|
|
7310
|
+
class OutputFixingParser extends BaseOutputParser {
|
|
7311
|
+
static lc_name() {
|
|
7312
|
+
return "OutputFixingParser";
|
|
7313
|
+
}
|
|
7314
|
+
/**
|
|
7315
|
+
* Static method to create a new instance of OutputFixingParser using a
|
|
7316
|
+
* given language model, parser, and optional fields.
|
|
7317
|
+
* @param llm The language model to be used.
|
|
7318
|
+
* @param parser The parser to be used.
|
|
7319
|
+
* @param fields Optional fields which may contain a prompt.
|
|
7320
|
+
* @returns A new instance of OutputFixingParser.
|
|
7321
|
+
*/
|
|
7322
|
+
static fromLLM(llm, parser, fields) {
|
|
7323
|
+
const prompt = fields?.prompt ?? NAIVE_FIX_PROMPT;
|
|
7324
|
+
const chain = new LLMChain({ llm, prompt });
|
|
7325
|
+
return new OutputFixingParser({ parser, retryChain: chain });
|
|
7326
|
+
}
|
|
7327
|
+
constructor({ parser, retryChain, }) {
|
|
7328
|
+
super(...arguments);
|
|
7329
|
+
Object.defineProperty(this, "lc_namespace", {
|
|
7330
|
+
enumerable: true,
|
|
7331
|
+
configurable: true,
|
|
7332
|
+
writable: true,
|
|
7333
|
+
value: ["langchain", "output_parsers", "fix"]
|
|
7334
|
+
});
|
|
7335
|
+
Object.defineProperty(this, "lc_serializable", {
|
|
7336
|
+
enumerable: true,
|
|
7337
|
+
configurable: true,
|
|
7338
|
+
writable: true,
|
|
7339
|
+
value: true
|
|
7340
|
+
});
|
|
7341
|
+
Object.defineProperty(this, "parser", {
|
|
7342
|
+
enumerable: true,
|
|
7343
|
+
configurable: true,
|
|
7344
|
+
writable: true,
|
|
7345
|
+
value: void 0
|
|
7346
|
+
});
|
|
7347
|
+
Object.defineProperty(this, "retryChain", {
|
|
7348
|
+
enumerable: true,
|
|
7349
|
+
configurable: true,
|
|
7350
|
+
writable: true,
|
|
7351
|
+
value: void 0
|
|
7352
|
+
});
|
|
7353
|
+
this.parser = parser;
|
|
7354
|
+
this.retryChain = retryChain;
|
|
7355
|
+
}
|
|
7356
|
+
/**
|
|
7357
|
+
* Method to parse the completion using the parser. If the initial parsing
|
|
7358
|
+
* fails, it uses the retryChain to attempt to fix the output and retry
|
|
7359
|
+
* the parsing process.
|
|
7360
|
+
* @param completion The completion to be parsed.
|
|
7361
|
+
* @param callbacks Optional callbacks to be used during parsing.
|
|
7362
|
+
* @returns The parsed output.
|
|
7363
|
+
*/
|
|
7364
|
+
async parse(completion, callbacks) {
|
|
7365
|
+
try {
|
|
7366
|
+
return await this.parser.parse(completion, callbacks);
|
|
7367
|
+
}
|
|
7368
|
+
catch (e) {
|
|
7369
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
7370
|
+
if (e instanceof OutputParserException) {
|
|
7371
|
+
const retryInput = {
|
|
7372
|
+
instructions: this.parser.getFormatInstructions(),
|
|
7373
|
+
completion,
|
|
7374
|
+
error: e,
|
|
7375
|
+
};
|
|
7376
|
+
if (isLLMChain(this.retryChain)) {
|
|
7377
|
+
const result = await this.retryChain.call(retryInput, callbacks);
|
|
7378
|
+
const newCompletion = result[this.retryChain.outputKey];
|
|
7379
|
+
return this.parser.parse(newCompletion, callbacks);
|
|
7380
|
+
}
|
|
7381
|
+
else {
|
|
7382
|
+
const result = await this.retryChain.invoke(retryInput, {
|
|
7383
|
+
callbacks,
|
|
7384
|
+
});
|
|
7385
|
+
return result;
|
|
7386
|
+
}
|
|
7387
|
+
}
|
|
7388
|
+
throw e;
|
|
7389
|
+
}
|
|
7390
|
+
}
|
|
7391
|
+
/**
|
|
7392
|
+
* Method to get the format instructions for the parser.
|
|
7393
|
+
* @returns The format instructions for the parser.
|
|
7394
|
+
*/
|
|
7395
|
+
getFormatInstructions() {
|
|
7396
|
+
return this.parser.getFormatInstructions();
|
|
7397
|
+
}
|
|
7398
|
+
}
|
|
7399
|
+
|
|
7400
|
+
/**
|
|
7401
|
+
* Creates a parser with built-in retry logic for schema-based generation
|
|
7402
|
+
* @param schema - Zod schema for the expected output structure
|
|
7403
|
+
* @param llm - LLM instance for retry attempts
|
|
7404
|
+
* @param options - Configuration options for retry behavior
|
|
7405
|
+
* @returns OutputFixingParser configured with retry logic
|
|
7406
|
+
* @throws LangChainExecutionError if parser creation fails
|
|
7407
|
+
*/
|
|
7408
|
+
function createSchemaParser(schema, llm, options = {}) {
|
|
7409
|
+
// Validate required parameters
|
|
7410
|
+
validateRequired(schema, 'schema', 'createSchemaParser');
|
|
7411
|
+
validateRequired(llm, 'llm', 'createSchemaParser');
|
|
7412
|
+
validateRequired(options, 'options', 'createSchemaParser');
|
|
7413
|
+
// Validate schema is actually a Zod schema
|
|
7414
|
+
if (typeof schema.parse !== 'function') {
|
|
7415
|
+
throw new LangChainExecutionError('createSchemaParser: Schema must be a valid Zod schema with a parse method', { schemaType: typeof schema, hasParseMethod: typeof schema.parse });
|
|
7416
|
+
}
|
|
7417
|
+
// Validate options structure
|
|
7418
|
+
if (typeof options !== 'object' || Array.isArray(options)) {
|
|
7419
|
+
throw new LangChainExecutionError('createSchemaParser: Options must be a non-array object', { options, type: typeof options, isArray: Array.isArray(options) });
|
|
7420
|
+
}
|
|
7421
|
+
const { retryTemplate } = options;
|
|
7422
|
+
// Validate retryTemplate if provided
|
|
7423
|
+
if (retryTemplate !== undefined && typeof retryTemplate !== 'string') {
|
|
7424
|
+
throw new LangChainExecutionError('createSchemaParser: retryTemplate must be a string when provided', { retryTemplate, type: typeof retryTemplate });
|
|
7425
|
+
}
|
|
7426
|
+
try {
|
|
7427
|
+
const baseParser = new StructuredOutputParser(schema);
|
|
7428
|
+
const defaultRetryTemplate = `The following text failed to parse as valid JSON. Please convert it into a valid JSON object that matches the required schema.
|
|
7429
|
+
|
|
7430
|
+
## Text to fix:
|
|
7431
|
+
{completion}
|
|
7432
|
+
|
|
7433
|
+
## Instructions:
|
|
7434
|
+
{instructions}
|
|
7435
|
+
|
|
7436
|
+
You must return ONLY valid JSON that matches the schema exactly. Do not include any additional text, explanations, or markdown formatting:`;
|
|
7437
|
+
const retryPromptTemplate = new PromptTemplate({
|
|
7438
|
+
template: retryTemplate || defaultRetryTemplate,
|
|
7439
|
+
inputVariables: ['completion', 'instructions'],
|
|
7440
|
+
});
|
|
7441
|
+
const retryChain = retryPromptTemplate.pipe(llm).pipe(baseParser);
|
|
7442
|
+
return new OutputFixingParser({
|
|
7443
|
+
parser: baseParser,
|
|
7444
|
+
retryChain: retryChain,
|
|
7445
|
+
});
|
|
7446
|
+
}
|
|
7447
|
+
catch (error) {
|
|
7448
|
+
handleLangChainError(error, 'createSchemaParser: Failed to create schema parser', {
|
|
7449
|
+
schemaName: schema.constructor.name,
|
|
7450
|
+
llmType: llm.constructor.name,
|
|
7451
|
+
hasRetryTemplate: !!retryTemplate
|
|
7452
|
+
});
|
|
7453
|
+
}
|
|
7454
|
+
}
|
|
7455
|
+
|
|
7456
|
+
/**
|
|
7457
|
+
* High-level function that combines chain execution with schema-based parsing
|
|
7458
|
+
* Includes automatic retry logic and graceful degradation
|
|
7459
|
+
* @param schema - Zod schema for the expected output structure
|
|
7460
|
+
* @param llm - LLM instance
|
|
7461
|
+
* @param prompt - Prompt template
|
|
7462
|
+
* @param variables - Variables for the prompt
|
|
7463
|
+
* @param options - Configuration options
|
|
7464
|
+
* @returns Parsed result matching the schema type
|
|
7465
|
+
*/
|
|
7466
|
+
async function executeChainWithSchema(schema, llm, prompt, variables, options = {}) {
|
|
7467
|
+
const { retryOptions = { maxAttempts: 3 }, fallbackParser, onFallback, ...parserOptions } = options;
|
|
7468
|
+
const parser = createSchemaParser(schema, llm, parserOptions);
|
|
7469
|
+
// Define the operation to retry
|
|
7470
|
+
const operation = async () => {
|
|
7471
|
+
const result = await executeChain({
|
|
7472
|
+
llm,
|
|
7473
|
+
prompt,
|
|
7474
|
+
variables,
|
|
7475
|
+
parser,
|
|
7476
|
+
});
|
|
7477
|
+
return result;
|
|
7478
|
+
};
|
|
7479
|
+
try {
|
|
7480
|
+
// Use the general retry utility
|
|
7481
|
+
return await withRetry(operation, retryOptions);
|
|
7482
|
+
}
|
|
7483
|
+
catch (error) {
|
|
7484
|
+
// If all retries failed and we have a fallback parser, use it
|
|
7485
|
+
if (fallbackParser) {
|
|
7486
|
+
if (onFallback) {
|
|
7487
|
+
onFallback();
|
|
7488
|
+
}
|
|
7489
|
+
// Generate without structured parsing as fallback
|
|
7490
|
+
const fallbackResult = await executeChain({
|
|
7491
|
+
llm,
|
|
7492
|
+
prompt,
|
|
7493
|
+
variables,
|
|
7494
|
+
parser: new StringOutputParser(),
|
|
7495
|
+
});
|
|
7496
|
+
const fallbackText = typeof fallbackResult === 'string' ? fallbackResult : String(fallbackResult);
|
|
7497
|
+
return fallbackParser(fallbackText);
|
|
7498
|
+
}
|
|
7499
|
+
// No fallback available, re-throw the error
|
|
7500
|
+
throw error;
|
|
7501
|
+
}
|
|
7502
|
+
}
|
|
7503
|
+
|
|
7504
|
+
/**
|
|
7505
|
+
* Extract the path from a file path string.
|
|
7506
|
+
* @param {string} filePath - The full file path.
|
|
7507
|
+
* @returns {string} The path portion of the file path.
|
|
7508
|
+
*/
|
|
7509
|
+
function getPathFromFilePath(filePath) {
|
|
7510
|
+
return filePath.split('/').slice(0, -1).join('/');
|
|
7511
|
+
}
|
|
7512
|
+
|
|
7513
|
+
async function summarize(documents, { chain, textSplitter, options }) {
|
|
7514
|
+
const { returnIntermediateSteps = false } = options || {};
|
|
7515
|
+
const docs = await textSplitter.splitDocuments(documents.map((doc) => new Document(doc)));
|
|
7516
|
+
const res = await chain.invoke({
|
|
7517
|
+
input_documents: docs,
|
|
7518
|
+
returnIntermediateSteps,
|
|
7519
|
+
});
|
|
7520
|
+
if (res.error)
|
|
7521
|
+
throw new Error(res.error);
|
|
7522
|
+
return res.text && res.text.trim();
|
|
7523
|
+
}
|
|
7524
|
+
|
|
7525
|
+
/**
|
|
7526
|
+
* Create groups from a given node info.
|
|
7527
|
+
* @param {DiffNode} node - The node info to start grouping.
|
|
7528
|
+
* @returns {DirectoryDiff[]} The groups created.
|
|
7529
|
+
*/
|
|
7530
|
+
function createDirectoryDiffs(node) {
|
|
7531
|
+
const groupByPath = {};
|
|
7532
|
+
function traverse(node) {
|
|
7533
|
+
node.diffs.forEach((diff) => {
|
|
7534
|
+
const path = getPathFromFilePath(diff.file);
|
|
7535
|
+
if (!groupByPath[path]) {
|
|
7536
|
+
groupByPath[path] = { diffs: [], path, tokenCount: 0 };
|
|
7537
|
+
}
|
|
7538
|
+
groupByPath[path].diffs.push(diff);
|
|
7539
|
+
groupByPath[path].tokenCount += diff.tokenCount;
|
|
7540
|
+
});
|
|
7541
|
+
node.children.forEach(traverse);
|
|
7542
|
+
}
|
|
7543
|
+
traverse(node);
|
|
7544
|
+
return Object.values(groupByPath);
|
|
7545
|
+
}
|
|
7546
|
+
/**
|
|
7547
|
+
* Summarize a directory diff asynchronously.
|
|
7548
|
+
*/
|
|
7549
|
+
async function summarizeDirectoryDiff(directory, { chain, textSplitter, tokenizer }) {
|
|
7550
|
+
try {
|
|
7551
|
+
const directorySummary = await summarize(directory.diffs.map((diff) => ({
|
|
7552
|
+
pageContent: diff.diff,
|
|
7553
|
+
metadata: {
|
|
7554
|
+
file: diff.file,
|
|
7555
|
+
summary: diff.summary,
|
|
7556
|
+
},
|
|
7557
|
+
})), {
|
|
7558
|
+
chain,
|
|
7559
|
+
textSplitter,
|
|
7560
|
+
options: {
|
|
7561
|
+
returnIntermediateSteps: true,
|
|
7562
|
+
},
|
|
7563
|
+
});
|
|
7564
|
+
const newTokenTotal = tokenizer(directorySummary);
|
|
7565
|
+
return {
|
|
7566
|
+
diffs: directory.diffs,
|
|
7567
|
+
path: directory.path,
|
|
7568
|
+
summary: directorySummary,
|
|
7569
|
+
tokenCount: newTokenTotal,
|
|
7570
|
+
};
|
|
7571
|
+
}
|
|
7572
|
+
catch (error) {
|
|
7573
|
+
console.error(error);
|
|
7574
|
+
return directory;
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7577
|
+
const defaultOutputCallback = (group) => {
|
|
7578
|
+
let output = `
|
|
7579
|
+
-------\n* changes in "/${group.path}"\n\n`;
|
|
7580
|
+
if (group.summary) {
|
|
7581
|
+
output += `${group.diffs.map((diff) => ` • ${diff.summary}`).join('\n')}\n\nSummary:\n\n${group.summary}\n\n`;
|
|
7582
|
+
}
|
|
7583
|
+
else {
|
|
7584
|
+
output += `${group.diffs.map((diff) => ` • ${diff.summary}\n\n${diff.diff}`).join('\n\n')}\n\n`;
|
|
7585
|
+
}
|
|
7586
|
+
return output;
|
|
7587
|
+
};
|
|
7588
|
+
async function summarizeDiffs(rootDiffNode, { tokenizer, logger, maxTokens = 2048, textSplitter, chain, handleOutput = defaultOutputCallback, }) {
|
|
7589
|
+
const queue = new pQueue({ concurrency: 8 });
|
|
7590
|
+
logger.startTimer().startSpinner(`Organizing Diffs...`, { color: 'blue' });
|
|
7591
|
+
const directoryDiffs = createDirectoryDiffs(rootDiffNode);
|
|
7592
|
+
// Sort by token count descending
|
|
7593
|
+
directoryDiffs.sort((a, b) => b.tokenCount - a.tokenCount);
|
|
7594
|
+
let totalTokenCount = directoryDiffs.reduce((sum, group) => sum + group.tokenCount, 0);
|
|
7595
|
+
logger.stopSpinner('Diffs Organized').stopTimer();
|
|
7596
|
+
logger.startSpinner(`Consolidating Diffs`, { color: 'blue' });
|
|
7597
|
+
const processingTasks = directoryDiffs.map((group, i) => {
|
|
7598
|
+
return queue.add(async () => {
|
|
7599
|
+
// If the diff token count is already less than the average req, we can skip summarizing.
|
|
7600
|
+
const isLessThanAvgTokenReq = group.tokenCount <= maxTokens / directoryDiffs.length;
|
|
7601
|
+
if (totalTokenCount <= maxTokens || isLessThanAvgTokenReq) {
|
|
7602
|
+
return group;
|
|
7603
|
+
}
|
|
7604
|
+
group = await summarizeDirectoryDiff(group, {
|
|
7605
|
+
chain,
|
|
7606
|
+
textSplitter,
|
|
7607
|
+
tokenizer,
|
|
7608
|
+
});
|
|
7609
|
+
// We need to subtract the old token count and add the new one
|
|
7610
|
+
totalTokenCount = totalTokenCount - directoryDiffs[i].tokenCount + group.tokenCount;
|
|
7611
|
+
directoryDiffs[i] = group;
|
|
7612
|
+
logger
|
|
7613
|
+
.verbose(`\n • Summarized diffs in "/${group.path}" `, { color: 'blue' })
|
|
7614
|
+
.verbose(`\nTotal token count: ${totalTokenCount}`, {
|
|
7615
|
+
color: totalTokenCount > maxTokens ? 'yellow' : 'green',
|
|
7616
|
+
});
|
|
7617
|
+
return group;
|
|
7618
|
+
}, { priority: group.tokenCount });
|
|
7619
|
+
});
|
|
7620
|
+
await Promise.all(processingTasks);
|
|
7621
|
+
logger.stopSpinner(`Summarized Diffs`);
|
|
7622
|
+
return directoryDiffs.map(handleOutput).join('');
|
|
7623
|
+
}
|
|
7624
|
+
|
|
7625
|
+
/**
|
|
7626
|
+
* Asynchronously collect diffs for a given node and its children.
|
|
7627
|
+
*/
|
|
7628
|
+
async function collectDiffs(node, getFileDiff, tokenizer, logger) {
|
|
7629
|
+
// Collect diffs for the files of the current node
|
|
7630
|
+
const diffPromises = node.files.map(async (nodeFile) => {
|
|
7631
|
+
const diff = await getFileDiff(nodeFile);
|
|
7632
|
+
const tokenCount = tokenizer(diff);
|
|
7633
|
+
logger.verbose(`Collected diff for ${nodeFile.filePath} (${tokenCount} tokens)`, {
|
|
7634
|
+
color: 'magenta',
|
|
7635
|
+
});
|
|
7636
|
+
return {
|
|
7637
|
+
file: nodeFile.filePath,
|
|
7638
|
+
summary: nodeFile.summary,
|
|
7639
|
+
diff,
|
|
7640
|
+
tokenCount,
|
|
7641
|
+
};
|
|
7642
|
+
});
|
|
7643
|
+
// Collect diffs for the children of the current node
|
|
7644
|
+
const childrenPromises = Array.from(node.children.values()).map(async (child) => collectDiffs(child, getFileDiff, tokenizer, logger));
|
|
7645
|
+
const [diffs, children] = await Promise.all([
|
|
7646
|
+
Promise.all(diffPromises),
|
|
7647
|
+
Promise.all(childrenPromises),
|
|
7648
|
+
]);
|
|
7649
|
+
return {
|
|
7650
|
+
path: node.getPath(),
|
|
7651
|
+
diffs,
|
|
7652
|
+
children,
|
|
7653
|
+
};
|
|
7654
|
+
}
|
|
7655
|
+
|
|
7656
|
+
class DiffTreeNode {
|
|
7657
|
+
constructor(path) {
|
|
7658
|
+
this.path = [];
|
|
7659
|
+
this.files = [];
|
|
7660
|
+
this.children = new Map();
|
|
7661
|
+
if (path)
|
|
7662
|
+
this.path = path;
|
|
7663
|
+
}
|
|
7664
|
+
addFile(file) {
|
|
7665
|
+
this.files.push(file);
|
|
7666
|
+
}
|
|
7667
|
+
addChild(part, node) {
|
|
7668
|
+
this.children.set(part, node);
|
|
7669
|
+
}
|
|
7670
|
+
getChild(part) {
|
|
7671
|
+
return this.children.get(part);
|
|
7672
|
+
}
|
|
7673
|
+
getPath() {
|
|
7674
|
+
return this.path.join('/');
|
|
7675
|
+
}
|
|
7676
|
+
print(indentation = 0) {
|
|
7677
|
+
const indent = ' '.repeat(indentation);
|
|
7678
|
+
let output = `${indent}- Path: ${this.getPath()}\n`;
|
|
7679
|
+
if (this.files.length > 0) {
|
|
7680
|
+
output += `${indent} Files:\n`;
|
|
7681
|
+
for (const file of this.files) {
|
|
7682
|
+
output += `${indent} - ${file.summary}\n`;
|
|
7683
|
+
}
|
|
7684
|
+
}
|
|
7685
|
+
if (this.children.size > 0) {
|
|
7686
|
+
output += `${indent} Children:\n`;
|
|
7687
|
+
for (const [, child] of this.children) {
|
|
7688
|
+
output += child.print(indentation + 4);
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7691
|
+
return output;
|
|
7692
|
+
}
|
|
7693
|
+
}
|
|
7694
|
+
const createDiffTree = (changes) => {
|
|
7695
|
+
const root = new DiffTreeNode();
|
|
7696
|
+
for (const change of changes) {
|
|
7697
|
+
let currentParent = root;
|
|
7698
|
+
const parts = change.filePath.split('/');
|
|
7699
|
+
parts.pop();
|
|
7700
|
+
for (const part of parts) {
|
|
7701
|
+
let childNode = currentParent.getChild(part);
|
|
7702
|
+
if (!childNode) {
|
|
7703
|
+
childNode = new DiffTreeNode([...currentParent.path, part]);
|
|
7704
|
+
currentParent.addChild(part, childNode);
|
|
7705
|
+
}
|
|
7706
|
+
currentParent = childNode;
|
|
7707
|
+
}
|
|
7708
|
+
// Create a NodeFile object and add it to the parent
|
|
7709
|
+
currentParent.addFile({
|
|
7710
|
+
filePath: change.filePath,
|
|
7711
|
+
oldFilePath: change.oldFilePath,
|
|
7712
|
+
summary: change.summary,
|
|
7713
|
+
status: change.status,
|
|
7714
|
+
});
|
|
7715
|
+
}
|
|
7716
|
+
return root;
|
|
7717
|
+
};
|
|
7718
|
+
|
|
7719
|
+
/**
|
|
7720
|
+
* Parses the default file diff for a given nodeFile.
|
|
7721
|
+
*
|
|
7722
|
+
* @param nodeFile - The file change object.
|
|
7723
|
+
* @param commit - The commit to diff against. Defaults to '--staged'.
|
|
7724
|
+
* @param git - The SimpleGit instance.
|
|
7725
|
+
* @returns A Promise that resolves to the file diff as a string.
|
|
7726
|
+
*/
|
|
7727
|
+
async function parseDefaultFileDiff(nodeFile, commit = '--staged', git) {
|
|
7728
|
+
if (commit === '--staged') {
|
|
7729
|
+
return await git.diff(['--staged', nodeFile.filePath]);
|
|
7730
|
+
}
|
|
7731
|
+
else if (commit === '--unstaged') {
|
|
7732
|
+
return await git.diff([nodeFile.filePath]);
|
|
7733
|
+
}
|
|
7734
|
+
else if (commit === '--untracked') {
|
|
7735
|
+
// For untracked files, read the file content directly from the filesystem
|
|
7736
|
+
try {
|
|
7737
|
+
const fileContent = await promises.readFile(nodeFile.filePath, 'utf-8');
|
|
7738
|
+
return fileContent;
|
|
7739
|
+
}
|
|
7740
|
+
catch (error) {
|
|
7741
|
+
throw new Error(`Error reading untracked file: ${error?.message || 'Unknown error'}`);
|
|
7742
|
+
}
|
|
7743
|
+
}
|
|
7744
|
+
return await git.diff([commit, nodeFile.filePath]);
|
|
7745
|
+
}
|
|
7746
|
+
/**
|
|
7747
|
+
* Parses the diff for a renamed file.
|
|
7748
|
+
*
|
|
7749
|
+
* @param nodeFile - The file change object.
|
|
7750
|
+
* @param commit - The commit hash or '--staged'.
|
|
7751
|
+
* @param git - The SimpleGit instance.
|
|
7752
|
+
* @param logger - The logger instance.
|
|
7753
|
+
* @returns A Promise that resolves to the diff string.
|
|
7754
|
+
*/
|
|
7755
|
+
async function parseRenamedFileDiff(nodeFile, commit, git, logger) {
|
|
7756
|
+
let result = '';
|
|
7757
|
+
const oldFilePath = nodeFile?.oldFilePath || nodeFile.filePath;
|
|
7758
|
+
let previousCommitHash = 'HEAD';
|
|
7759
|
+
let newCommitHash = '';
|
|
7760
|
+
if (commit !== '--staged') {
|
|
7761
|
+
try {
|
|
7762
|
+
previousCommitHash = await git.revparse([`${commit}~1`]);
|
|
7763
|
+
}
|
|
7764
|
+
catch (err) {
|
|
7765
|
+
logger.verbose(`Error getting previous commit hash for ${nodeFile.filePath}`, {
|
|
7766
|
+
color: 'red',
|
|
7767
|
+
});
|
|
7768
|
+
}
|
|
7769
|
+
newCommitHash = commit;
|
|
7770
|
+
}
|
|
7771
|
+
try {
|
|
7772
|
+
const [previousContent, newContent] = await Promise.all([
|
|
7773
|
+
git.show([`${previousCommitHash}:${oldFilePath}`]),
|
|
7774
|
+
git.show([`${newCommitHash}:${nodeFile.filePath}`]),
|
|
7775
|
+
]);
|
|
7776
|
+
if (previousContent !== newContent) {
|
|
7777
|
+
result = createTwoFilesPatch(oldFilePath, nodeFile.filePath, previousContent, newContent, '', '', {
|
|
7778
|
+
context: 3,
|
|
7779
|
+
});
|
|
7780
|
+
// remove the first 4 lines of the patch (they contain the old and new file names)
|
|
7781
|
+
result = result.split('\n').slice(4).join('\n');
|
|
7782
|
+
}
|
|
7783
|
+
else {
|
|
7784
|
+
result = 'File contents are unchanged.';
|
|
7785
|
+
}
|
|
7786
|
+
}
|
|
7787
|
+
catch (err) {
|
|
7788
|
+
logger.verbose(`Error comparing file contents for ${nodeFile.filePath}`, { color: 'red' });
|
|
7789
|
+
result = 'Error comparing file contents.';
|
|
7621
7790
|
}
|
|
7791
|
+
return result;
|
|
7792
|
+
}
|
|
7793
|
+
/**
|
|
7794
|
+
* Retrieves the diff for a given file change in a specific commit.
|
|
7795
|
+
* If the file is deleted, it returns a message indicating that the file has been deleted.
|
|
7796
|
+
* If the file is renamed, it parses the renamed file diff and returns it.
|
|
7797
|
+
* Otherwise, it retrieves the default diff from the index and returns it.
|
|
7798
|
+
*
|
|
7799
|
+
* @param nodeFile - The file change object.
|
|
7800
|
+
* @param commit - The commit hash.
|
|
7801
|
+
* @param git - The SimpleGit instance.
|
|
7802
|
+
* @param logger - The logger instance.
|
|
7803
|
+
* @returns A promise that resolves to the diff as a string.
|
|
7804
|
+
*/
|
|
7805
|
+
async function getDiff(nodeFile, commit, { git, logger, }) {
|
|
7806
|
+
if (nodeFile.status === 'deleted') {
|
|
7807
|
+
return 'This file has been deleted.';
|
|
7808
|
+
}
|
|
7809
|
+
if (nodeFile.status === 'renamed' && nodeFile.oldFilePath) {
|
|
7810
|
+
const renamedDiff = await parseRenamedFileDiff(nodeFile, commit, git, logger);
|
|
7811
|
+
return renamedDiff;
|
|
7812
|
+
}
|
|
7813
|
+
// If not deleted or renamed, get the diff from the index
|
|
7814
|
+
const defaultDiff = await parseDefaultFileDiff(nodeFile, commit, git);
|
|
7815
|
+
return defaultDiff;
|
|
7622
7816
|
}
|
|
7623
|
-
|
|
7624
|
-
var llm_chain = /*#__PURE__*/Object.freeze({
|
|
7625
|
-
__proto__: null,
|
|
7626
|
-
LLMChain: LLMChain
|
|
7627
|
-
});
|
|
7628
7817
|
|
|
7629
7818
|
/* eslint-disable spaced-comment */
|
|
7630
7819
|
const API_URL_RAW_PROMPT_TEMPLATE = `You are given the below API Documentation:
|
|
@@ -9374,8 +9563,6 @@ const loadSummarizationChain = (llm, params = { type: "map_reduce" }) => {
|
|
|
9374
9563
|
throw new Error(`Invalid _type: ${params.type}`);
|
|
9375
9564
|
};
|
|
9376
9565
|
|
|
9377
|
-
new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
|
|
9378
|
-
|
|
9379
9566
|
/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */
|
|
9380
9567
|
function isNothing(subject) {
|
|
9381
9568
|
return (typeof subject === 'undefined') || (subject === null);
|
|
@@ -10400,225 +10587,12 @@ for (var i = 0; i < 256; i++) {
|
|
|
10400
10587
|
simpleEscapeMap[i] = simpleEscapeSequence(i);
|
|
10401
10588
|
}
|
|
10402
10589
|
|
|
10403
|
-
/**
|
|
10404
|
-
* Get Summarization Chain
|
|
10405
|
-
* @param model
|
|
10406
|
-
* @param options
|
|
10407
|
-
* @returns
|
|
10408
|
-
*/
|
|
10409
|
-
function getSummarizationChain(model, options = { type: 'map_reduce' }) {
|
|
10410
|
-
return loadSummarizationChain(model, options);
|
|
10411
|
-
}
|
|
10412
|
-
|
|
10413
|
-
/**
|
|
10414
|
-
* Get Recursive Character Text Splitter
|
|
10415
|
-
*
|
|
10416
|
-
* @param options
|
|
10417
|
-
* @returns
|
|
10418
|
-
*/
|
|
10419
|
-
function getTextSplitter(options = {}) {
|
|
10420
|
-
return new RecursiveCharacterTextSplitter(options);
|
|
10421
|
-
}
|
|
10422
|
-
|
|
10423
|
-
/**
|
|
10424
|
-
* Asynchronously collect diffs for a given node and its children.
|
|
10425
|
-
*/
|
|
10426
|
-
async function collectDiffs(node, getFileDiff, tokenizer, logger) {
|
|
10427
|
-
// Collect diffs for the files of the current node
|
|
10428
|
-
const diffPromises = node.files.map(async (nodeFile) => {
|
|
10429
|
-
const diff = await getFileDiff(nodeFile);
|
|
10430
|
-
const tokenCount = tokenizer(diff);
|
|
10431
|
-
logger.verbose(`Collected diff for ${nodeFile.filePath} (${tokenCount} tokens)`, {
|
|
10432
|
-
color: 'magenta',
|
|
10433
|
-
});
|
|
10434
|
-
return {
|
|
10435
|
-
file: nodeFile.filePath,
|
|
10436
|
-
summary: nodeFile.summary,
|
|
10437
|
-
diff,
|
|
10438
|
-
tokenCount,
|
|
10439
|
-
};
|
|
10440
|
-
});
|
|
10441
|
-
// Collect diffs for the children of the current node
|
|
10442
|
-
const childrenPromises = Array.from(node.children.values()).map(async (child) => collectDiffs(child, getFileDiff, tokenizer, logger));
|
|
10443
|
-
const [diffs, children] = await Promise.all([
|
|
10444
|
-
Promise.all(diffPromises),
|
|
10445
|
-
Promise.all(childrenPromises),
|
|
10446
|
-
]);
|
|
10447
|
-
return {
|
|
10448
|
-
path: node.getPath(),
|
|
10449
|
-
diffs,
|
|
10450
|
-
children,
|
|
10451
|
-
};
|
|
10452
|
-
}
|
|
10453
|
-
|
|
10454
|
-
class DiffTreeNode {
|
|
10455
|
-
constructor(path) {
|
|
10456
|
-
this.path = [];
|
|
10457
|
-
this.files = [];
|
|
10458
|
-
this.children = new Map();
|
|
10459
|
-
if (path)
|
|
10460
|
-
this.path = path;
|
|
10461
|
-
}
|
|
10462
|
-
addFile(file) {
|
|
10463
|
-
this.files.push(file);
|
|
10464
|
-
}
|
|
10465
|
-
addChild(part, node) {
|
|
10466
|
-
this.children.set(part, node);
|
|
10467
|
-
}
|
|
10468
|
-
getChild(part) {
|
|
10469
|
-
return this.children.get(part);
|
|
10470
|
-
}
|
|
10471
|
-
getPath() {
|
|
10472
|
-
return this.path.join('/');
|
|
10473
|
-
}
|
|
10474
|
-
print(indentation = 0) {
|
|
10475
|
-
const indent = ' '.repeat(indentation);
|
|
10476
|
-
let output = `${indent}- Path: ${this.getPath()}\n`;
|
|
10477
|
-
if (this.files.length > 0) {
|
|
10478
|
-
output += `${indent} Files:\n`;
|
|
10479
|
-
for (const file of this.files) {
|
|
10480
|
-
output += `${indent} - ${file.summary}\n`;
|
|
10481
|
-
}
|
|
10482
|
-
}
|
|
10483
|
-
if (this.children.size > 0) {
|
|
10484
|
-
output += `${indent} Children:\n`;
|
|
10485
|
-
for (const [, child] of this.children) {
|
|
10486
|
-
output += child.print(indentation + 4);
|
|
10487
|
-
}
|
|
10488
|
-
}
|
|
10489
|
-
return output;
|
|
10490
|
-
}
|
|
10491
|
-
}
|
|
10492
|
-
const createDiffTree = (changes) => {
|
|
10493
|
-
const root = new DiffTreeNode();
|
|
10494
|
-
for (const change of changes) {
|
|
10495
|
-
let currentParent = root;
|
|
10496
|
-
const parts = change.filePath.split('/');
|
|
10497
|
-
parts.pop();
|
|
10498
|
-
for (const part of parts) {
|
|
10499
|
-
let childNode = currentParent.getChild(part);
|
|
10500
|
-
if (!childNode) {
|
|
10501
|
-
childNode = new DiffTreeNode([...currentParent.path, part]);
|
|
10502
|
-
currentParent.addChild(part, childNode);
|
|
10503
|
-
}
|
|
10504
|
-
currentParent = childNode;
|
|
10505
|
-
}
|
|
10506
|
-
// Create a NodeFile object and add it to the parent
|
|
10507
|
-
currentParent.addFile({
|
|
10508
|
-
filePath: change.filePath,
|
|
10509
|
-
oldFilePath: change.oldFilePath,
|
|
10510
|
-
summary: change.summary,
|
|
10511
|
-
status: change.status,
|
|
10512
|
-
});
|
|
10513
|
-
}
|
|
10514
|
-
return root;
|
|
10515
|
-
};
|
|
10516
|
-
|
|
10517
|
-
/**
|
|
10518
|
-
* Parses the default file diff for a given nodeFile.
|
|
10519
|
-
*
|
|
10520
|
-
* @param nodeFile - The file change object.
|
|
10521
|
-
* @param commit - The commit to diff against. Defaults to '--staged'.
|
|
10522
|
-
* @param git - The SimpleGit instance.
|
|
10523
|
-
* @returns A Promise that resolves to the file diff as a string.
|
|
10524
|
-
*/
|
|
10525
|
-
async function parseDefaultFileDiff(nodeFile, commit = '--staged', git) {
|
|
10526
|
-
if (commit === '--staged') {
|
|
10527
|
-
return await git.diff(['--staged', nodeFile.filePath]);
|
|
10528
|
-
}
|
|
10529
|
-
else if (commit === '--unstaged') {
|
|
10530
|
-
return await git.diff([nodeFile.filePath]);
|
|
10531
|
-
}
|
|
10532
|
-
else if (commit === '--untracked') {
|
|
10533
|
-
// For untracked files, read the file content directly from the filesystem
|
|
10534
|
-
try {
|
|
10535
|
-
const fileContent = await promises.readFile(nodeFile.filePath, 'utf-8');
|
|
10536
|
-
return fileContent;
|
|
10537
|
-
}
|
|
10538
|
-
catch (error) {
|
|
10539
|
-
throw new Error(`Error reading untracked file: ${error?.message || 'Unknown error'}`);
|
|
10540
|
-
}
|
|
10541
|
-
}
|
|
10542
|
-
return await git.diff([commit, nodeFile.filePath]);
|
|
10543
|
-
}
|
|
10544
|
-
/**
|
|
10545
|
-
* Parses the diff for a renamed file.
|
|
10546
|
-
*
|
|
10547
|
-
* @param nodeFile - The file change object.
|
|
10548
|
-
* @param commit - The commit hash or '--staged'.
|
|
10549
|
-
* @param git - The SimpleGit instance.
|
|
10550
|
-
* @param logger - The logger instance.
|
|
10551
|
-
* @returns A Promise that resolves to the diff string.
|
|
10552
|
-
*/
|
|
10553
|
-
async function parseRenamedFileDiff(nodeFile, commit, git, logger) {
|
|
10554
|
-
let result = '';
|
|
10555
|
-
const oldFilePath = nodeFile?.oldFilePath || nodeFile.filePath;
|
|
10556
|
-
let previousCommitHash = 'HEAD';
|
|
10557
|
-
let newCommitHash = '';
|
|
10558
|
-
if (commit !== '--staged') {
|
|
10559
|
-
try {
|
|
10560
|
-
previousCommitHash = await git.revparse([`${commit}~1`]);
|
|
10561
|
-
}
|
|
10562
|
-
catch (err) {
|
|
10563
|
-
logger.verbose(`Error getting previous commit hash for ${nodeFile.filePath}`, {
|
|
10564
|
-
color: 'red',
|
|
10565
|
-
});
|
|
10566
|
-
}
|
|
10567
|
-
newCommitHash = commit;
|
|
10568
|
-
}
|
|
10569
|
-
try {
|
|
10570
|
-
const [previousContent, newContent] = await Promise.all([
|
|
10571
|
-
git.show([`${previousCommitHash}:${oldFilePath}`]),
|
|
10572
|
-
git.show([`${newCommitHash}:${nodeFile.filePath}`]),
|
|
10573
|
-
]);
|
|
10574
|
-
if (previousContent !== newContent) {
|
|
10575
|
-
result = createTwoFilesPatch(oldFilePath, nodeFile.filePath, previousContent, newContent, '', '', {
|
|
10576
|
-
context: 3,
|
|
10577
|
-
});
|
|
10578
|
-
// remove the first 4 lines of the patch (they contain the old and new file names)
|
|
10579
|
-
result = result.split('\n').slice(4).join('\n');
|
|
10580
|
-
}
|
|
10581
|
-
else {
|
|
10582
|
-
result = 'File contents are unchanged.';
|
|
10583
|
-
}
|
|
10584
|
-
}
|
|
10585
|
-
catch (err) {
|
|
10586
|
-
logger.verbose(`Error comparing file contents for ${nodeFile.filePath}`, { color: 'red' });
|
|
10587
|
-
result = 'Error comparing file contents.';
|
|
10588
|
-
}
|
|
10589
|
-
return result;
|
|
10590
|
-
}
|
|
10591
|
-
/**
|
|
10592
|
-
* Retrieves the diff for a given file change in a specific commit.
|
|
10593
|
-
* If the file is deleted, it returns a message indicating that the file has been deleted.
|
|
10594
|
-
* If the file is renamed, it parses the renamed file diff and returns it.
|
|
10595
|
-
* Otherwise, it retrieves the default diff from the index and returns it.
|
|
10596
|
-
*
|
|
10597
|
-
* @param nodeFile - The file change object.
|
|
10598
|
-
* @param commit - The commit hash.
|
|
10599
|
-
* @param git - The SimpleGit instance.
|
|
10600
|
-
* @param logger - The logger instance.
|
|
10601
|
-
* @returns A promise that resolves to the diff as a string.
|
|
10602
|
-
*/
|
|
10603
|
-
async function getDiff(nodeFile, commit, { git, logger, }) {
|
|
10604
|
-
if (nodeFile.status === 'deleted') {
|
|
10605
|
-
return 'This file has been deleted.';
|
|
10606
|
-
}
|
|
10607
|
-
if (nodeFile.status === 'renamed' && nodeFile.oldFilePath) {
|
|
10608
|
-
const renamedDiff = await parseRenamedFileDiff(nodeFile, commit, git, logger);
|
|
10609
|
-
return renamedDiff;
|
|
10610
|
-
}
|
|
10611
|
-
// If not deleted or renamed, get the diff from the index
|
|
10612
|
-
const defaultDiff = await parseDefaultFileDiff(nodeFile, commit, git);
|
|
10613
|
-
return defaultDiff;
|
|
10614
|
-
}
|
|
10615
|
-
|
|
10616
10590
|
// Max tokens for GPT-3 is 4096
|
|
10617
10591
|
// const MAX_TOKENS_PER_SUMMARY = 4096
|
|
10618
10592
|
const MAX_TOKENS_PER_SUMMARY = 12288;
|
|
10619
10593
|
async function fileChangeParser({ changes, commit, options: { tokenizer, git, llm: model, logger }, }) {
|
|
10620
|
-
const textSplitter =
|
|
10621
|
-
const summarizationChain =
|
|
10594
|
+
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 10000, chunkOverlap: 250 });
|
|
10595
|
+
const summarizationChain = loadSummarizationChain(model, {
|
|
10622
10596
|
type: 'map_reduce',
|
|
10623
10597
|
combineMapPrompt: SUMMARIZE_PROMPT,
|
|
10624
10598
|
combinePrompt: SUMMARIZE_PROMPT,
|
|
@@ -10889,7 +10863,9 @@ const handler$3 = async (argv, logger) => {
|
|
|
10889
10863
|
const llm = getLlm(provider, model, config);
|
|
10890
10864
|
const INTERACTIVE = argv.interactive || isInteractive(config);
|
|
10891
10865
|
if (INTERACTIVE) {
|
|
10892
|
-
|
|
10866
|
+
if (!config.hideCocoBanner) {
|
|
10867
|
+
logger.log(LOGO);
|
|
10868
|
+
}
|
|
10893
10869
|
}
|
|
10894
10870
|
else {
|
|
10895
10871
|
logger.setConfig({ silent: true });
|
|
@@ -10940,7 +10916,8 @@ const handler$3 = async (argv, logger) => {
|
|
|
10940
10916
|
const schema = useConventional
|
|
10941
10917
|
? ConventionalCommitMessageResponseSchema
|
|
10942
10918
|
: CommitMessageResponseSchema;
|
|
10943
|
-
const
|
|
10919
|
+
const formatInstructions = `You must always return valid JSON fenced by a markdown code block. Do not return any additional text. The JSON object you return should match the following schema:
|
|
10920
|
+
{{ body: string, title: string }}`;
|
|
10944
10921
|
// Use conventional commit prompt if enabled
|
|
10945
10922
|
const promptTemplate = useConventional ? CONVENTIONAL_COMMIT_PROMPT : COMMIT_PROMPT;
|
|
10946
10923
|
const prompt = getPrompt({
|
|
@@ -10948,7 +10925,11 @@ const handler$3 = async (argv, logger) => {
|
|
|
10948
10925
|
variables: promptTemplate.inputVariables,
|
|
10949
10926
|
fallback: promptTemplate,
|
|
10950
10927
|
});
|
|
10951
|
-
|
|
10928
|
+
if (config.service.provider === 'ollama') {
|
|
10929
|
+
logger.log('Note: Ollama models may not strictly adhere to the output format instructions.', {
|
|
10930
|
+
color: 'yellow',
|
|
10931
|
+
});
|
|
10932
|
+
}
|
|
10952
10933
|
// Get additional context if provided
|
|
10953
10934
|
let additional_context = '';
|
|
10954
10935
|
if (argv.additional) {
|
|
@@ -10981,11 +10962,25 @@ const handler$3 = async (argv, logger) => {
|
|
|
10981
10962
|
commit_history: commit_history,
|
|
10982
10963
|
branch_name_context: branchNameContext,
|
|
10983
10964
|
};
|
|
10984
|
-
const
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10965
|
+
const maxAttempts = config.service.provider === 'ollama' && 'maxParsingAttempts' in config.service
|
|
10966
|
+
? config.service.maxParsingAttempts || 3
|
|
10967
|
+
: 3;
|
|
10968
|
+
const commitMsg = await executeChainWithSchema(schema, llm, prompt, variables, {
|
|
10969
|
+
retryOptions: {
|
|
10970
|
+
maxAttempts,
|
|
10971
|
+
onRetry: (attempt, error) => {
|
|
10972
|
+
logger.verbose(`Failed to parse commit message (attempt ${attempt}/${maxAttempts}): ${error.message}`, { color: 'yellow' });
|
|
10973
|
+
}
|
|
10974
|
+
},
|
|
10975
|
+
fallbackParser: (text) => ({
|
|
10976
|
+
title: text.split('\n')[0] || 'Auto-generated commit',
|
|
10977
|
+
body: text.split('\n').slice(1).join('\n') || 'Generated commit message',
|
|
10978
|
+
}),
|
|
10979
|
+
onFallback: () => {
|
|
10980
|
+
logger.verbose('Max retry attempts reached. Falling back to simple text output.', {
|
|
10981
|
+
color: 'red',
|
|
10982
|
+
});
|
|
10983
|
+
},
|
|
10989
10984
|
});
|
|
10990
10985
|
// Construct the full commit message
|
|
10991
10986
|
const appendedText = argv.append ? `\n\n${argv.append}` : '';
|
|
@@ -11203,12 +11198,15 @@ const OPEN_AI_MODELS = [
|
|
|
11203
11198
|
'gpt-3.5-turbo',
|
|
11204
11199
|
];
|
|
11205
11200
|
const ANTHROPIC_MODELS = [
|
|
11201
|
+
'claude-sonnet-4-0',
|
|
11202
|
+
'claude-3-7-sonnet-latest',
|
|
11203
|
+
'claude-3-5-haiku-latest',
|
|
11204
|
+
'claude-3-5-sonnet-latest',
|
|
11205
|
+
'claude-3-5-sonnet-20241022',
|
|
11206
11206
|
'claude-3-5-sonnet-20240620',
|
|
11207
11207
|
'claude-3-opus-20240229',
|
|
11208
11208
|
'claude-3-sonnet-20240229',
|
|
11209
11209
|
'claude-3-haiku-20240307',
|
|
11210
|
-
'claude-2.1',
|
|
11211
|
-
'claude-2.0',
|
|
11212
11210
|
];
|
|
11213
11211
|
|
|
11214
11212
|
const questions = {
|
|
@@ -11500,9 +11498,9 @@ var init = {
|
|
|
11500
11498
|
options: options$2,
|
|
11501
11499
|
};
|
|
11502
11500
|
|
|
11503
|
-
const RecapLlmResponseSchema =
|
|
11504
|
-
title:
|
|
11505
|
-
summary:
|
|
11501
|
+
const RecapLlmResponseSchema = objectType({
|
|
11502
|
+
title: stringType().optional(),
|
|
11503
|
+
summary: stringType().optional(),
|
|
11506
11504
|
});
|
|
11507
11505
|
const command$1 = 'recap';
|
|
11508
11506
|
/**
|
|
@@ -11576,7 +11574,9 @@ const handler$1 = async (argv, logger) => {
|
|
|
11576
11574
|
const llm = getLlm(provider, model, config);
|
|
11577
11575
|
const INTERACTIVE = argv.interactive || isInteractive(config);
|
|
11578
11576
|
if (INTERACTIVE) {
|
|
11579
|
-
|
|
11577
|
+
if (!config.hideCocoBanner) {
|
|
11578
|
+
logger.log(LOGO);
|
|
11579
|
+
}
|
|
11580
11580
|
}
|
|
11581
11581
|
else {
|
|
11582
11582
|
logger.setConfig({ silent: true });
|
|
@@ -11725,26 +11725,26 @@ var recap = {
|
|
|
11725
11725
|
options: options$1,
|
|
11726
11726
|
};
|
|
11727
11727
|
|
|
11728
|
-
const ReviewFeedbackItemSchema =
|
|
11729
|
-
title:
|
|
11730
|
-
summary:
|
|
11731
|
-
severity:
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11728
|
+
const ReviewFeedbackItemSchema = objectType({
|
|
11729
|
+
title: stringType(),
|
|
11730
|
+
summary: stringType(),
|
|
11731
|
+
severity: unionType([
|
|
11732
|
+
literalType(1),
|
|
11733
|
+
literalType(2),
|
|
11734
|
+
literalType(3),
|
|
11735
|
+
literalType(4),
|
|
11736
|
+
literalType(5),
|
|
11737
|
+
literalType(6),
|
|
11738
|
+
literalType(7),
|
|
11739
|
+
literalType(8),
|
|
11740
|
+
literalType(9),
|
|
11741
|
+
literalType(10),
|
|
11742
11742
|
]),
|
|
11743
|
-
category:
|
|
11744
|
-
filePath:
|
|
11743
|
+
category: stringType(),
|
|
11744
|
+
filePath: stringType(),
|
|
11745
11745
|
});
|
|
11746
11746
|
// Array schema for review feedback items
|
|
11747
|
-
const ReviewFeedbackItemArraySchema =
|
|
11747
|
+
const ReviewFeedbackItemArraySchema = arrayType(ReviewFeedbackItemSchema);
|
|
11748
11748
|
const command = 'review';
|
|
11749
11749
|
/**
|
|
11750
11750
|
* Command line options via yargs
|
|
@@ -14014,7 +14014,9 @@ const handler = async (argv, logger) => {
|
|
|
14014
14014
|
const llm = getLlm(provider, model, config);
|
|
14015
14015
|
const INTERACTIVE = isInteractive(config);
|
|
14016
14016
|
if (INTERACTIVE) {
|
|
14017
|
-
|
|
14017
|
+
if (!config.hideCocoBanner) {
|
|
14018
|
+
logger.log(LOGO);
|
|
14019
|
+
}
|
|
14018
14020
|
}
|
|
14019
14021
|
async function factory() {
|
|
14020
14022
|
if (argv.branch) {
|