@apify/input_schema 3.29.2 → 4.0.0-beta.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/index.d.ts +4 -0
- package/index.js +4 -0
- package/index.js.map +1 -0
- package/input_schema.d.ts +43 -0
- package/input_schema.js +340 -0
- package/input_schema.js.map +1 -0
- package/intl.d.ts +4 -0
- package/intl.js +39 -0
- package/intl.js.map +1 -0
- package/package.json +18 -20
- package/types.d.ts +128 -0
- package/types.js +2 -0
- package/types.js.map +1 -0
- package/utilities.d.ts +34 -0
- package/utilities.js +366 -0
- package/utilities.js.map +1 -0
- package/cjs/index.cjs +0 -609
- package/cjs/index.cjs.map +0 -1
- package/cjs/index.d.ts +0 -204
- package/esm/index.d.mts +0 -204
- package/esm/index.mjs +0 -575
- package/esm/index.mjs.map +0 -1
package/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './intl.js';
|
|
2
|
+
export * from './input_schema.js';
|
|
3
|
+
export { StringFieldDefinition, BooleanFieldDefinition, IntegerFieldDefinition, NumberFieldDefinition, ObjectFieldDefinition, ArrayFieldDefinition, ResourceFieldDefinition, ResourceArrayFieldDefinition, MixedFieldDefinition, FieldDefinition, InputSchema, } from './types.js';
|
|
4
|
+
export * from './utilities.js';
|
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAclC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './intl.js';\nexport * from './input_schema.js';\nexport {\n StringFieldDefinition,\n BooleanFieldDefinition,\n IntegerFieldDefinition,\n NumberFieldDefinition,\n ObjectFieldDefinition,\n ArrayFieldDefinition,\n ResourceFieldDefinition,\n ResourceArrayFieldDefinition,\n MixedFieldDefinition,\n FieldDefinition,\n InputSchema,\n} from './types.js';\nexport * from './utilities.js';\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ErrorObject } from 'ajv';
|
|
2
|
+
import type { Ajv } from 'ajv';
|
|
3
|
+
import { inputSchema as schema } from '@apify/json_schemas';
|
|
4
|
+
import type { InputSchema } from './types.js';
|
|
5
|
+
export { schema as inputSchema };
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves a custom error message defined in the schema for a particular schema path.
|
|
8
|
+
* @param rootSchema json schema object
|
|
9
|
+
* @param schemaPath schema path to the failed validation keyword,
|
|
10
|
+
* as provided in an AJV error object, including the keyword at the end, e.g. "#/properties/name/type"
|
|
11
|
+
*/
|
|
12
|
+
export declare function getCustomErrorMessage(rootSchema: Record<string, any>, schemaPath: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* This function parses AJV error and transforms it into a readable string.
|
|
15
|
+
*
|
|
16
|
+
* @param error An error as returned from AJV.
|
|
17
|
+
* @param rootName Usually 'input' or 'schema' based on if we are passing the input or schema.
|
|
18
|
+
* @param properties (Used only when parsing input errors) List of input schema properties.
|
|
19
|
+
* @param input (Used only when parsing input errors) Actual input that is being parsed.
|
|
20
|
+
* @returns {null|{fieldKey: *, message: *}}
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseAjvError(error: ErrorObject, rootName: string, properties?: Record<string, {
|
|
23
|
+
nullable?: boolean;
|
|
24
|
+
editor?: string;
|
|
25
|
+
}>, input?: Record<string, unknown>): {
|
|
26
|
+
fieldKey: string;
|
|
27
|
+
message: string;
|
|
28
|
+
} | null;
|
|
29
|
+
/**
|
|
30
|
+
* Validates that all required fields are present in properties list
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateExistenceOfRequiredFields(inputSchema: InputSchema): void;
|
|
33
|
+
/**
|
|
34
|
+
* This function validates given input schema first just for basic structure then each field one by one,
|
|
35
|
+
* then checks that all required fields are present and finally checks fully against the whole schema.
|
|
36
|
+
*
|
|
37
|
+
* This way we get the most accurate error message for user.
|
|
38
|
+
*
|
|
39
|
+
* @param validator An instance of AJV validator. Important: The JSON Schema that the passed input schema is validated against
|
|
40
|
+
* is using features from JSON Schema 2019 draft, so the AJV instance must support it.
|
|
41
|
+
* @param inputSchema Input schema to validate.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateInputSchema(validator: Ajv, inputSchema: Record<string, unknown>): asserts inputSchema is InputSchema;
|
package/input_schema.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { inputSchema as schema } from '@apify/json_schemas';
|
|
2
|
+
import { m } from './intl.js';
|
|
3
|
+
import { ensureAjvSupportsDraft2019, validateRegexpPattern } from './utilities.js';
|
|
4
|
+
export { schema as inputSchema };
|
|
5
|
+
const { definitions } = schema;
|
|
6
|
+
// Because the definitions contain not only the root properties definitions, but also sub-schema definitions,
|
|
7
|
+
// utility definitions, and component definitions, we need to filter them out and validate only against the appropriate ones.
|
|
8
|
+
// We do this by checking the prefix of the definition title (Utils:, Component:, or Sub-schema:)
|
|
9
|
+
const [fieldDefinitions, subFieldDefinitions] = Object.values(definitions).reduce((acc, definition) => {
|
|
10
|
+
if (definition.title.startsWith('Utils:') || definition.title.startsWith('Component:')) {
|
|
11
|
+
// skip utility and component definitions
|
|
12
|
+
return acc;
|
|
13
|
+
}
|
|
14
|
+
if (definition.title.startsWith('Sub-schema:')) {
|
|
15
|
+
acc[1].push(definition);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
acc[0].push(definition);
|
|
19
|
+
}
|
|
20
|
+
return acc;
|
|
21
|
+
}, [[], []]);
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves a custom error message defined in the schema for a particular schema path.
|
|
24
|
+
* @param rootSchema json schema object
|
|
25
|
+
* @param schemaPath schema path to the failed validation keyword,
|
|
26
|
+
* as provided in an AJV error object, including the keyword at the end, e.g. "#/properties/name/type"
|
|
27
|
+
*/
|
|
28
|
+
export function getCustomErrorMessage(rootSchema, schemaPath) {
|
|
29
|
+
if (!schemaPath)
|
|
30
|
+
return null;
|
|
31
|
+
const pathParts = schemaPath.replace(/^#\//, '').split('/').filter(Boolean);
|
|
32
|
+
// The last part is the keyword
|
|
33
|
+
const keyword = pathParts.pop();
|
|
34
|
+
if (!keyword)
|
|
35
|
+
return null;
|
|
36
|
+
// Navigate through the schema to find the relevant fragment
|
|
37
|
+
let schemaFragment = rootSchema;
|
|
38
|
+
for (const key of pathParts) {
|
|
39
|
+
if (schemaFragment && typeof schemaFragment === 'object') {
|
|
40
|
+
schemaFragment = schemaFragment[key];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (typeof schemaFragment !== 'object') {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const { errorMessage } = schemaFragment;
|
|
50
|
+
if (!errorMessage)
|
|
51
|
+
return null;
|
|
52
|
+
if (typeof errorMessage === 'object' && keyword in errorMessage) {
|
|
53
|
+
return errorMessage[keyword];
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* This function parses AJV error and transforms it into a readable string.
|
|
59
|
+
*
|
|
60
|
+
* @param error An error as returned from AJV.
|
|
61
|
+
* @param rootName Usually 'input' or 'schema' based on if we are passing the input or schema.
|
|
62
|
+
* @param properties (Used only when parsing input errors) List of input schema properties.
|
|
63
|
+
* @param input (Used only when parsing input errors) Actual input that is being parsed.
|
|
64
|
+
* @returns {null|{fieldKey: *, message: *}}
|
|
65
|
+
*/
|
|
66
|
+
export function parseAjvError(error, rootName, properties = {}, input = {}) {
|
|
67
|
+
// There are 3 possible errors comming from validation:
|
|
68
|
+
// - either { keword: 'anything', instancePath: '/someField', message: 'error message that we can use' }
|
|
69
|
+
// - or { keyword: 'additionalProperties', params: { additionalProperty: 'field' }, message: 'must NOT have additional properties' }
|
|
70
|
+
// - or { keyword: 'required', instancePath: '', params.missingProperty: 'someField' }
|
|
71
|
+
let fieldKey;
|
|
72
|
+
let message;
|
|
73
|
+
// remove leading and trailing slashes and replace remaining slashes with dots
|
|
74
|
+
const cleanPropertyName = (name) => {
|
|
75
|
+
return name.replace(/^\/|\/$/g, '').replace(/\//g, '.');
|
|
76
|
+
};
|
|
77
|
+
// First, try to get a custom error message from the schema
|
|
78
|
+
// If found, use it directly and skip further processing
|
|
79
|
+
const customError = getCustomErrorMessage({ properties }, error.schemaPath);
|
|
80
|
+
if (customError) {
|
|
81
|
+
fieldKey = cleanPropertyName(error.instancePath);
|
|
82
|
+
return { fieldKey, message: customError };
|
|
83
|
+
}
|
|
84
|
+
// If error is with keyword type, it means that type of input is incorrect
|
|
85
|
+
// this can mean that provided value is null
|
|
86
|
+
if (error.keyword === 'type') {
|
|
87
|
+
fieldKey = cleanPropertyName(error.instancePath);
|
|
88
|
+
// Check if value is null and field is nullable, if yes, then skip this error
|
|
89
|
+
if (properties[fieldKey] && properties[fieldKey].nullable && input[fieldKey] === null) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });
|
|
93
|
+
}
|
|
94
|
+
else if (error.keyword === 'required') {
|
|
95
|
+
fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.missingProperty}`);
|
|
96
|
+
message = m('inputSchema.validation.required', { rootName, fieldKey });
|
|
97
|
+
}
|
|
98
|
+
else if (error.keyword === 'additionalProperties') {
|
|
99
|
+
fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.additionalProperty}`);
|
|
100
|
+
message = m('inputSchema.validation.additionalProperty', { rootName, fieldKey });
|
|
101
|
+
}
|
|
102
|
+
else if (error.keyword === 'unevaluatedProperties') {
|
|
103
|
+
fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.unevaluatedProperty}`);
|
|
104
|
+
message = m('inputSchema.validation.additionalProperty', { rootName, fieldKey });
|
|
105
|
+
}
|
|
106
|
+
else if (error.keyword === 'enum') {
|
|
107
|
+
fieldKey = cleanPropertyName(error.instancePath);
|
|
108
|
+
const errorMessage = `${error.message}: "${error.params.allowedValues.join('", "')}"`;
|
|
109
|
+
message = m('inputSchema.validation.generic', { rootName, fieldKey, message: errorMessage });
|
|
110
|
+
}
|
|
111
|
+
else if (error.keyword === 'const') {
|
|
112
|
+
fieldKey = cleanPropertyName(error.instancePath);
|
|
113
|
+
message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
fieldKey = cleanPropertyName(error.instancePath);
|
|
117
|
+
message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });
|
|
118
|
+
}
|
|
119
|
+
return { fieldKey, message };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Selects the most relevant error from an AJV errors array.
|
|
123
|
+
* Prefers top-level errors over sub-branch errors from oneOf/anyOf,
|
|
124
|
+
* which tend to show partial/misleading allowed values.
|
|
125
|
+
*/
|
|
126
|
+
function selectBestError(errors) {
|
|
127
|
+
const branchPattern = /\/(oneOf|anyOf)\/\d+\//;
|
|
128
|
+
const nonBranchErrors = errors.filter((e) => !branchPattern.test(e.schemaPath) && e.keyword !== 'oneOf' && e.keyword !== 'anyOf');
|
|
129
|
+
return nonBranchErrors[0] ?? errors[0];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Validates a given object against the schema and throws a human-readable error.
|
|
133
|
+
*/
|
|
134
|
+
const validateAgainstSchemaOrThrow = (validator, obj, inputSchema, rootName) => {
|
|
135
|
+
if (validator.validate(inputSchema, obj))
|
|
136
|
+
return;
|
|
137
|
+
let bestError = selectBestError(validator.errors);
|
|
138
|
+
/*
|
|
139
|
+
When the best AJV error comes from a oneOf/anyOf branch (showing only a subset of valid values),
|
|
140
|
+
and the schema has a broader top-level enum for the same property, and the input value is not in
|
|
141
|
+
that enum at all, the error is enhanced to show all valid values instead of just the branch subset.
|
|
142
|
+
*/
|
|
143
|
+
const branchPattern = /\/(oneOf|anyOf)\/\d+\//;
|
|
144
|
+
if (bestError.keyword === 'enum' && branchPattern.test(bestError.schemaPath)) {
|
|
145
|
+
const propName = bestError.instancePath.replace(/^\//, '');
|
|
146
|
+
if (propName && !propName.includes('/')) {
|
|
147
|
+
const topLevelEnum = inputSchema?.properties?.[propName]?.enum;
|
|
148
|
+
if (Array.isArray(topLevelEnum) && !topLevelEnum.includes(obj[propName])) {
|
|
149
|
+
bestError = { ...bestError, params: { allowedValues: topLevelEnum } };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const errorMessage = parseAjvError(bestError, rootName)?.message;
|
|
154
|
+
throw new Error(`Input schema is not valid (${errorMessage})`);
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* This validates given object only against the basic input schema without checking the particular fields.
|
|
158
|
+
* We override schema.properties.properties not to validate field definitions.
|
|
159
|
+
*/
|
|
160
|
+
function validateBasicStructure(validator, obj) {
|
|
161
|
+
// We need to remove $id from the schema, because AJV cache the schema by id and if we provide
|
|
162
|
+
// different schema instance with the same id, it will throw an error.
|
|
163
|
+
const { $id, ...schemaWithoutId } = schema;
|
|
164
|
+
const schemaWithoutProperties = {
|
|
165
|
+
...schemaWithoutId,
|
|
166
|
+
properties: { ...schema.properties, properties: { type: 'object' } },
|
|
167
|
+
};
|
|
168
|
+
validateAgainstSchemaOrThrow(validator, obj, schemaWithoutProperties, 'schema');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Validates particular field against it's schema.
|
|
172
|
+
* @param validator An instance of AJV validator (must support draft 2019-09).
|
|
173
|
+
* @param fieldSchema Schema of the field to validate.
|
|
174
|
+
* @param fieldKey Key of the field in the input schema.
|
|
175
|
+
* @param isSubField If true, the field is a sub-field of another field, so we need to skip some definitions.
|
|
176
|
+
*/
|
|
177
|
+
function validateFieldAgainstSchemaDefinition(validator, fieldSchema, fieldKey, isSubField = false) {
|
|
178
|
+
const relevantDefinitions = isSubField ? subFieldDefinitions : fieldDefinitions;
|
|
179
|
+
const matchingDefinitions = Object.values(relevantDefinitions) // cast as any, as the code in first branch seems to be invalid
|
|
180
|
+
.filter((definition) => {
|
|
181
|
+
return definition.properties.type.enum
|
|
182
|
+
? // This is a normal case where fieldSchema.type can be only one possible value matching definition.properties.type.enum.0
|
|
183
|
+
definition.properties.type.enum[0] === fieldSchema.type
|
|
184
|
+
: // This is a type "Any" where fieldSchema.type is an array of possible values
|
|
185
|
+
Array.isArray(fieldSchema.type);
|
|
186
|
+
});
|
|
187
|
+
// There is not matching definition.
|
|
188
|
+
if (matchingDefinitions.length === 0) {
|
|
189
|
+
const errorMessage = m('inputSchema.validation.noMatchingDefinition', { fieldKey });
|
|
190
|
+
throw new Error(`Input schema is not valid (${errorMessage})`);
|
|
191
|
+
}
|
|
192
|
+
// We are validating a field schema against one of the definitions, but one definition can reference other definitions.
|
|
193
|
+
// So this basically creates a new JSON Schema with a picked definition at root and puts all definitions from the `schema.json`
|
|
194
|
+
// into the `definitions` property of this final schema.
|
|
195
|
+
const enhanceDefinition = (definition) => {
|
|
196
|
+
return {
|
|
197
|
+
...definition,
|
|
198
|
+
definitions,
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
// If there is only one matching then we are done and simply compare it.
|
|
202
|
+
if (matchingDefinitions.length === 1) {
|
|
203
|
+
validateAgainstSchemaOrThrow(validator, fieldSchema, enhanceDefinition(matchingDefinitions[0]), `schema.properties.${fieldKey}`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
// If there are more matching definitions then we need to get the right one.
|
|
207
|
+
// If the definition contains "enum" property then it's enum type.
|
|
208
|
+
if (fieldSchema.enum) {
|
|
209
|
+
const definition = matchingDefinitions.filter((item) => !!item.properties.enum).pop();
|
|
210
|
+
if (!definition)
|
|
211
|
+
throw new Error('Input schema validation failed to find "enum property" definition');
|
|
212
|
+
validateAgainstSchemaOrThrow(validator, fieldSchema, enhanceDefinition(definition), `schema.properties.${fieldKey}`);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
// If the definition contains "resourceType" property then it's resource type.
|
|
216
|
+
if (fieldSchema.resourceType) {
|
|
217
|
+
const definition = matchingDefinitions.filter((item) => !!item.properties.resourceType).pop();
|
|
218
|
+
if (!definition)
|
|
219
|
+
throw new Error('Input schema validation failed to find "resource property" definition');
|
|
220
|
+
validateAgainstSchemaOrThrow(validator, fieldSchema, enhanceDefinition(definition), `schema.properties.${fieldKey}`);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Otherwise we use the other definition.
|
|
224
|
+
const definition = matchingDefinitions
|
|
225
|
+
.filter((item) => !item.properties.enum && !item.properties.resourceType)
|
|
226
|
+
.pop();
|
|
227
|
+
if (!definition)
|
|
228
|
+
throw new Error('Input schema validation failed to find other than "enum" or "resource" definition');
|
|
229
|
+
validateAgainstSchemaOrThrow(validator, fieldSchema, enhanceDefinition(definition), `schema.properties.${fieldKey}`);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Validates particular field against it's schema and other rules (like regex patterns).
|
|
233
|
+
* @param validator An instance of AJV validator (must support draft 2019-09).
|
|
234
|
+
* @param fieldSchema Schema of the field to validate.
|
|
235
|
+
* @param fieldKey Key of the field in the input schema.
|
|
236
|
+
* @param isSubField If true, the field is a sub-field of another field, so we need to skip some definitions.
|
|
237
|
+
*/
|
|
238
|
+
function validateField(validator, fieldSchema, fieldKey, isSubField = false) {
|
|
239
|
+
// The deprecated patternKey/patternValue properties are no longer supported. They would fail
|
|
240
|
+
// the schema definition validation below anyway, but this check gives a clear error message
|
|
241
|
+
// with a link to migration instructions.
|
|
242
|
+
// TODO: Remove this check (and the deprecatedProperty message) once schemas have had enough
|
|
243
|
+
// time to migrate and the generic "property is not allowed" error is a good enough response.
|
|
244
|
+
for (const property of ['patternKey', 'patternValue']) {
|
|
245
|
+
if (property in fieldSchema) {
|
|
246
|
+
const message = m('inputSchema.validation.deprecatedProperty', { fieldKey, property });
|
|
247
|
+
throw new Error(`Input schema is not valid (${message})`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Validate against schema definition first.
|
|
251
|
+
validateFieldAgainstSchemaDefinition(validator, fieldSchema, fieldKey, isSubField);
|
|
252
|
+
// Validate regex pattern if defined.
|
|
253
|
+
const { pattern } = fieldSchema;
|
|
254
|
+
if (pattern)
|
|
255
|
+
validateRegexpPattern(pattern, `${fieldKey}.pattern`);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Validates all subfields (and their subfields) of a given field schema.
|
|
259
|
+
*/
|
|
260
|
+
function validateSubFields(validator, fieldSchema, fieldKey) {
|
|
261
|
+
Object.entries(fieldSchema.properties).forEach(([subFieldKey, subFieldSchema]) => {
|
|
262
|
+
// The sub-properties has to be validated first, so we got more relevant error messages.
|
|
263
|
+
if (subFieldSchema.type === 'object' && subFieldSchema.properties) {
|
|
264
|
+
// If the field has sub-fields, we need to validate them as well.
|
|
265
|
+
validateSubFields(validator, subFieldSchema, `${fieldKey}.${subFieldKey}`);
|
|
266
|
+
}
|
|
267
|
+
// If the field is an array and has defined schema (items property), we need to validate it differently.
|
|
268
|
+
if (subFieldSchema.type === 'array' && subFieldSchema.items) {
|
|
269
|
+
validateArrayField(validator, subFieldSchema, `${fieldKey}.${subFieldKey}`);
|
|
270
|
+
}
|
|
271
|
+
validateField(validator, subFieldSchema, `${fieldKey}.${subFieldKey}`, true);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function validateArrayField(validator, fieldSchema, fieldKey) {
|
|
275
|
+
const arraySchema = fieldSchema.items;
|
|
276
|
+
if (!arraySchema)
|
|
277
|
+
return;
|
|
278
|
+
// If the array has object items and have sub-schema defined, we need to validate it.
|
|
279
|
+
if (arraySchema.type === 'object' && arraySchema.properties) {
|
|
280
|
+
validateSubFields(validator, arraySchema, `${fieldKey}.items`);
|
|
281
|
+
}
|
|
282
|
+
// If it's an array of arrays we need, we need to validate the inner array schema.
|
|
283
|
+
if (arraySchema.type === 'array' && arraySchema.items) {
|
|
284
|
+
validateArrayField(validator, arraySchema, `${fieldKey}.items`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Validates all properties in the input schema
|
|
289
|
+
*/
|
|
290
|
+
function validateProperties(inputSchema, validator) {
|
|
291
|
+
Object.entries(inputSchema.properties).forEach(([fieldKey, fieldSchema]) => {
|
|
292
|
+
// The sub-properties has to be validated first, so we got more relevant error messages.
|
|
293
|
+
if (fieldSchema.type === 'object' && fieldSchema.properties) {
|
|
294
|
+
// If the field has sub-fields, we need to validate them as well.
|
|
295
|
+
validateSubFields(validator, fieldSchema, fieldKey);
|
|
296
|
+
}
|
|
297
|
+
// If the field is an array and has defined schema (items property), we need to validate it differently.
|
|
298
|
+
if (fieldSchema.type === 'array' && fieldSchema.items) {
|
|
299
|
+
validateArrayField(validator, fieldSchema, fieldKey);
|
|
300
|
+
}
|
|
301
|
+
validateField(validator, fieldSchema, fieldKey);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Validates that all required fields are present in properties list
|
|
306
|
+
*/
|
|
307
|
+
export function validateExistenceOfRequiredFields(inputSchema) {
|
|
308
|
+
// If the input schema does not have any required fields, we do not need to validate them
|
|
309
|
+
if (!inputSchema?.required?.length)
|
|
310
|
+
return;
|
|
311
|
+
Object.values(inputSchema?.required).forEach((fieldKey) => {
|
|
312
|
+
// If the required field is present in the list of properties, we can check the next one
|
|
313
|
+
if (inputSchema?.properties[fieldKey])
|
|
314
|
+
return;
|
|
315
|
+
// The required field is not defined in list of properties. Which means the schema is not valid.
|
|
316
|
+
throw new Error(m('inputSchema.validation.missingRequiredField', { fieldKey }));
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* This function validates given input schema first just for basic structure then each field one by one,
|
|
321
|
+
* then checks that all required fields are present and finally checks fully against the whole schema.
|
|
322
|
+
*
|
|
323
|
+
* This way we get the most accurate error message for user.
|
|
324
|
+
*
|
|
325
|
+
* @param validator An instance of AJV validator. Important: The JSON Schema that the passed input schema is validated against
|
|
326
|
+
* is using features from JSON Schema 2019 draft, so the AJV instance must support it.
|
|
327
|
+
* @param inputSchema Input schema to validate.
|
|
328
|
+
*/
|
|
329
|
+
export function validateInputSchema(validator, inputSchema) {
|
|
330
|
+
ensureAjvSupportsDraft2019(validator);
|
|
331
|
+
// First validate just basic structure without fields.
|
|
332
|
+
validateBasicStructure(validator, inputSchema);
|
|
333
|
+
// Then validate each field separately.
|
|
334
|
+
validateProperties(inputSchema, validator);
|
|
335
|
+
// Next validate if required fields are actually present in the schema
|
|
336
|
+
validateExistenceOfRequiredFields(inputSchema);
|
|
337
|
+
// Finally just to be sure run validation against the whole schema.
|
|
338
|
+
validateAgainstSchemaOrThrow(validator, inputSchema, schema, 'schema');
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=input_schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input_schema.js","sourceRoot":"","sources":["../src/input_schema.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ErrorObject, Schema } from 'ajv';\nimport type { Ajv } from 'ajv';\n\nimport { inputSchema as schema } from '@apify/json_schemas';\n\nimport { m } from './intl.js';\nimport type {\n CommonResourceFieldDefinition,\n FieldDefinition,\n InputSchema,\n InputSchemaBaseChecked,\n StringFieldDefinition,\n} from './types.js';\nimport { ensureAjvSupportsDraft2019, validateRegexpPattern } from './utilities.js';\n\nexport { schema as inputSchema };\n\nconst { definitions } = schema;\n\n// Because the definitions contain not only the root properties definitions, but also sub-schema definitions,\n// utility definitions, and component definitions, we need to filter them out and validate only against the appropriate ones.\n// We do this by checking the prefix of the definition title (Utils:, Component:, or Sub-schema:)\n\nconst [fieldDefinitions, subFieldDefinitions] = Object.values<any>(definitions).reduce<[any[], any[]]>(\n (acc, definition) => {\n if (definition.title.startsWith('Utils:') || definition.title.startsWith('Component:')) {\n // skip utility and component definitions\n return acc;\n }\n\n if (definition.title.startsWith('Sub-schema:')) {\n acc[1].push(definition);\n } else {\n acc[0].push(definition);\n }\n\n return acc;\n },\n [[], []],\n);\n\n/**\n * Retrieves a custom error message defined in the schema for a particular schema path.\n * @param rootSchema json schema object\n * @param schemaPath schema path to the failed validation keyword,\n * as provided in an AJV error object, including the keyword at the end, e.g. \"#/properties/name/type\"\n */\nexport function getCustomErrorMessage(rootSchema: Record<string, any>, schemaPath: string): string | null {\n if (!schemaPath) return null;\n\n const pathParts = schemaPath.replace(/^#\\//, '').split('/').filter(Boolean);\n\n // The last part is the keyword\n const keyword = pathParts.pop();\n if (!keyword) return null;\n\n // Navigate through the schema to find the relevant fragment\n let schemaFragment: Record<string, any> = rootSchema;\n for (const key of pathParts) {\n if (schemaFragment && typeof schemaFragment === 'object') {\n schemaFragment = schemaFragment[key];\n } else {\n return null;\n }\n }\n\n if (typeof schemaFragment !== 'object') {\n return null;\n }\n\n const { errorMessage } = schemaFragment;\n if (!errorMessage) return null;\n\n if (typeof errorMessage === 'object' && keyword in errorMessage) {\n return errorMessage[keyword];\n }\n\n return null;\n}\n\n/**\n * This function parses AJV error and transforms it into a readable string.\n *\n * @param error An error as returned from AJV.\n * @param rootName Usually 'input' or 'schema' based on if we are passing the input or schema.\n * @param properties (Used only when parsing input errors) List of input schema properties.\n * @param input (Used only when parsing input errors) Actual input that is being parsed.\n * @returns {null|{fieldKey: *, message: *}}\n */\nexport function parseAjvError(\n error: ErrorObject,\n rootName: string,\n properties: Record<string, { nullable?: boolean; editor?: string }> = {},\n input: Record<string, unknown> = {},\n): { fieldKey: string; message: string } | null {\n // There are 3 possible errors comming from validation:\n // - either { keword: 'anything', instancePath: '/someField', message: 'error message that we can use' }\n // - or { keyword: 'additionalProperties', params: { additionalProperty: 'field' }, message: 'must NOT have additional properties' }\n // - or { keyword: 'required', instancePath: '', params.missingProperty: 'someField' }\n\n let fieldKey: string;\n let message: string;\n\n // remove leading and trailing slashes and replace remaining slashes with dots\n const cleanPropertyName = (name: string) => {\n return name.replace(/^\\/|\\/$/g, '').replace(/\\//g, '.');\n };\n\n // First, try to get a custom error message from the schema\n // If found, use it directly and skip further processing\n const customError = getCustomErrorMessage({ properties }, error.schemaPath);\n if (customError) {\n fieldKey = cleanPropertyName(error.instancePath);\n return { fieldKey, message: customError };\n }\n\n // If error is with keyword type, it means that type of input is incorrect\n // this can mean that provided value is null\n if (error.keyword === 'type') {\n fieldKey = cleanPropertyName(error.instancePath);\n // Check if value is null and field is nullable, if yes, then skip this error\n if (properties[fieldKey] && properties[fieldKey].nullable && input[fieldKey] === null) {\n return null;\n }\n message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });\n } else if (error.keyword === 'required') {\n fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.missingProperty}`);\n message = m('inputSchema.validation.required', { rootName, fieldKey });\n } else if (error.keyword === 'additionalProperties') {\n fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.additionalProperty}`);\n message = m('inputSchema.validation.additionalProperty', { rootName, fieldKey });\n } else if (error.keyword === 'unevaluatedProperties') {\n fieldKey = cleanPropertyName(`${error.instancePath}/${error.params.unevaluatedProperty}`);\n message = m('inputSchema.validation.additionalProperty', { rootName, fieldKey });\n } else if (error.keyword === 'enum') {\n fieldKey = cleanPropertyName(error.instancePath);\n const errorMessage = `${error.message}: \"${error.params.allowedValues.join('\", \"')}\"`;\n message = m('inputSchema.validation.generic', { rootName, fieldKey, message: errorMessage });\n } else if (error.keyword === 'const') {\n fieldKey = cleanPropertyName(error.instancePath);\n message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });\n } else {\n fieldKey = cleanPropertyName(error.instancePath);\n message = m('inputSchema.validation.generic', { rootName, fieldKey, message: error.message });\n }\n\n return { fieldKey, message };\n}\n\n/**\n * Selects the most relevant error from an AJV errors array.\n * Prefers top-level errors over sub-branch errors from oneOf/anyOf,\n * which tend to show partial/misleading allowed values.\n */\nfunction selectBestError(errors: ErrorObject[]): ErrorObject {\n const branchPattern = /\\/(oneOf|anyOf)\\/\\d+\\//;\n const nonBranchErrors = errors.filter(\n (e) => !branchPattern.test(e.schemaPath) && e.keyword !== 'oneOf' && e.keyword !== 'anyOf',\n );\n return nonBranchErrors[0] ?? errors[0];\n}\n\n/**\n * Validates a given object against the schema and throws a human-readable error.\n */\nconst validateAgainstSchemaOrThrow = (\n validator: Ajv,\n obj: Record<string, unknown>,\n inputSchema: Schema,\n rootName: string,\n) => {\n if (validator.validate(inputSchema, obj)) return;\n\n let bestError = selectBestError(validator.errors!);\n\n /*\n When the best AJV error comes from a oneOf/anyOf branch (showing only a subset of valid values),\n and the schema has a broader top-level enum for the same property, and the input value is not in\n that enum at all, the error is enhanced to show all valid values instead of just the branch subset.\n */\n const branchPattern = /\\/(oneOf|anyOf)\\/\\d+\\//;\n if (bestError.keyword === 'enum' && branchPattern.test(bestError.schemaPath)) {\n const propName = bestError.instancePath.replace(/^\\//, '');\n if (propName && !propName.includes('/')) {\n const topLevelEnum = (inputSchema as Record<string, any>)?.properties?.[propName]?.enum;\n if (Array.isArray(topLevelEnum) && !topLevelEnum.includes(obj[propName])) {\n bestError = { ...bestError, params: { allowedValues: topLevelEnum } };\n }\n }\n }\n\n const errorMessage = parseAjvError(bestError, rootName)?.message;\n throw new Error(`Input schema is not valid (${errorMessage})`);\n};\n\n/**\n * This validates given object only against the basic input schema without checking the particular fields.\n * We override schema.properties.properties not to validate field definitions.\n */\nfunction validateBasicStructure(validator: Ajv, obj: Record<string, unknown>): asserts obj is InputSchemaBaseChecked {\n // We need to remove $id from the schema, because AJV cache the schema by id and if we provide\n // different schema instance with the same id, it will throw an error.\n const { $id, ...schemaWithoutId } = schema;\n const schemaWithoutProperties = {\n ...schemaWithoutId,\n properties: { ...schema.properties, properties: { type: 'object' } as any },\n };\n validateAgainstSchemaOrThrow(validator, obj, schemaWithoutProperties, 'schema');\n}\n\n/**\n * Validates particular field against it's schema.\n * @param validator An instance of AJV validator (must support draft 2019-09).\n * @param fieldSchema Schema of the field to validate.\n * @param fieldKey Key of the field in the input schema.\n * @param isSubField If true, the field is a sub-field of another field, so we need to skip some definitions.\n */\nfunction validateFieldAgainstSchemaDefinition(\n validator: Ajv,\n fieldSchema: Record<string, unknown>,\n fieldKey: string,\n isSubField = false,\n): asserts fieldSchema is FieldDefinition {\n const relevantDefinitions = isSubField ? subFieldDefinitions : fieldDefinitions;\n\n const matchingDefinitions = Object.values<any>(relevantDefinitions) // cast as any, as the code in first branch seems to be invalid\n .filter((definition) => {\n return definition.properties.type.enum\n ? // This is a normal case where fieldSchema.type can be only one possible value matching definition.properties.type.enum.0\n definition.properties.type.enum[0] === fieldSchema.type\n : // This is a type \"Any\" where fieldSchema.type is an array of possible values\n Array.isArray(fieldSchema.type);\n });\n\n // There is not matching definition.\n if (matchingDefinitions.length === 0) {\n const errorMessage = m('inputSchema.validation.noMatchingDefinition', { fieldKey });\n throw new Error(`Input schema is not valid (${errorMessage})`);\n }\n\n // We are validating a field schema against one of the definitions, but one definition can reference other definitions.\n // So this basically creates a new JSON Schema with a picked definition at root and puts all definitions from the `schema.json`\n // into the `definitions` property of this final schema.\n const enhanceDefinition = (definition: object) => {\n return {\n ...definition,\n definitions,\n };\n };\n\n // If there is only one matching then we are done and simply compare it.\n if (matchingDefinitions.length === 1) {\n validateAgainstSchemaOrThrow(\n validator,\n fieldSchema,\n enhanceDefinition(matchingDefinitions[0]),\n `schema.properties.${fieldKey}`,\n );\n return;\n }\n\n // If there are more matching definitions then we need to get the right one.\n // If the definition contains \"enum\" property then it's enum type.\n if ((fieldSchema as StringFieldDefinition).enum) {\n const definition = matchingDefinitions.filter((item) => !!item.properties.enum).pop();\n if (!definition) throw new Error('Input schema validation failed to find \"enum property\" definition');\n validateAgainstSchemaOrThrow(\n validator,\n fieldSchema,\n enhanceDefinition(definition),\n `schema.properties.${fieldKey}`,\n );\n return;\n }\n // If the definition contains \"resourceType\" property then it's resource type.\n if ((fieldSchema as CommonResourceFieldDefinition<unknown>).resourceType) {\n const definition = matchingDefinitions.filter((item) => !!item.properties.resourceType).pop();\n if (!definition) throw new Error('Input schema validation failed to find \"resource property\" definition');\n validateAgainstSchemaOrThrow(\n validator,\n fieldSchema,\n enhanceDefinition(definition),\n `schema.properties.${fieldKey}`,\n );\n return;\n }\n // Otherwise we use the other definition.\n const definition = matchingDefinitions\n .filter((item) => !item.properties.enum && !item.properties.resourceType)\n .pop();\n if (!definition)\n throw new Error('Input schema validation failed to find other than \"enum\" or \"resource\" definition');\n validateAgainstSchemaOrThrow(\n validator,\n fieldSchema,\n enhanceDefinition(definition),\n `schema.properties.${fieldKey}`,\n );\n}\n\n/**\n * Validates particular field against it's schema and other rules (like regex patterns).\n * @param validator An instance of AJV validator (must support draft 2019-09).\n * @param fieldSchema Schema of the field to validate.\n * @param fieldKey Key of the field in the input schema.\n * @param isSubField If true, the field is a sub-field of another field, so we need to skip some definitions.\n */\nfunction validateField(\n validator: Ajv,\n fieldSchema: Record<string, unknown>,\n fieldKey: string,\n isSubField = false,\n): asserts fieldSchema is FieldDefinition {\n // The deprecated patternKey/patternValue properties are no longer supported. They would fail\n // the schema definition validation below anyway, but this check gives a clear error message\n // with a link to migration instructions.\n // TODO: Remove this check (and the deprecatedProperty message) once schemas have had enough\n // time to migrate and the generic \"property is not allowed\" error is a good enough response.\n for (const property of ['patternKey', 'patternValue']) {\n if (property in fieldSchema) {\n const message = m('inputSchema.validation.deprecatedProperty', { fieldKey, property });\n throw new Error(`Input schema is not valid (${message})`);\n }\n }\n\n // Validate against schema definition first.\n validateFieldAgainstSchemaDefinition(validator, fieldSchema, fieldKey, isSubField);\n\n // Validate regex pattern if defined.\n const { pattern } = fieldSchema as Partial<StringFieldDefinition>;\n if (pattern) validateRegexpPattern(pattern, `${fieldKey}.pattern`);\n}\n\n/**\n * Validates all subfields (and their subfields) of a given field schema.\n */\nfunction validateSubFields(validator: Ajv, fieldSchema: InputSchemaBaseChecked, fieldKey: string) {\n Object.entries(fieldSchema.properties).forEach(([subFieldKey, subFieldSchema]) => {\n // The sub-properties has to be validated first, so we got more relevant error messages.\n if (subFieldSchema.type === 'object' && subFieldSchema.properties) {\n // If the field has sub-fields, we need to validate them as well.\n validateSubFields(validator, subFieldSchema as any as InputSchemaBaseChecked, `${fieldKey}.${subFieldKey}`);\n }\n\n // If the field is an array and has defined schema (items property), we need to validate it differently.\n if (subFieldSchema.type === 'array' && subFieldSchema.items) {\n validateArrayField(validator, subFieldSchema, `${fieldKey}.${subFieldKey}`);\n }\n\n validateField(validator, subFieldSchema, `${fieldKey}.${subFieldKey}`, true);\n });\n}\n\nfunction validateArrayField(\n validator: Ajv,\n fieldSchema: { items?: { type: 'string'; properties: Record<string, any> } },\n fieldKey: string,\n) {\n const arraySchema = (fieldSchema as any).items;\n if (!arraySchema) return;\n\n // If the array has object items and have sub-schema defined, we need to validate it.\n if (arraySchema.type === 'object' && arraySchema.properties) {\n validateSubFields(validator, arraySchema as InputSchemaBaseChecked, `${fieldKey}.items`);\n }\n\n // If it's an array of arrays we need, we need to validate the inner array schema.\n if (arraySchema.type === 'array' && arraySchema.items) {\n validateArrayField(validator, arraySchema, `${fieldKey}.items`);\n }\n}\n\n/**\n * Validates all properties in the input schema\n */\nfunction validateProperties(inputSchema: InputSchemaBaseChecked, validator: Ajv): asserts inputSchema is InputSchema {\n Object.entries(inputSchema.properties).forEach(([fieldKey, fieldSchema]) => {\n // The sub-properties has to be validated first, so we got more relevant error messages.\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n // If the field has sub-fields, we need to validate them as well.\n validateSubFields(validator, fieldSchema as any as InputSchemaBaseChecked, fieldKey);\n }\n\n // If the field is an array and has defined schema (items property), we need to validate it differently.\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n validateArrayField(validator, fieldSchema, fieldKey);\n }\n\n validateField(validator, fieldSchema, fieldKey);\n });\n}\n\n/**\n * Validates that all required fields are present in properties list\n */\nexport function validateExistenceOfRequiredFields(inputSchema: InputSchema) {\n // If the input schema does not have any required fields, we do not need to validate them\n if (!inputSchema?.required?.length) return;\n\n Object.values(inputSchema?.required).forEach((fieldKey) => {\n // If the required field is present in the list of properties, we can check the next one\n if (inputSchema?.properties[fieldKey as string]) return;\n\n // The required field is not defined in list of properties. Which means the schema is not valid.\n throw new Error(m('inputSchema.validation.missingRequiredField', { fieldKey }));\n });\n}\n\n/**\n * This function validates given input schema first just for basic structure then each field one by one,\n * then checks that all required fields are present and finally checks fully against the whole schema.\n *\n * This way we get the most accurate error message for user.\n *\n * @param validator An instance of AJV validator. Important: The JSON Schema that the passed input schema is validated against\n * is using features from JSON Schema 2019 draft, so the AJV instance must support it.\n * @param inputSchema Input schema to validate.\n */\nexport function validateInputSchema(\n validator: Ajv,\n inputSchema: Record<string, unknown>,\n): asserts inputSchema is InputSchema {\n ensureAjvSupportsDraft2019(validator);\n\n // First validate just basic structure without fields.\n validateBasicStructure(validator, inputSchema);\n\n // Then validate each field separately.\n validateProperties(inputSchema, validator);\n\n // Next validate if required fields are actually present in the schema\n validateExistenceOfRequiredFields(inputSchema);\n\n // Finally just to be sure run validation against the whole schema.\n validateAgainstSchemaOrThrow(validator, inputSchema, schema, 'schema');\n}\n"]}
|
package/intl.d.ts
ADDED
package/intl.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const intlStrings = {
|
|
2
|
+
'inputSchema.validation.generic': 'Field {rootName}.{fieldKey} {message}',
|
|
3
|
+
'inputSchema.validation.required': 'Field {rootName}.{fieldKey} is required',
|
|
4
|
+
'inputSchema.validation.proxyRequired': 'Field {rootName}.{fieldKey} is required. Please provide custom proxy URLs or use Apify Proxy.',
|
|
5
|
+
'inputSchema.validation.requestListSourcesInvalid': 'Items in {rootName}.{fieldKey} at positions [{invalidIndexes}] do not contain valid URLs',
|
|
6
|
+
'inputSchema.validation.arrayKeysInvalid': 'Keys in {rootName}.{fieldKey} at positions [{invalidIndexes}] must match regular expression "{pattern}"',
|
|
7
|
+
'inputSchema.validation.arrayValuesInvalid': 'Values in {rootName}.{fieldKey} at positions [{invalidIndexes}] must match regular expression "{pattern}"',
|
|
8
|
+
'inputSchema.validation.objectKeysInvalid': 'Keys [{invalidKeys}] in {rootName}.{fieldKey} must match regular expression "{pattern}',
|
|
9
|
+
'inputSchema.validation.objectValuesInvalid': 'Keys [{invalidKeys}] in {rootName}.{fieldKey} must have string value which matches regular expression "{pattern}"',
|
|
10
|
+
'inputSchema.validation.additionalProperty': 'Property {rootName}.{fieldKey} is not allowed.',
|
|
11
|
+
'inputSchema.validation.proxyGroupsNotAvailable': 'You currently do not have access to proxy groups: {groups}',
|
|
12
|
+
'inputSchema.validation.customProxyInvalid': 'Proxy URL "{invalidUrl}" has invalid format, it must be socks[4|4a|5|5h]|http[s]://[username[:password]]@hostname:port.',
|
|
13
|
+
'inputSchema.validation.apifyProxyCountryInvalid': 'Country code "{invalidCountry}" is invalid. Only ISO 3166-1 alpha-2 country codes are supported.',
|
|
14
|
+
'inputSchema.validation.apifyProxyCountryWithoutApifyProxyForbidden': 'The country for Apify Proxy can be specified only when using Apify Proxy.',
|
|
15
|
+
'inputSchema.validation.noAvailableAutoProxy': 'Currently you do not have access to any proxy group usable in automatic mode.',
|
|
16
|
+
'inputSchema.validation.noMatchingDefinition': "Field schema.properties.{fieldKey} is not matching any input schema type definition. Please make sure that it's type is valid.",
|
|
17
|
+
'inputSchema.validation.missingRequiredField': 'Field schema.properties.{fieldKey} does not exist, but it is specified in schema.required. Either define the field or remove it from schema.required.',
|
|
18
|
+
'inputSchema.validation.proxyGroupMustBeArrayOfStrings': 'Field {rootName}.{fieldKey}.apifyProxyGroups must be an array of strings.',
|
|
19
|
+
'inputSchema.validation.secretFieldSchemaChanged': 'The field schema.properties.{fieldKey} is a secret field, but its schema has changed. Please update the value in the input editor.',
|
|
20
|
+
'inputSchema.validation.deprecatedProperty': 'Property schema.properties.{fieldKey}.{property} is deprecated and no longer supported. Please remove it from the input schema. ' +
|
|
21
|
+
'See https://docs.apify.com/platform/actors/development/actor-definition/input-schema/specification/v1#deprecation-of-patternkey-and-patternvalue for migration instructions.',
|
|
22
|
+
'inputSchema.validation.regexpNotValid': 'The regular expression "{pattern}" in field schema.properties.{fieldKey} must be valid.',
|
|
23
|
+
'inputSchema.validation.regexpNotSafe': 'The regular expression "{pattern}" in field schema.properties.{fieldKey} may cause excessive backtracking or be unsafe to execute.',
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Helper function to simulate intl formatMessage function
|
|
27
|
+
*/
|
|
28
|
+
export function m(stringId, variables) {
|
|
29
|
+
let text = intlStrings[stringId];
|
|
30
|
+
if (!text)
|
|
31
|
+
return stringId;
|
|
32
|
+
if (variables) {
|
|
33
|
+
Object.keys(variables).forEach((variableName) => {
|
|
34
|
+
text = text.split(`{${variableName}}`).join(variables[variableName]);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return text;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=intl.js.map
|
package/intl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intl.js","sourceRoot":"","sources":["../src/intl.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAChB,gCAAgC,EAAE,uCAAuC;IACzE,iCAAiC,EAAE,yCAAyC;IAC5E,sCAAsC,EAClC,+FAA+F;IACnG,kDAAkD,EAC9C,0FAA0F;IAC9F,yCAAyC,EACrC,yGAAyG;IAC7G,2CAA2C,EACvC,2GAA2G;IAC/G,0CAA0C,EACtC,wFAAwF;IAC5F,4CAA4C,EACxC,mHAAmH;IACvH,2CAA2C,EAAE,gDAAgD;IAC7F,gDAAgD,EAAE,4DAA4D;IAC9G,2CAA2C,EACvC,yHAAyH;IAC7H,iDAAiD,EAC7C,kGAAkG;IACtG,oEAAoE,EAChE,2EAA2E;IAC/E,6CAA6C,EACzC,+EAA+E;IACnF,6CAA6C,EACzC,gIAAgI;IACpI,6CAA6C,EACzC,uJAAuJ;IAC3J,uDAAuD,EACnD,2EAA2E;IAC/E,iDAAiD,EAC7C,oIAAoI;IACxI,2CAA2C,EACvC,kIAAkI;QAClI,8KAA8K;IAClL,uCAAuC,EACnC,yFAAyF;IAC7F,sCAAsC,EAClC,oIAAoI;CAC3I,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,CAAC,CAAC,QAAgB,EAAE,SAA+B;IAC/D,IAAI,IAAI,GAAG,WAAW,CAAC,QAAoC,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC;IAE3B,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;YAC5C,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["const intlStrings = {\n 'inputSchema.validation.generic': 'Field {rootName}.{fieldKey} {message}',\n 'inputSchema.validation.required': 'Field {rootName}.{fieldKey} is required',\n 'inputSchema.validation.proxyRequired':\n 'Field {rootName}.{fieldKey} is required. Please provide custom proxy URLs or use Apify Proxy.',\n 'inputSchema.validation.requestListSourcesInvalid':\n 'Items in {rootName}.{fieldKey} at positions [{invalidIndexes}] do not contain valid URLs',\n 'inputSchema.validation.arrayKeysInvalid':\n 'Keys in {rootName}.{fieldKey} at positions [{invalidIndexes}] must match regular expression \"{pattern}\"',\n 'inputSchema.validation.arrayValuesInvalid':\n 'Values in {rootName}.{fieldKey} at positions [{invalidIndexes}] must match regular expression \"{pattern}\"',\n 'inputSchema.validation.objectKeysInvalid':\n 'Keys [{invalidKeys}] in {rootName}.{fieldKey} must match regular expression \"{pattern}',\n 'inputSchema.validation.objectValuesInvalid':\n 'Keys [{invalidKeys}] in {rootName}.{fieldKey} must have string value which matches regular expression \"{pattern}\"',\n 'inputSchema.validation.additionalProperty': 'Property {rootName}.{fieldKey} is not allowed.',\n 'inputSchema.validation.proxyGroupsNotAvailable': 'You currently do not have access to proxy groups: {groups}',\n 'inputSchema.validation.customProxyInvalid':\n 'Proxy URL \"{invalidUrl}\" has invalid format, it must be socks[4|4a|5|5h]|http[s]://[username[:password]]@hostname:port.',\n 'inputSchema.validation.apifyProxyCountryInvalid':\n 'Country code \"{invalidCountry}\" is invalid. Only ISO 3166-1 alpha-2 country codes are supported.',\n 'inputSchema.validation.apifyProxyCountryWithoutApifyProxyForbidden':\n 'The country for Apify Proxy can be specified only when using Apify Proxy.',\n 'inputSchema.validation.noAvailableAutoProxy':\n 'Currently you do not have access to any proxy group usable in automatic mode.',\n 'inputSchema.validation.noMatchingDefinition':\n \"Field schema.properties.{fieldKey} is not matching any input schema type definition. Please make sure that it's type is valid.\",\n 'inputSchema.validation.missingRequiredField':\n 'Field schema.properties.{fieldKey} does not exist, but it is specified in schema.required. Either define the field or remove it from schema.required.',\n 'inputSchema.validation.proxyGroupMustBeArrayOfStrings':\n 'Field {rootName}.{fieldKey}.apifyProxyGroups must be an array of strings.',\n 'inputSchema.validation.secretFieldSchemaChanged':\n 'The field schema.properties.{fieldKey} is a secret field, but its schema has changed. Please update the value in the input editor.',\n 'inputSchema.validation.deprecatedProperty':\n 'Property schema.properties.{fieldKey}.{property} is deprecated and no longer supported. Please remove it from the input schema. ' +\n 'See https://docs.apify.com/platform/actors/development/actor-definition/input-schema/specification/v1#deprecation-of-patternkey-and-patternvalue for migration instructions.',\n 'inputSchema.validation.regexpNotValid':\n 'The regular expression \"{pattern}\" in field schema.properties.{fieldKey} must be valid.',\n 'inputSchema.validation.regexpNotSafe':\n 'The regular expression \"{pattern}\" in field schema.properties.{fieldKey} may cause excessive backtracking or be unsafe to execute.',\n};\n\n/**\n * Helper function to simulate intl formatMessage function\n */\nexport function m(stringId: string, variables?: Record<string, any>) {\n let text = intlStrings[stringId as keyof typeof intlStrings];\n if (!text) return stringId;\n\n if (variables) {\n Object.keys(variables).forEach((variableName) => {\n text = text.split(`{${variableName}}`).join(variables[variableName]);\n });\n }\n\n return text;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apify/input_schema",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-beta.0",
|
|
4
4
|
"description": "Tools and constants shared across Apify projects.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"require": {
|
|
15
|
-
"types": "./cjs/index.d.ts",
|
|
16
|
-
"default": "./cjs/index.cjs"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"default": "./index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
19
14
|
},
|
|
20
15
|
"keywords": [
|
|
21
16
|
"apify"
|
|
@@ -40,17 +35,17 @@
|
|
|
40
35
|
"homepage": "https://apify.com",
|
|
41
36
|
"scripts": {
|
|
42
37
|
"build": "pnpm clean && pnpm compile && pnpm copy",
|
|
43
|
-
"clean": "
|
|
44
|
-
"compile": "
|
|
45
|
-
"copy": "
|
|
38
|
+
"clean": "node ../../scripts/clean.ts",
|
|
39
|
+
"compile": "tsc -p tsconfig.build.json",
|
|
40
|
+
"copy": "node ../../scripts/copy.ts"
|
|
46
41
|
},
|
|
47
42
|
"publishConfig": {
|
|
48
43
|
"access": "public"
|
|
49
44
|
},
|
|
50
45
|
"dependencies": {
|
|
51
|
-
"@apify/consts": "^
|
|
52
|
-
"@apify/input_secrets": "^
|
|
53
|
-
"@apify/json_schemas": "^0.
|
|
46
|
+
"@apify/consts": "^3.0.0-beta.2",
|
|
47
|
+
"@apify/input_secrets": "^2.0.0-beta.0",
|
|
48
|
+
"@apify/json_schemas": "^1.0.0-beta.2",
|
|
54
49
|
"acorn-loose": "^8.5.2",
|
|
55
50
|
"countries-list": "^3.4.1"
|
|
56
51
|
},
|
|
@@ -60,6 +55,9 @@
|
|
|
60
55
|
"devDependencies": {
|
|
61
56
|
"@types/safe-regex": "^1.1.6"
|
|
62
57
|
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=22"
|
|
60
|
+
},
|
|
63
61
|
"lerna": {
|
|
64
62
|
"command": {
|
|
65
63
|
"publish": {
|
|
@@ -67,5 +65,5 @@
|
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
},
|
|
70
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "bfcf1b6ac826f248d84cc43c56e81bc09232a97a"
|
|
71
69
|
}
|