apify-client 3.0.0-beta.2 → 3.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +3 -1
  2. package/dist/apify_api_error.d.ts +60 -19
  3. package/dist/apify_api_error.js +88 -21
  4. package/dist/apify_client.d.ts +22 -3
  5. package/dist/apify_client.js +35 -29
  6. package/dist/base/api_client.d.ts +6 -6
  7. package/dist/base/api_client.js +24 -16
  8. package/dist/base/resource_client.d.ts +23 -9
  9. package/dist/base/resource_client.js +49 -25
  10. package/dist/base/resource_collection_client.d.ts +7 -4
  11. package/dist/base/resource_collection_client.js +21 -15
  12. package/dist/bundle.js +38 -48
  13. package/dist/bundle.js.map +1 -1
  14. package/dist/generated/api.d.ts +287 -214
  15. package/dist/generated/schemas.d.ts +6699 -0
  16. package/dist/generated/schemas.js +1521 -0
  17. package/dist/http_client.d.ts +18 -51
  18. package/dist/http_client.js +79 -42
  19. package/dist/index.d.ts +3 -1
  20. package/dist/index.js +2 -1
  21. package/dist/interceptors.js +22 -4
  22. package/dist/lazy_schema.d.ts +8 -0
  23. package/dist/lazy_schema.js +11 -0
  24. package/dist/models.d.ts +32 -52
  25. package/dist/resource_clients/actor.d.ts +46 -31
  26. package/dist/resource_clients/actor.js +71 -53
  27. package/dist/resource_clients/actor_collection.d.ts +9 -5
  28. package/dist/resource_clients/actor_collection.js +12 -3
  29. package/dist/resource_clients/actor_env_var.d.ts +10 -3
  30. package/dist/resource_clients/actor_env_var.js +17 -6
  31. package/dist/resource_clients/actor_env_var_collection.d.ts +14 -18
  32. package/dist/resource_clients/actor_env_var_collection.js +18 -11
  33. package/dist/resource_clients/actor_version.d.ts +18 -3
  34. package/dist/resource_clients/actor_version.js +20 -9
  35. package/dist/resource_clients/actor_version_collection.d.ts +16 -17
  36. package/dist/resource_clients/actor_version_collection.js +20 -11
  37. package/dist/resource_clients/build.d.ts +18 -6
  38. package/dist/resource_clients/build.js +35 -17
  39. package/dist/resource_clients/build_collection.d.ts +3 -1
  40. package/dist/resource_clients/build_collection.js +5 -1
  41. package/dist/resource_clients/dataset.d.ts +23 -9
  42. package/dist/resource_clients/dataset.js +70 -48
  43. package/dist/resource_clients/dataset_collection.d.ts +6 -2
  44. package/dist/resource_clients/dataset_collection.js +13 -2
  45. package/dist/resource_clients/key_value_store.d.ts +48 -15
  46. package/dist/resource_clients/key_value_store.js +69 -39
  47. package/dist/resource_clients/key_value_store_collection.d.ts +6 -2
  48. package/dist/resource_clients/key_value_store_collection.js +13 -2
  49. package/dist/resource_clients/log.d.ts +9 -19
  50. package/dist/resource_clients/log.js +55 -44
  51. package/dist/resource_clients/request_queue.d.ts +56 -26
  52. package/dist/resource_clients/request_queue.js +178 -113
  53. package/dist/resource_clients/request_queue_collection.d.ts +6 -2
  54. package/dist/resource_clients/request_queue_collection.js +10 -3
  55. package/dist/resource_clients/run.d.ts +51 -17
  56. package/dist/resource_clients/run.js +83 -43
  57. package/dist/resource_clients/run_collection.d.ts +3 -1
  58. package/dist/resource_clients/run_collection.js +5 -1
  59. package/dist/resource_clients/schedule.d.ts +16 -7
  60. package/dist/resource_clients/schedule.js +31 -21
  61. package/dist/resource_clients/schedule_collection.d.ts +6 -2
  62. package/dist/resource_clients/schedule_collection.js +10 -3
  63. package/dist/resource_clients/store_collection.d.ts +3 -1
  64. package/dist/resource_clients/store_collection.js +5 -1
  65. package/dist/resource_clients/task.d.ts +28 -10
  66. package/dist/resource_clients/task.js +67 -44
  67. package/dist/resource_clients/task_collection.d.ts +6 -2
  68. package/dist/resource_clients/task_collection.js +10 -3
  69. package/dist/resource_clients/user.d.ts +17 -8
  70. package/dist/resource_clients/user.js +40 -39
  71. package/dist/resource_clients/webhook.d.ts +14 -5
  72. package/dist/resource_clients/webhook.js +30 -22
  73. package/dist/resource_clients/webhook_collection.d.ts +6 -2
  74. package/dist/resource_clients/webhook_collection.js +10 -3
  75. package/dist/resource_clients/webhook_dispatch.d.ts +4 -1
  76. package/dist/resource_clients/webhook_dispatch.js +8 -2
  77. package/dist/resource_clients/webhook_dispatch_collection.d.ts +3 -1
  78. package/dist/resource_clients/webhook_dispatch_collection.js +5 -1
  79. package/dist/response_validation_error.d.ts +26 -0
  80. package/dist/response_validation_error.js +37 -0
  81. package/dist/schemas.d.ts +15 -0
  82. package/dist/schemas.js +15 -0
  83. package/dist/statistics.d.ts +1 -6
  84. package/dist/statistics.js +2 -2
  85. package/dist/timeouts.d.ts +72 -0
  86. package/dist/timeouts.js +31 -0
  87. package/dist/utils.d.ts +57 -41
  88. package/dist/utils.js +155 -121
  89. package/package.json +36 -35
  90. package/dist/argument_validation_error.d.ts +0 -17
  91. package/dist/argument_validation_error.js +0 -153
