-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinputSchema.ts
376 lines (353 loc) · 11.8 KB
/
inputSchema.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
import type { ArrVal } from '../utils/types';
export const FIELD_TYPE = ['string', 'array', 'object', 'boolean', 'integer'] as const;
export type FieldType = ArrVal<typeof FIELD_TYPE>;
export const STRING_EDITOR_TYPE = ['textfield', 'textarea', 'javascript', 'select', 'datepicker', 'hidden'] as const; // prettier-ignore
export type StringEditorType = ArrVal<typeof STRING_EDITOR_TYPE>;
export const BOOLEAN_EDITOR_TYPE = ['checkbox', 'hidden'] as const; // prettier-ignore
export type BooleanEditorType = ArrVal<typeof BOOLEAN_EDITOR_TYPE>;
export const INTEGER_EDITOR_TYPE = ['number', 'hidden'] as const; // prettier-ignore
export type IntegerEditorType = ArrVal<typeof INTEGER_EDITOR_TYPE>;
export const OBJECT_EDITOR_TYPE = ['json', 'proxy', 'hidden'] as const; // prettier-ignore
export type ObjectEditorType = ArrVal<typeof OBJECT_EDITOR_TYPE>;
export const ARRAY_EDITOR_TYPE = ['json', 'requestListSources', 'pseudoUrls', 'globs', 'keyValue', 'stringList', 'hidden'] as const; // prettier-ignore
export type ArrayEditorType = ArrVal<typeof ARRAY_EDITOR_TYPE>;
/** See https://docs.apify.com/platform/actors/development/input-schema */
export interface ActorInputSchema<TProps extends Record<string, Field> = Record<string, Field>> {
/**
* Any text describing your input schema.
*
* Example: `'Cheerio Crawler input'`
*/
title: string;
/**
* Help text for the input that will be displayed above the UI fields.
*/
description?: string;
/** This is fixed and must be set to string object. */
type: 'object';
/**
* The version of the specification against which your schema is written.
* Currently, only version 1 is out.
*/
schemaVersion: 1;
/** This is an object mapping each field key to its specification. */
properties: TProps;
/** An array of field keys that are required. */
required?: (keyof TProps)[];
}
/** See https://docs.apify.com/platform/actors/development/input-schema#fields */
export type Field = StringField | BooleanField | IntegerField | ObjectField | ArrayField;
interface BaseField {
/** Allowed type for the input value. Cannot be mixed. */
type: FieldType;
/** Title of the field in UI. */
title: string;
/** Description of the field that will be displayed as help text in Actor input UI. */
description: string;
/**
* If this property is set, then all fields following this field
* (this field included) will be separated into a collapsible section
* with the value set as its caption. The section ends at the last field
* or the next field which has the sectionCaption property set.
*/
sectionCaption?: string;
/**
* If the sectionCaption property is set, then you can use this property to
* provide additional description to the section. The description will be
* visible right under the caption when the section is open.
*/
sectionDescription?: string;
/** Specifies whether null is an allowed value. */
nullable?: boolean;
}
/** Value of these fields is dependent on the field type */
interface BaseFieldTypedProps<T> {
/** Default value that will be used when no value is provided. */
default?: T;
/**
* Value that will be prefilled in the actor input interface.
* Only the boolean type doesn't support prefill property.
*/
prefill?: T;
/**
* Sample value of this field for the actor to be displayed when
* actor is published in Apify Store.
*/
example?: T;
}
/**
* See https://docs.apify.com/platform/actors/development/input-schema#string
*
* Example of code input:
*
* ```json
* {
* "title": "Page function",
* "type": "string",
* "description": "Function executed for each request",
* "editor": "javascript",
* "prefill": "async () => { return $('title').text(); }",
* }
* ```
*
* Example of country selection using a select input:
*
* ```json
* {
* "title": "Country",
* "type": "string",
* "description": "Select your country",
* "editor": "select",
* "default": "us",
* "enum": ["us", "de", "fr"],
* "enumTitles": ["USA", "Germany", "France"]
* }
* ```
*/
export type StringField<TVal extends string = string, TEnumTitles extends string = string> =
| SelectStringField<TVal, TEnumTitles>
| TextStringField<TVal>
| BaseStringField<TVal>;
interface BaseStringField<TVal extends string = string>
extends BaseField,
BaseFieldTypedProps<TVal> {
type: 'string';
/** Visual editor used for the input field. */
editor: Exclude<StringEditorType, 'select' | 'textarea' | 'textfield'>;
/**
* Regular expression that will be used to validate the input.
* If validation fails, the actor will not run.
*
* NOTE: When using escape characters `\` for the regular expression
* in the pattern field, be sure to escape them to avoid invalid
* JSON issues. For example, the regular expression
*
* `https:\/\/(www\.)?apify\.com\/.+`
*
* would become
*
* `https:\\/\\/(www\\.)?apify\\.com\\/.+`
*/
pattern?: string;
/** Minimum length of the string. */
minLength?: number;
/** Maximum length of the string. */
maxLength?: number;
}
interface SelectStringField<TEnum extends string = string, TEnumTitles extends string = string>
extends Omit<BaseStringField, 'editor' | 'default' | 'prefill' | 'example'>,
BaseFieldTypedProps<TEnum> {
editor: 'select';
/**
* Using this field, you can limit values
* to the given array of strings.
* Input will be displayed as select box.
*/
enum: TEnum[] | readonly TEnum[];
/** Titles for the enum keys described. */
enumTitles?: TEnumTitles[] | readonly TEnumTitles[];
}
interface TextStringField<TVal extends string = string>
extends Omit<BaseStringField<TVal>, 'editor'> {
editor: 'textfield' | 'textarea';
/**
* Specifies whether the input field will be stored encrypted.
* Only available with textfield and textarea editors.
*/
isSecret?: boolean;
}
/**
* See https://docs.apify.com/platform/actors/development/input-schema#boolean
*
* Example options with group caption:
*
* ```json
* {
* "title": "Verbose log",
* "type": "boolean",
* "description": "Debug messages will be included in the log.",
* "default": true,
* "groupCaption": "Options",
* "groupDescription": "Various options for this actor"
* },
* {
* "title": "Lightspeed",
* "type": "boolean",
* "description": "If checked then actors runs at the speed of light.",
* "default": true
* }
* ```
*/
export interface BooleanField<TVal extends boolean = boolean>
extends BaseField,
Omit<BaseFieldTypedProps<TVal>, 'prefill'> {
type: 'boolean';
/** Visual editor used for the input field. */
editor?: BooleanEditorType;
/**
* If you want to group multiple checkboxes together,
* add this option to the first of the group.
*/
groupCaption?: string;
/** Description displayed as help text displayed of group title. */
groupDescription?: string;
}
/**
* See https://docs.apify.com/platform/actors/development/input-schema#integer
*
* Example:
*
* ```json
* {
* "title": "Memory",
* "type": "integer",
* "description": "Select memory in megabytes",
* "default": 64,
* "maximum": 1024,
* "unit": "MB"
* }
* ```
*/
export interface IntegerField<TVal extends number = number, TUnit extends string = string>
extends BaseField,
BaseFieldTypedProps<TVal> {
type: 'integer';
/** Visual editor used for the input field. */
editor?: IntegerEditorType;
/** Maximum allowed value. */
maximum?: number;
/** Minimum allowed value. */
minimum?: number;
/** Unit displayed next to the field in UI, for example second, MB, etc. */
unit?: TUnit;
}
/**
* See https://docs.apify.com/platform/actors/development/input-schema#object
*
* Example of proxy configuration:
*
* ```json
* {
* "title": "Proxy configuration",
* "type": "object",
* "description": "Select proxies to be used by your crawler.",
* "prefill": { "useApifyProxy": true },
* "editor": "proxy"
* }
* ```
*
* Example of a blackbox object:
*
* ```json
* {
* "title": "User object",
* "type": "object",
* "description": "Enter object representing user",
* "prefill": {
* "name": "John Doe",
* "email": "janedoe@gmail.com"
* },
* "editor": "json"
* }
* ```
*/
export interface ObjectField<TVal extends object = object>
extends BaseField,
BaseFieldTypedProps<TVal> {
type: 'object';
/** Visual editor used for the input field. */
editor: ObjectEditorType;
/** Regular expression that will be used to validate the keys of the object. */
patternKey?: string;
/** Regular expression that will be used to validate the values of object. */
patternValue?: string;
/** Maximum number of properties the object can have. */
maxProperties?: number;
/** Minimum number of properties the object can have. */
minProperties?: number;
}
/**
* See https://docs.apify.com/platform/actors/development/input-schema#array
*
* Usage of this field is based on the selected editor:
* - `requestListSources` - value from this field can be used as input of RequestList class from Crawlee.
* - `pseudoUrls` - is intended to be used with a combination of the PseudoUrl class and the enqueueLinks() function from Crawlee.
*
* Example of request list sources configuration:
*
* ```json
* {
* "title": "Start URLs",
* "type": "array",
* "description": "URLs to start with",
* "prefill": [{ "url": "http://example.com" }],
* "editor": "requestListSources"
* }
* ```
*
* Example of an array:
*
* ```json
* {
* "title": "Colors",
* "type": "array",
* "description": "Enter colors you know",
* "prefill": ["Red", "White"],
* "editor": "json"
* }
* ```
*/
export type ArrayField<TVal extends any[] = any[]> =
| BaseArrayField<TVal>
| KeyValueArrayField<TVal>
| StringListArrayField<TVal>;
interface BaseArrayField<TVal extends any[] = any[]> extends BaseField, BaseFieldTypedProps<TVal> {
type: 'array';
/** Visual editor used for the input field. */
editor: Exclude<ArrayEditorType, 'stringList' | 'keyValue'>;
/** Maximum number of items the array can contain. */
maxItems?: number;
/** Minimum number of items the array can contain. */
minItems?: number;
/** Specifies whether the array should contain only unique values. */
uniqueItems?: boolean;
}
interface KeyValueOrStringListArrayFieldProps {
/**
* Placeholder displayed in value field when no value is provided.
* Works only with `keyValue` and `stringList` editors.
*/
placeholderValue?: string;
/**
* Regular expression that will be used to validate the values
* of items in the array. Works only with `keyValue` and `stringList` editors.
*/
patternValue?: string;
}
interface StringListArrayField<TVal extends any[] = any[]>
extends Omit<BaseArrayField<TVal>, 'editor'>,
KeyValueOrStringListArrayFieldProps {
editor: 'stringList';
}
interface KeyValueArrayField<TVal extends any[] = any[]>
extends Omit<BaseArrayField<TVal>, 'editor'>,
KeyValueOrStringListArrayFieldProps {
editor: 'keyValue';
/**
* Placeholder displayed for key field when no value is specified.
* Works only with `keyValue` editor.
*/
placeholderKey?: string;
/**
* Regular expression that will be used to validate
* the keys of items in the array.
* Works only with `keyValue` editor.
*/
patternKey?: string;
}
export const createActorInputSchema = <T extends ActorInputSchema<any>>(config: T) => config;
export const createStringField = <T extends string, TEnumTitles extends string = string>(field: StringField<T, TEnumTitles>) => field; // prettier-ignore
export const createBooleanField = <T extends boolean>(field: BooleanField<T>) => field; // prettier-ignore
export const createIntegerField = <T extends number, TUnit extends string>(field: IntegerField<T, TUnit>) => field; // prettier-ignore
export const createObjectField = <T extends object>(field: ObjectField<T>) => field; // prettier-ignore
export const createArrayField = <T extends any[]>(field: ArrayField<T>) => field; // prettier-ignore