apify 4.0.0-beta.19 → 4.0.0-beta.21
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/actor.d.ts +29 -6
- package/dist/actor.js +46 -47
- package/dist/apify_dataset_backend.d.ts +18 -0
- package/dist/apify_dataset_backend.js +33 -0
- package/dist/apify_key_value_store_backend.d.ts +23 -0
- package/dist/apify_key_value_store_backend.js +54 -0
- package/dist/apify_request_queue_backend.d.ts +78 -0
- package/dist/apify_request_queue_backend.js +114 -0
- package/dist/apify_request_queue_shared_backend.d.ts +44 -0
- package/dist/apify_request_queue_shared_backend.js +211 -0
- package/dist/apify_request_queue_single_backend.d.ts +52 -0
- package/dist/apify_request_queue_single_backend.js +256 -0
- package/dist/apify_storage_backend.d.ts +109 -0
- package/dist/apify_storage_backend.js +249 -0
- package/dist/configuration.d.ts +6 -4
- package/dist/configuration.js +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -3
- package/dist/input-schemas.d.ts +1 -1
- package/dist/platform_event_manager.d.ts +2 -2
- package/dist/platform_event_manager.js +5 -5
- package/dist/proxy_configuration.d.ts +8 -2
- package/dist/proxy_configuration.js +21 -10
- package/dist/storage.d.ts +3 -3
- package/dist/storage.js +4 -4
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +11 -0
- package/package.json +6 -6
- package/dist/apify_storage_client.d.ts +0 -66
- package/dist/apify_storage_client.js +0 -200
- package/dist/key_value_store.d.ts +0 -21
- package/dist/key_value_store.js +0 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apify",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.21",
|
|
4
4
|
"description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -54,13 +54,14 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@apify/consts": "^2.51.0",
|
|
57
|
+
"@apify/datastructures": "^2.0.3",
|
|
57
58
|
"@apify/input_secrets": "^1.2.0",
|
|
58
59
|
"@apify/log": "^2.4.3",
|
|
59
60
|
"@apify/timeout": "^0.3.0",
|
|
60
61
|
"@apify/utilities": "^2.13.0",
|
|
61
|
-
"@crawlee/core": "^4.0.0-beta.
|
|
62
|
-
"@crawlee/types": "^4.0.0-beta.
|
|
63
|
-
"@crawlee/utils": "^4.0.0-beta.
|
|
62
|
+
"@crawlee/core": "^4.0.0-beta.105",
|
|
63
|
+
"@crawlee/types": "^4.0.0-beta.105",
|
|
64
|
+
"@crawlee/utils": "^4.0.0-beta.105",
|
|
64
65
|
"apify-client": "^2.23.4",
|
|
65
66
|
"semver": "^7.5.4",
|
|
66
67
|
"tslib": "^2.6.2",
|
|
@@ -71,7 +72,6 @@
|
|
|
71
72
|
"@apify/oxlint-config": "^0.2.5",
|
|
72
73
|
"@apify/tsconfig": "^0.1.2",
|
|
73
74
|
"@commitlint/config-conventional": "^21.0.0",
|
|
74
|
-
"@crawlee/memory-storage": "^4.0.0-beta.61",
|
|
75
75
|
"@playwright/browser-chromium": "^1.60.0",
|
|
76
76
|
"@types/content-type": "^1.1.8",
|
|
77
77
|
"@types/node": "^24.0.0",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"@types/tough-cookie": "^4.0.5",
|
|
80
80
|
"@types/ws": "^8.5.12",
|
|
81
81
|
"commitlint": "^21.0.0",
|
|
82
|
-
"crawlee": "^4.0.0-beta.
|
|
82
|
+
"crawlee": "^4.0.0-beta.105",
|
|
83
83
|
"globby": "^16.0.0",
|
|
84
84
|
"husky": "^9.1.7",
|
|
85
85
|
"lint-staged": "^17.0.0",
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import type { CreateDatasetClientOptions, CreateKeyValueStoreClientOptions, CreateRequestQueueClientOptions, DatasetClient, KeyValueStoreClient, RequestQueueClient, StorageClient } from '@crawlee/types';
|
|
3
|
-
import type { ApifyClient } from 'apify-client';
|
|
4
|
-
import { type ChargeResult, type ChargingManager } from './charging.js';
|
|
5
|
-
import type { Configuration } from './configuration.js';
|
|
6
|
-
type StorageType = 'Dataset' | 'KeyValueStore' | 'RequestQueue';
|
|
7
|
-
/** Marks a dataset client whose `pushItems` charges for pay-per-event. @internal */
|
|
8
|
-
export declare const USES_PUSH_DATA_INTERCEPTION: unique symbol;
|
|
9
|
-
/**
|
|
10
|
-
* Context of a single `Actor.pushData()` call, shared with the intercepted
|
|
11
|
-
* `pushItems()` calls so they can (1) know which event to charge and
|
|
12
|
-
* (2) aggregate the {@link ChargeResult} across the multiple `pushItems()`
|
|
13
|
-
* calls a single `pushData()` may trigger (Crawlee batches large pushes).
|
|
14
|
-
*/
|
|
15
|
-
export interface PpeAwarePushDataContext {
|
|
16
|
-
eventName: string | undefined;
|
|
17
|
-
chargeResult?: ChargeResult;
|
|
18
|
-
}
|
|
19
|
-
export declare const pushDataChargingContext: AsyncLocalStorage<PpeAwarePushDataContext>;
|
|
20
|
-
/**
|
|
21
|
-
* Bridges `apify-client`'s synchronous resource accessors (`dataset(id)`,
|
|
22
|
-
* `keyValueStore(id)`, `requestQueue(id, options?)`) to crawlee v4's
|
|
23
|
-
* `StorageClient` interface (async factory methods accepting either an `id`
|
|
24
|
-
* or a `name`).
|
|
25
|
-
*
|
|
26
|
-
* For the run's default dataset it transparently swaps in a charging-aware
|
|
27
|
-
* dataset client (pay-per-event on `Actor.pushData()`), provided a charging
|
|
28
|
-
* manager is supplied and a default-dataset-item price is configured.
|
|
29
|
-
*
|
|
30
|
-
* `storageExists()` lets `Dataset.open(idOrName)` resolve a string to an id
|
|
31
|
-
* first (when one exists on the platform) and fall back to a name otherwise —
|
|
32
|
-
* otherwise crawlee's `resolveStorageIdentifier` treats every string as a name
|
|
33
|
-
* and the SDK would silently create a new storage named like the passed id.
|
|
34
|
-
*
|
|
35
|
-
* `Actor` wires this up automatically; construct it directly only to use Apify
|
|
36
|
-
* platform storage with crawlee's storage classes outside of `Actor` — e.g. to
|
|
37
|
-
* read another run's output with an explicit token:
|
|
38
|
-
*
|
|
39
|
-
* ```ts
|
|
40
|
-
* import { ApifyClient, ApifyStorageClient, Dataset } from 'apify';
|
|
41
|
-
*
|
|
42
|
-
* const client = new ApifyClient({ token });
|
|
43
|
-
* const dataset = await Dataset.open(datasetId, { storageClient: new ApifyStorageClient(client) });
|
|
44
|
-
* const { items } = await dataset.getData();
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export declare class ApifyStorageClient implements StorageClient {
|
|
48
|
-
private readonly client;
|
|
49
|
-
private readonly config?;
|
|
50
|
-
private readonly getChargingManager?;
|
|
51
|
-
constructor(client: ApifyClient, config?: Configuration | undefined, getChargingManager?: (() => ChargingManager) | undefined);
|
|
52
|
-
storageExists(id: string, type: StorageType): Promise<boolean>;
|
|
53
|
-
createDatasetClient(options?: CreateDatasetClientOptions): Promise<DatasetClient>;
|
|
54
|
-
createKeyValueStoreClient(options?: CreateKeyValueStoreClientOptions): Promise<KeyValueStoreClient>;
|
|
55
|
-
createRequestQueueClient(options?: CreateRequestQueueClientOptions): Promise<RequestQueueClient>;
|
|
56
|
-
/**
|
|
57
|
-
* Returns a charging-aware dataset client when `id` is the run's default
|
|
58
|
-
* dataset and a default-dataset-item price is configured; otherwise
|
|
59
|
-
* `undefined` (caller uses the plain client).
|
|
60
|
-
*/
|
|
61
|
-
private chargingDatasetClient;
|
|
62
|
-
private resolveId;
|
|
63
|
-
private resourceClient;
|
|
64
|
-
private collectionClient;
|
|
65
|
-
}
|
|
66
|
-
export {};
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-classes-per-file */
|
|
2
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
-
import { DatasetClient as ApifyDatasetClient } from 'apify-client';
|
|
4
|
-
import { DEFAULT_DATASET_ITEM_EVENT, mergeChargeResults, pushDataAndCharge, } from './charging.js';
|
|
5
|
-
const DEFAULT_ID_CONFIG_KEY = {
|
|
6
|
-
Dataset: 'defaultDatasetId',
|
|
7
|
-
KeyValueStore: 'defaultKeyValueStoreId',
|
|
8
|
-
RequestQueue: 'defaultRequestQueueId',
|
|
9
|
-
};
|
|
10
|
-
/** Marks a dataset client whose `pushItems` charges for pay-per-event. @internal */
|
|
11
|
-
export const USES_PUSH_DATA_INTERCEPTION = Symbol('apify:uses-push-data-interception');
|
|
12
|
-
export const pushDataChargingContext = new AsyncLocalStorage();
|
|
13
|
-
/**
|
|
14
|
-
* Default `DatasetClient` that charges for pushed items (pay-per-event). Used
|
|
15
|
-
* only for the run's default dataset when a `apify-default-dataset-item` price
|
|
16
|
-
* is configured; for everything else the plain `apify-client` dataset client is
|
|
17
|
-
* used.
|
|
18
|
-
*/
|
|
19
|
-
class PpeAwareDatasetClient extends ApifyDatasetClient {
|
|
20
|
-
getChargingManager;
|
|
21
|
-
constructor(options, getChargingManager) {
|
|
22
|
-
super(options);
|
|
23
|
-
this.getChargingManager = getChargingManager;
|
|
24
|
-
}
|
|
25
|
-
normalizeItems(items) {
|
|
26
|
-
if (typeof items === 'string') {
|
|
27
|
-
const parsed = JSON.parse(items);
|
|
28
|
-
return Array.isArray(parsed) ? parsed : [parsed];
|
|
29
|
-
}
|
|
30
|
-
if (Array.isArray(items)) {
|
|
31
|
-
return items.flatMap((item) => typeof item === 'string' ? JSON.parse(item) : item);
|
|
32
|
-
}
|
|
33
|
-
return [items];
|
|
34
|
-
}
|
|
35
|
-
async pushItems(items) {
|
|
36
|
-
const context = pushDataChargingContext.getStore();
|
|
37
|
-
// A single JSON string may encode multiple items (e.g. '[{...},{...}]'),
|
|
38
|
-
// which the charging logic would miscount — parse strings into arrays so
|
|
39
|
-
// each logical item is counted individually.
|
|
40
|
-
const normalizedItems = this.normalizeItems(items);
|
|
41
|
-
const result = await pushDataAndCharge({
|
|
42
|
-
chargingManager: this.getChargingManager(),
|
|
43
|
-
items: normalizedItems,
|
|
44
|
-
eventName: context?.eventName,
|
|
45
|
-
isDefaultDataset: true,
|
|
46
|
-
// stringify for faster validation in the Apify client
|
|
47
|
-
pushFn: async (limitedItems) => super.pushItems(JSON.stringify(limitedItems)),
|
|
48
|
-
});
|
|
49
|
-
if (!context)
|
|
50
|
-
return;
|
|
51
|
-
// One `Actor.pushData()` may map to several `pushItems()` calls — aggregate.
|
|
52
|
-
context.chargeResult =
|
|
53
|
-
context.chargeResult === undefined ? result : mergeChargeResults(context.chargeResult, result);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// crawlee v4's `StorageClient` sub-client interfaces use different method names
|
|
57
|
-
// than `apify-client`'s resource clients (`getValue`/`getRecord`,
|
|
58
|
-
// `pushData`/`pushItems`, `getData`/`listItems`, `getMetadata`/`get`,
|
|
59
|
-
// `drop`/`delete`). `adapt` wraps a client in a name-remapping proxy: `renames`
|
|
60
|
-
// aliases the differing methods and `overrides` replaces the few whose return
|
|
61
|
-
// shape differs; everything else — identically-named methods and the
|
|
62
|
-
// pay-per-event marker symbol — passes straight through.
|
|
63
|
-
//
|
|
64
|
-
// `purge()` has no apify-client equivalent and isn't needed on the platform
|
|
65
|
-
// (a run's storages are already fresh), so it's a no-op.
|
|
66
|
-
const noPurge = { purge: async () => { } };
|
|
67
|
-
function adapt(client, renames, overrides = {}) {
|
|
68
|
-
return new Proxy(client, {
|
|
69
|
-
get(target, prop) {
|
|
70
|
-
if (typeof prop === 'string' && prop in overrides)
|
|
71
|
-
return overrides[prop];
|
|
72
|
-
const value = Reflect.get(target, (typeof prop === 'string' && renames[prop]) || prop, target);
|
|
73
|
-
return typeof value === 'function' ? value.bind(target) : value;
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Bridges `apify-client`'s synchronous resource accessors (`dataset(id)`,
|
|
79
|
-
* `keyValueStore(id)`, `requestQueue(id, options?)`) to crawlee v4's
|
|
80
|
-
* `StorageClient` interface (async factory methods accepting either an `id`
|
|
81
|
-
* or a `name`).
|
|
82
|
-
*
|
|
83
|
-
* For the run's default dataset it transparently swaps in a charging-aware
|
|
84
|
-
* dataset client (pay-per-event on `Actor.pushData()`), provided a charging
|
|
85
|
-
* manager is supplied and a default-dataset-item price is configured.
|
|
86
|
-
*
|
|
87
|
-
* `storageExists()` lets `Dataset.open(idOrName)` resolve a string to an id
|
|
88
|
-
* first (when one exists on the platform) and fall back to a name otherwise —
|
|
89
|
-
* otherwise crawlee's `resolveStorageIdentifier` treats every string as a name
|
|
90
|
-
* and the SDK would silently create a new storage named like the passed id.
|
|
91
|
-
*
|
|
92
|
-
* `Actor` wires this up automatically; construct it directly only to use Apify
|
|
93
|
-
* platform storage with crawlee's storage classes outside of `Actor` — e.g. to
|
|
94
|
-
* read another run's output with an explicit token:
|
|
95
|
-
*
|
|
96
|
-
* ```ts
|
|
97
|
-
* import { ApifyClient, ApifyStorageClient, Dataset } from 'apify';
|
|
98
|
-
*
|
|
99
|
-
* const client = new ApifyClient({ token });
|
|
100
|
-
* const dataset = await Dataset.open(datasetId, { storageClient: new ApifyStorageClient(client) });
|
|
101
|
-
* const { items } = await dataset.getData();
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export class ApifyStorageClient {
|
|
105
|
-
client;
|
|
106
|
-
config;
|
|
107
|
-
getChargingManager;
|
|
108
|
-
constructor(client, config, getChargingManager) {
|
|
109
|
-
this.client = client;
|
|
110
|
-
this.config = config;
|
|
111
|
-
this.getChargingManager = getChargingManager;
|
|
112
|
-
}
|
|
113
|
-
async storageExists(id, type) {
|
|
114
|
-
// Apify's `GET /v2/{kind}/{idOrName}` matches by either id or name;
|
|
115
|
-
// confirm it was an *id* match so crawlee can fall through to `{ name }`.
|
|
116
|
-
const info = await this.resourceClient(id, type).get();
|
|
117
|
-
return info?.id === id;
|
|
118
|
-
}
|
|
119
|
-
async createDatasetClient(options) {
|
|
120
|
-
const id = await this.resolveId(options, 'Dataset');
|
|
121
|
-
const client = this.chargingDatasetClient(id) ?? this.client.dataset(id);
|
|
122
|
-
return adapt(client, {
|
|
123
|
-
getMetadata: 'get',
|
|
124
|
-
drop: 'delete',
|
|
125
|
-
pushData: 'pushItems',
|
|
126
|
-
getData: 'listItems',
|
|
127
|
-
}, noPurge);
|
|
128
|
-
}
|
|
129
|
-
async createKeyValueStoreClient(options) {
|
|
130
|
-
const id = await this.resolveId(options, 'KeyValueStore');
|
|
131
|
-
const client = this.client.keyValueStore(id);
|
|
132
|
-
return adapt(client, {
|
|
133
|
-
getMetadata: 'get',
|
|
134
|
-
getValue: 'getRecord',
|
|
135
|
-
setValue: 'setRecord',
|
|
136
|
-
deleteValue: 'deleteRecord',
|
|
137
|
-
drop: 'delete',
|
|
138
|
-
getPublicUrl: 'getRecordPublicUrl',
|
|
139
|
-
}, {
|
|
140
|
-
...noPurge,
|
|
141
|
-
// crawlee expects an array; apify-client returns `{ items }`.
|
|
142
|
-
listKeys: async (opts) => (await client.listKeys(opts)).items,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
async createRequestQueueClient(options) {
|
|
146
|
-
const id = await this.resolveId(options, 'RequestQueue');
|
|
147
|
-
const client = this.client.requestQueue(id, options?.clientKey ? { clientKey: options.clientKey } : undefined);
|
|
148
|
-
return adapt(client, { getMetadata: 'get', drop: 'delete' }, noPurge);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Returns a charging-aware dataset client when `id` is the run's default
|
|
152
|
-
* dataset and a default-dataset-item price is configured; otherwise
|
|
153
|
-
* `undefined` (caller uses the plain client).
|
|
154
|
-
*/
|
|
155
|
-
chargingDatasetClient(id) {
|
|
156
|
-
const { getChargingManager } = this;
|
|
157
|
-
if (!getChargingManager)
|
|
158
|
-
return undefined;
|
|
159
|
-
if (id !== this.config?.defaultDatasetId)
|
|
160
|
-
return undefined;
|
|
161
|
-
const hasDefaultDatasetItemEvent = DEFAULT_DATASET_ITEM_EVENT in getChargingManager().getPricingInfo().perEventPrices;
|
|
162
|
-
if (!hasDefaultDatasetItemEvent)
|
|
163
|
-
return undefined;
|
|
164
|
-
const datasetClient = new PpeAwareDatasetClient({
|
|
165
|
-
id,
|
|
166
|
-
baseUrl: this.client.baseUrl,
|
|
167
|
-
publicBaseUrl: this.client.publicBaseUrl,
|
|
168
|
-
apifyClient: this.client,
|
|
169
|
-
httpClient: this.client.httpClient,
|
|
170
|
-
}, getChargingManager);
|
|
171
|
-
Object.assign(datasetClient, {
|
|
172
|
-
[USES_PUSH_DATA_INTERCEPTION]: true,
|
|
173
|
-
});
|
|
174
|
-
return datasetClient;
|
|
175
|
-
}
|
|
176
|
-
async resolveId(options, type) {
|
|
177
|
-
if (options?.id)
|
|
178
|
-
return options.id;
|
|
179
|
-
if (options?.name) {
|
|
180
|
-
return (await this.collectionClient(type).getOrCreate(options.name)).id;
|
|
181
|
-
}
|
|
182
|
-
// No id/name (crawlee's `__default__` alias): use the default storage
|
|
183
|
-
// id from the run's environment. apify-client rejects an empty id.
|
|
184
|
-
return this.config?.[DEFAULT_ID_CONFIG_KEY[type]] ?? '';
|
|
185
|
-
}
|
|
186
|
-
resourceClient(id, type) {
|
|
187
|
-
if (type === 'Dataset')
|
|
188
|
-
return this.client.dataset(id);
|
|
189
|
-
if (type === 'KeyValueStore')
|
|
190
|
-
return this.client.keyValueStore(id);
|
|
191
|
-
return this.client.requestQueue(id);
|
|
192
|
-
}
|
|
193
|
-
collectionClient(type) {
|
|
194
|
-
if (type === 'Dataset')
|
|
195
|
-
return this.client.datasets();
|
|
196
|
-
if (type === 'KeyValueStore')
|
|
197
|
-
return this.client.keyValueStores();
|
|
198
|
-
return this.client.requestQueues();
|
|
199
|
-
}
|
|
200
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { StorageOpenOptions } from '@crawlee/core';
|
|
2
|
-
import { KeyValueStore as CoreKeyValueStore } from '@crawlee/core';
|
|
3
|
-
/**
|
|
4
|
-
* @inheritDoc
|
|
5
|
-
*/
|
|
6
|
-
export declare class KeyValueStore extends CoreKeyValueStore {
|
|
7
|
-
/**
|
|
8
|
-
* Returns a URL for the given key that may be used to publicly
|
|
9
|
-
* access the value in the remote key-value store.
|
|
10
|
-
*
|
|
11
|
-
* On the Apify platform the URL is signed with the store's
|
|
12
|
-
* `urlSigningSecretKey` so that anyone with the URL can read the record
|
|
13
|
-
* without authentication. Locally we delegate to crawlee's default
|
|
14
|
-
* implementation (which produces a `file://` URL or returns `undefined`).
|
|
15
|
-
*/
|
|
16
|
-
getPublicUrl(key: string): Promise<string | undefined>;
|
|
17
|
-
/**
|
|
18
|
-
* @inheritDoc
|
|
19
|
-
*/
|
|
20
|
-
static open(storeIdOrName?: string | null, options?: StorageOpenOptions): Promise<KeyValueStore>;
|
|
21
|
-
}
|
package/dist/key_value_store.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { KeyValueStore as CoreKeyValueStore } from '@crawlee/core';
|
|
2
|
-
import { KeyValueStoreClient as RemoteKeyValueStoreClient } from 'apify-client';
|
|
3
|
-
import { createHmacSignature } from '@apify/utilities';
|
|
4
|
-
/**
|
|
5
|
-
* @inheritDoc
|
|
6
|
-
*/
|
|
7
|
-
export class KeyValueStore extends CoreKeyValueStore {
|
|
8
|
-
/**
|
|
9
|
-
* Returns a URL for the given key that may be used to publicly
|
|
10
|
-
* access the value in the remote key-value store.
|
|
11
|
-
*
|
|
12
|
-
* On the Apify platform the URL is signed with the store's
|
|
13
|
-
* `urlSigningSecretKey` so that anyone with the URL can read the record
|
|
14
|
-
* without authentication. Locally we delegate to crawlee's default
|
|
15
|
-
* implementation (which produces a `file://` URL or returns `undefined`).
|
|
16
|
-
*/
|
|
17
|
-
async getPublicUrl(key) {
|
|
18
|
-
const config = this.config;
|
|
19
|
-
// Detect a remote (Apify) store by its client type rather than by
|
|
20
|
-
// `isAtHome`, so that a `forceCloud` store opened locally still gets a
|
|
21
|
-
// signed Apify URL (matching the platform behaviour). `client` is
|
|
22
|
-
// `private` on `CoreKeyValueStore`, so bypass the visibility check.
|
|
23
|
-
const { client } = this;
|
|
24
|
-
const isLocalStore = !(client instanceof RemoteKeyValueStoreClient);
|
|
25
|
-
if (isLocalStore) {
|
|
26
|
-
return super.getPublicUrl(key);
|
|
27
|
-
}
|
|
28
|
-
const publicUrl = new URL(`${config.apiPublicBaseUrl}/v2/key-value-stores/${this.id}/records/${key}`);
|
|
29
|
-
const metadata = (await client.getMetadata());
|
|
30
|
-
if (metadata?.urlSigningSecretKey) {
|
|
31
|
-
publicUrl.searchParams.append('signature', createHmacSignature(metadata.urlSigningSecretKey, key));
|
|
32
|
-
}
|
|
33
|
-
return publicUrl.toString();
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @inheritDoc
|
|
37
|
-
*/
|
|
38
|
-
static async open(storeIdOrName, options = {}) {
|
|
39
|
-
return super.open(storeIdOrName, options);
|
|
40
|
-
}
|
|
41
|
-
}
|