@@ -1,4 +1,4 @@
1
- import { toPath, toPathSegment } from '../utils.js';
1
+ import { SCANNED_COUNT, toPath, toPathSegment } from '../utils.js';
2
2
  /** @private */
3
3
  export class ApiClient {
4
4
  id;
@@ -16,7 +16,7 @@ export class ApiClient {
16
16
  constructor(options) {
17
17
  const { baseUrl, publicBaseUrl, apifyClient, httpClient, resourcePath, id, params = {} } = options;
18
18
  this.id = id;
19
- this.safeId = id && this._toSafeId(id);
19
+ this.safeId = id && this.toSafeId(id);
20
20
  this.baseUrl = baseUrl;
21
21
  this.publicBaseUrl = publicBaseUrl;
22
22
  this.resourcePath = resourcePath;
@@ -25,35 +25,35 @@ export class ApiClient {
25
25
  this.httpClient = httpClient;
26
26
  this.params = params;
27
27
  }
28
- _subResourceOptions(moreOptions) {
28
+ subResourceOptions(moreOptions) {
29
29
  const baseOptions = {
30
- baseUrl: this._url(),
30
+ baseUrl: this.buildUrl(),
31
31
  publicBaseUrl: this.publicBaseUrl,
32
32
  apifyClient: this.apifyClient,
33
33
  httpClient: this.httpClient,
34
- params: this._params(),
34
+ params: this.buildParams(),
35
35
  };
36
36
  return { ...baseOptions, ...moreOptions };
37
37
  }
38
- _url(path) {
38
+ buildUrl(path) {
39
39
  return path ? `${this.url}/${toPath(path)}` : this.url;
40
40
  }
41
- _publicUrl(path) {
41
+ buildPublicUrl(path) {
42
42
  const url = this.id
43
43
  ? `${this.publicBaseUrl}/${this.resourcePath}/${toPathSegment(this.safeId)}`
44
44
  : `${this.publicBaseUrl}/${this.resourcePath}`;
45
45
  return path ? `${url}/${toPath(path)}` : url;
46
46
  }
47
- _params(endpointParams) {
47
+ buildParams(endpointParams) {
48
48
  return { ...this.params, ...endpointParams };
49
49
  }
50
- _toSafeId(id) {
50
+ toSafeId(id) {
51
51
  return id.replaceAll('/', '~');
52
52
  }
53
53
  /**
54
54
  * Returns async iterator to iterate through all items and Promise that can be awaited to get first page of results.
55
55
  */
56
- _listPaginatedFromCallback(getPaginatedList, options = {}) {
56
+ listPaginatedFromCallback(getPaginatedList, options = {}) {
57
57
  const minForLimitParam = (a, b) => {
58
58
  // API treats 0 as undefined for limit parameter
59
59
  if (a === 0)
@@ -67,20 +67,27 @@ export class ApiClient {
67
67
  return Math.min(a, b);
68
68
  };
69
69
  // `chunkSize` only sizes this loop's requests; it is not an API parameter, so it must not reach
70
- // `_params()` and the query string.
70
+ // `buildParams()` and the query string. The same goes for `timeoutSecs`, which callers take out before
71
+ // calling this, since it also picks the timeout of every page request.
71
72
  const { chunkSize, ...listOptions } = options;
72
73
  const paginatedListPromise = getPaginatedList({
73
74
  ...listOptions,
74
75
  limit: minForLimitParam(options.limit, chunkSize),
75
76
  });
77
+ // A page can return more or fewer items than the rows it scanned (see `SCANNED_COUNT`). The next offset and
78
+ // the stop condition follow the scanned number alone: advancing by `items.length` would re-scan rows after a
79
+ // filter dropped some and skip rows after `unwind` multiplied them, and stopping at an empty page would end
80
+ // the iteration in front of rows a filter hid.
81
+ const scannedRows = (page) => page[SCANNED_COUNT] ?? page.items.length;
76
82
  async function* asyncGenerator() {
77
83
  let currentPage = await paginatedListPromise;
78
84
  yield* currentPage.items;
79
85
  const offset = options.offset ?? 0;
80
86
  const limit = Math.min(options.limit || currentPage.total, currentPage.total);
81
- let currentOffset = offset + currentPage.items.length;
82
- let remainingItems = Math.min(currentPage.total - offset, limit) - currentPage.items.length;
83
- while (currentPage.items.length > 0 && // Continue only if at least some items were returned in the last page.
87
+ let pageScanned = scannedRows(currentPage);
88
+ let currentOffset = offset + pageScanned;
89
+ let remainingItems = Math.min(currentPage.total - offset, limit) - pageScanned;
90
+ while (pageScanned > 0 && // Continue only if the last page scanned some rows.
84
91
  remainingItems > 0) {
85
92
  const newOptions = {
86
93
  ...listOptions,
@@ -89,8 +96,9 @@ export class ApiClient {
89
96
  };
90
97
  currentPage = await getPaginatedList(newOptions);
91
98
  yield* currentPage.items;
92
- currentOffset += currentPage.items.length;
93
- remainingItems -= currentPage.items.length;
99
+ pageScanned = scannedRows(currentPage);
100
+ currentOffset += pageScanned;
101
+ remainingItems -= pageScanned;
94
102
  }
95
103
  }
96
104
  return Object.defineProperty(paginatedListPromise, Symbol.asyncIterator, {
@@ -1,24 +1,38 @@
1
1
  import type { ACT_JOB_STATUSES } from '@apify/consts';
2
+ import type { z } from 'zod';
3
+ import type { Timeout, TimeoutOptions, TimeoutTier } from '../timeouts.js';
2
4
  import { ApiClient } from './api_client.js';
3
- export declare const SMALL_TIMEOUT_MILLIS: number;
4
- export declare const MEDIUM_TIMEOUT_MILLIS: number;
5
- export declare const DEFAULT_TIMEOUT_MILLIS: number;
6
5
  /**
7
6
  * Resource client.
8
7
  * @private
9
8
  */
10
9
  export declare class ResourceClient extends ApiClient {
11
- protected _get<T, R>(options?: T, timeoutMillis?: number): Promise<R | undefined>;
12
- protected _update<T, R>(newFields: T, timeoutMillis?: number): Promise<R>;
13
- protected _delete(timeoutMillis?: number): Promise<void>;
10
+ /**
11
+ * Picks the timeout of a request that asks the API to hold its response with `waitForFinish`. The request
12
+ * gets the hold the caller asked for plus the round trip its tier allows, so the client does not abort a
13
+ * request while the API is still holding it - which for `start()` and `build()` would retry a call that
14
+ * creates a resource. An explicit per-call `timeoutSecs` is used as given.
15
+ */
16
+ protected timeoutForWaitForFinish(timeoutSecs: Timeout | undefined, tier: TimeoutTier, waitForFinishSecs: number | undefined): Timeout;
17
+ /**
18
+ * A 404 resolves to `undefined` only when the client names its resource by ID. A chained client without one, such
19
+ * as `run.dataset()`, throws it instead (see `catchNotFoundForResourceOrThrow()`).
20
+ */
21
+ protected getResource<T, R>(schema: z.ZodType, options: T, timeoutSecs: Timeout): Promise<R | undefined>;
22
+ protected updateResource<T, R>(schema: z.ZodType, newFields: T, timeoutSecs: Timeout): Promise<R>;
23
+ /**
24
+ * A 404 is swallowed, keeping the DELETE idempotent, only when the client names its resource by ID. A chained client
25
+ * without one throws it instead (see `catchNotFoundForResourceOrThrow()`).
26
+ */
27
+ protected deleteResource(timeoutSecs: Timeout): Promise<void>;
14
28
  /**
15
29
  * This function is used in Build and Run endpoints so it's kept
16
30
  * here to stay DRY.
17
31
  */
18
- protected _waitForFinish<R extends {
32
+ protected waitForJobFinish<R extends {
19
33
  status: (typeof ACT_JOB_STATUSES)[keyof typeof ACT_JOB_STATUSES];
20
- }>(options?: WaitForFinishOptions): Promise<R>;
34
+ }>(schema: z.ZodType, options?: WaitForFinishOptions): Promise<R>;
21
35
  }
22
- export interface WaitForFinishOptions {
36
+ export interface WaitForFinishOptions extends TimeoutOptions {
23
37
  waitSecs?: number;
24
38
  }
@@ -1,5 +1,5 @@
1
1
  import { ACT_JOB_TERMINAL_STATUSES } from '@apify/consts';
2
- import { catchNotFoundOrThrow, parseDateFields, pluckData } from '../utils.js';
2
+ import { catchNotFoundForResourceOrThrow, catchNotFoundOrThrow, parseResponse } from '../utils.js';
3
3
  import { ApiClient } from './api_client.js';
4
4
  /**
5
5
  * We need to supply some number for the API,
@@ -7,59 +7,82 @@ import { ApiClient } from './api_client.js';
7
7
  * 999999 seconds is more than 10 days.
8
8
  */
9
9
  const MAX_WAIT_FOR_FINISH = 999999;
10
- export const SMALL_TIMEOUT_MILLIS = 5 * 1000; // For fast and common actions. Suitable for idempotent actions.
11
- export const MEDIUM_TIMEOUT_MILLIS = 30 * 1000; // For actions that may take longer.
12
- export const DEFAULT_TIMEOUT_MILLIS = 360 * 1000; // 6 minutes
10
+ /** The API holds a `waitForFinish` response for at most a minute, however long the parameter asks for. */
11
+ const MAX_WAIT_FOR_FINISH_HOLD_SECS = 60;
13
12
  /**
14
13
  * Resource client.
15
14
  * @private
16
15
  */
17
16
  export class ResourceClient extends ApiClient {
18
- async _get(options = {}, timeoutMillis) {
17
+ /**
18
+ * Picks the timeout of a request that asks the API to hold its response with `waitForFinish`. The request
19
+ * gets the hold the caller asked for plus the round trip its tier allows, so the client does not abort a
20
+ * request while the API is still holding it - which for `start()` and `build()` would retry a call that
21
+ * creates a resource. An explicit per-call `timeoutSecs` is used as given.
22
+ */
23
+ timeoutForWaitForFinish(timeoutSecs, tier, waitForFinishSecs) {
24
+ if (timeoutSecs !== undefined)
25
+ return timeoutSecs;
26
+ if (waitForFinishSecs === undefined)
27
+ return tier;
28
+ const holdSecs = Math.min(waitForFinishSecs, MAX_WAIT_FOR_FINISH_HOLD_SECS);
29
+ if (holdSecs <= 0)
30
+ return tier;
31
+ return holdSecs + this.httpClient.timeoutMillis[tier] / 1000;
32
+ }
33
+ /**
34
+ * A 404 resolves to `undefined` only when the client names its resource by ID. A chained client without one, such
35
+ * as `run.dataset()`, throws it instead (see `catchNotFoundForResourceOrThrow()`).
36
+ */
37
+ async getResource(schema, options, timeoutSecs) {
19
38
  const requestOpts = {
20
- url: this._url(),
39
+ url: this.buildUrl(),
21
40
  method: 'GET',
22
- params: this._params(options),
23
- timeout: timeoutMillis,
41
+ params: this.buildParams(options),
42
+ timeoutSecs,
24
43
  };
25
44
  try {
26
45
  const response = await this.httpClient.call(requestOpts);
27
- return parseDateFields(pluckData(response.data));
46
+ return parseResponse(response, schema);
28
47
  }
29
48
  catch (err) {
30
- catchNotFoundOrThrow(err);
49
+ catchNotFoundForResourceOrThrow(err, this.id);
31
50
  }
32
51
  return undefined;
33
52
  }
34
- async _update(newFields, timeoutMillis) {
53
+ async updateResource(schema, newFields, timeoutSecs) {
35
54
  const response = await this.httpClient.call({
36
- url: this._url(),
55
+ url: this.buildUrl(),
37
56
  method: 'PUT',
38
- params: this._params(),
57
+ params: this.buildParams(),
39
58
  data: newFields,
40
- timeout: timeoutMillis,
59
+ timeoutSecs,
41
60
  });
42
- return parseDateFields(pluckData(response.data));
61
+ return parseResponse(response, schema);
43
62
  }
44
- async _delete(timeoutMillis) {
63
+ /**
64
+ * A 404 is swallowed, keeping the DELETE idempotent, only when the client names its resource by ID. A chained client
65
+ * without one throws it instead (see `catchNotFoundForResourceOrThrow()`).
66
+ */
67
+ async deleteResource(timeoutSecs) {
45
68
  try {
46
69
  await this.httpClient.call({
47
- url: this._url(),
70
+ url: this.buildUrl(),
48
71
  method: 'DELETE',
49
- params: this._params(),
50
- timeout: timeoutMillis,
72
+ params: this.buildParams(),
73
+ timeoutSecs,
51
74
  });
52
75
  }
53
76
  catch (err) {
54
- catchNotFoundOrThrow(err);
77
+ catchNotFoundForResourceOrThrow(err, this.id);
55
78
  }
56
79
  }
57
80
  /**
58
81
  * This function is used in Build and Run endpoints so it's kept
59
82
  * here to stay DRY.
60
83
  */
61
- async _waitForFinish(options = {}) {
62
- const { waitSecs = MAX_WAIT_FOR_FINISH } = options;
84
+ async waitForJobFinish(schema, options = {}) {
85
+ const { waitSecs = MAX_WAIT_FOR_FINISH, timeoutSecs = 'noTimeout' } = options;
63
86
  const waitMillis = waitSecs * 1000;
64
87
  let job;
65
88
  const startedAt = Date.now();
@@ -75,13 +98,14 @@ export class ResourceClient extends ApiClient {
75
98
  const remainingWaitSeconds = Math.round((waitMillis - millisSinceStart) / 1000);
76
99
  const waitForFinish = Math.max(0, remainingWaitSeconds);
77
100
  const requestOpts = {
78
- url: this._url(),
101
+ url: this.buildUrl(),
79
102
  method: 'GET',
80
- params: this._params({ waitForFinish }),
103
+ params: this.buildParams({ waitForFinish }),
104
+ timeoutSecs,
81
105
  };
82
106
  try {
83
107
  const response = await this.httpClient.call(requestOpts);
84
- job = parseDateFields(pluckData(response.data));
108
+ job = parseResponse(response, schema);
85
109
  }
86
110
  catch (err) {
87
111
  catchNotFoundOrThrow(err);
@@ -1,3 +1,5 @@
1
+ import type { z } from 'zod';
2
+ import type { Timeout, TimeoutOptions } from '../timeouts.js';
1
3
  import type { PaginatedResponse, PaginationOptions } from '../utils.js';
2
4
  import { ApiClient } from './api_client.js';
3
5
  /**
@@ -8,11 +10,12 @@ export declare class ResourceCollectionClient extends ApiClient {
8
10
  /**
9
11
  * @private
10
12
  */
11
- protected _list<T, R>(options?: T): Promise<R>;
13
+ protected listResources<T, R>(schema: z.ZodType, options: T | undefined, timeoutSecs: Timeout): Promise<R>;
12
14
  /**
13
15
  * Returns async iterator to iterate through all items and Promise that can be awaited to get first page of results.
16
+ * `defaultTimeoutSecs` applies to every page request unless `options.timeoutSecs` overrides it.
14
17
  */
15
- protected _listPaginated<T extends PaginationOptions, Data, R extends PaginatedResponse<Data>>(options?: T): AsyncIterable<Data> & Promise<R>;
16
- protected _create<D, R>(resource: D): Promise<R>;
17
- protected _getOrCreate<D, R>(name?: string, resource?: D): Promise<R>;
18
+ protected listResourcesPaginated<T extends PaginationOptions & TimeoutOptions, Data, R extends PaginatedResponse<Data>>(schema: z.ZodType, options: T, defaultTimeoutSecs: Timeout): AsyncIterable<Data> & Promise<R>;
19
+ protected createResource<D, R>(schema: z.ZodType, resource: D, timeoutSecs: Timeout): Promise<R>;
20
+ protected getOrCreateResource<D, R>(schema: z.ZodType, name: string | undefined, resource: D | undefined, timeoutSecs: Timeout): Promise<R>;
18
21
  }
@@ -1,4 +1,4 @@
1
- import { parseDateFields, pluckData } from '../utils.js';
1
+ import { parseResponse } from '../utils.js';
2
2
  import { ApiClient } from './api_client.js';
3
3
  /**
4
4
  * Resource collection client.
@@ -8,36 +8,42 @@ export class ResourceCollectionClient extends ApiClient {
8
8
  /**
9
9
  * @private
10
10
  */
11
- async _list(options = {}) {
11
+ async listResources(schema, options, timeoutSecs) {
12
12
  const response = await this.httpClient.call({
13
- url: this._url(),
13
+ url: this.buildUrl(),
14
14
  method: 'GET',
15
- params: this._params(options),
15
+ params: this.buildParams(options),
16
+ timeoutSecs,
16
17
  });
17
- return parseDateFields(pluckData(response.data));
18
+ return parseResponse(response, schema);
18
19
  }
19
20
  /**
20
21
  * Returns async iterator to iterate through all items and Promise that can be awaited to get first page of results.
22
+ * `defaultTimeoutSecs` applies to every page request unless `options.timeoutSecs` overrides it.
21
23
  */
22
- _listPaginated(options = {}) {
23
- return this._listPaginatedFromCallback((this._list.bind(this)), options);
24
+ listResourcesPaginated(schema, options, defaultTimeoutSecs) {
25
+ // `timeoutSecs` only times the page requests; it is not an API parameter, so it must not reach the query string.
26
+ const { timeoutSecs = defaultTimeoutSecs, ...listOptions } = options;
27
+ return this.listPaginatedFromCallback(async (pageOptions) => this.listResources(schema, pageOptions, timeoutSecs), listOptions);
24
28
  }
25
- async _create(resource) {
29
+ async createResource(schema, resource, timeoutSecs) {
26
30
  const response = await this.httpClient.call({
27
- url: this._url(),
31
+ url: this.buildUrl(),
28
32
  method: 'POST',
29
- params: this._params(),
33
+ params: this.buildParams(),
30
34
  data: resource,
35
+ timeoutSecs,
31
36
  });
32
- return parseDateFields(pluckData(response.data));
37
+ return parseResponse(response, schema);
33
38
  }
34
- async _getOrCreate(name, resource) {
39
+ async getOrCreateResource(schema, name, resource, timeoutSecs) {
35
40
  const response = await this.httpClient.call({
36
- url: this._url(),
41
+ url: this.buildUrl(),
37
42
  method: 'POST',
38
- params: this._params({ name }),
43
+ params: this.buildParams({ name }),
39
44
  data: resource,
45
+ timeoutSecs,
40
46
  });
41
- return parseDateFields(pluckData(response.data));
47
+ return parseResponse(response, schema);
42
48
  }
43
49
  }