@apify/actor-utils 0.1.8-beta.0 → 0.1.8

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.
@@ -1,8 +1,8 @@
1
1
  import type { ChargeResult } from 'apify';
2
2
  /**
3
- * Pushes to the default dataset, or a named dataset when `alias` is given,
4
- * converting a schema-validation failure into a {@link NonRetryableError}
5
- * instead of leaving it to be retried.
3
+ * Pushes to the default dataset, or a named dataset when `alias` is given.
4
+ * Items that fail dataset schema-validation are repaired where possible and
5
+ * dropped (with a logged error) otherwise, instead of failing the whole push.
6
6
  *
7
7
  * @param data - A single item or array of items to push.
8
8
  * @param options.alias - Alias of the dataset to push to, opened via {@link Actor.openDataset}.
@@ -21,9 +21,9 @@ export declare function safePushData<T extends object>(data: T | T[], options?:
21
21
  }): Promise<void>;
22
22
  /**
23
23
  * Pushes to the default dataset and atomically charges for `eventName`, via
24
- * {@link Actor.pushData}'s built-in pay-per-event support. Converts a
25
- * schema-validation failure into a {@link NonRetryableError} instead of
26
- * leaving it to be retried.
24
+ * {@link Actor.pushData}'s built-in pay-per-event support. Items that fail
25
+ * dataset schema-validation are repaired where possible and dropped (with a
26
+ * logged error) otherwise, instead of failing the whole push.
27
27
  *
28
28
  * @param data - A single item or array of items to push.
29
29
  * @param options.eventName - Pay-per-event event name to charge for this push.
@@ -1 +1 @@
1
- {"version":3,"file":"push-data.d.ts","sourceRoot":"","sources":["../../../src/gteam-internal/push-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAwB1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AACjB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"push-data.d.ts","sourceRoot":"","sources":["../../../src/gteam-internal/push-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAgC1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;AACjB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC/C,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC,CAAC"}
@@ -1,40 +1,40 @@
1
- import { NonRetryableError } from '@crawlee/core';
2
1
  import { Actor, log } from 'apify';
3
- import { ApifyApiError } from 'apify-client';
2
+ import { pushDataWithSchemaRepair } from '../push-data-with-schema-repair/index.js';
3
+ // Actor.pushData(items, eventName)'s resolved value when every item got
4
+ // dropped and the push itself never ran — mirrors what a charge-less push
5
+ // would report, so callers checking `chargeableWithinLimit` don't crash on
6
+ // a missing result.
7
+ const NO_CHARGE_RESULT = {
8
+ eventChargeLimitReached: false,
9
+ chargedCount: 0,
10
+ chargeableWithinLimit: {},
11
+ };
4
12
  /**
5
- * Wraps a push call, converting a dataset schema-validation failure into a
6
- * {@link NonRetryableError} instead of a retryable one — a schema mismatch
7
- * will never fix itself on retry, so retrying just burns compute.
13
+ * Wraps a push call, repairing or dropping items that fail dataset
14
+ * schema-validation instead of letting the whole batch fail. Every dropped
15
+ * item is logged, so existing log-based monitoring keeps working.
8
16
  */
9
- async function wrapPushData(pushDataFn) {
10
- try {
11
- return await pushDataFn();
12
- }
13
- catch (error) {
14
- if (!(error instanceof ApifyApiError) || !Array.isArray(error.data?.invalidItems)) {
15
- throw error;
16
- }
17
- const msg = 'Dataset validation failed';
18
- for (const { validationErrors } of error.data.invalidItems) {
19
- log.error(msg, { msg, error: `${error}`, validationErrors });
20
- }
21
- throw new NonRetryableError(msg);
17
+ async function wrapPushData(data, pushFn) {
18
+ const msg = 'Dataset validation failed';
19
+ const { droppedItems, pushResult } = await pushDataWithSchemaRepair(pushFn, data);
20
+ for (const { errors } of droppedItems) {
21
+ log.error(msg, { msg, validationErrors: errors });
22
22
  }
23
+ return pushResult;
23
24
  }
24
25
  export async function safePushData(data, options) {
25
26
  const { alias, eventName } = options ?? {};
26
- // Default dataset: Actor.pushData(data, eventName) already pushes and
27
+ // Default dataset: Actor.pushData(items, eventName) already pushes and
27
28
  // charges atomically, so delegate to it as-is instead of reimplementing charging.
28
29
  if (!alias) {
29
30
  if (eventName) {
30
- return wrapPushData(async () => Actor.pushData(data, eventName));
31
+ const pushResult = await wrapPushData(data, async (items) => Actor.pushData(items, eventName));
32
+ return pushResult ?? NO_CHARGE_RESULT;
31
33
  }
32
- return wrapPushData(async () => Actor.pushData(data));
34
+ return wrapPushData(data, async (items) => Actor.pushData(items));
33
35
  }
34
36
  // Named dataset: charging is handled by the caller — call Actor.charge() themselves after this push.
35
37
  const dataset = await Actor.openDataset({ alias });
36
- return wrapPushData(async () => {
37
- await dataset.pushData(data);
38
- });
38
+ return wrapPushData(data, async (items) => dataset.pushData(items));
39
39
  }
40
40
  //# sourceMappingURL=push-data.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"push-data.js","sourceRoot":"","sources":["../../../src/gteam-internal/push-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAI,UAA4B;IACvD,IAAI,CAAC;QACD,OAAO,MAAM,UAAU,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,KAAK,YAAY,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC;YAChF,MAAM,KAAK,CAAC;QAChB,CAAC;QACD,MAAM,GAAG,GAAG,2BAA2B,CAAC;QACxC,KAAK,MAAM,EAAE,gBAAgB,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;AACL,CAAC;AAyCD,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,IAAa,EACb,OAAgD;IAEhD,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAE3C,sEAAsE;IACtE,kFAAkF;IAClF,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,IAAI,SAAS,EAAE,CAAC;YACZ,OAAO,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,qGAAqG;IACrG,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,CAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,OAAO,YAAY,CAAC,KAAK,IAAI,EAAE;QAC3B,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"push-data.js","sourceRoot":"","sources":["../../../src/gteam-internal/push-data.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,oBAAoB;AACpB,MAAM,gBAAgB,GAAiB;IACnC,uBAAuB,EAAE,KAAK;IAC9B,YAAY,EAAE,CAAC;IACf,qBAAqB,EAAE,EAAE;CAC5B,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,YAAY,CACvB,IAAa,EACb,MAAkC;IAElC,MAAM,GAAG,GAAG,2BAA2B,CAAC;IACxC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClF,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAyCD,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,IAAa,EACb,OAAgD;IAEhD,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAE3C,uEAAuE;IACvE,kFAAkF;IAClF,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YAC/F,OAAO,UAAU,IAAI,gBAAgB,CAAC;QAC1C,CAAC;QACD,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,qGAAqG;IACrG,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,CAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,CAAC"}
package/package.json CHANGED
@@ -1,113 +1,108 @@
1
1
  {
2
- "name": "@apify/actor-utils",
3
- "version": "0.1.8-beta.0",
4
- "type": "module",
5
- "description": "Wrapper around Actor.pushData that survives dataset schema-validation failures by stripping offending fields and retrying. Callers pass the actual push function as pushFn.",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/apify/apify-actor-utils.git"
9
- },
10
- "engines": {
11
- "node": ">=22.6.0"
12
- },
13
- "types": "./dist/index.d.ts",
14
- "main": "./dist/index.js",
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "default": "./dist/index.js"
2
+ "name": "@apify/actor-utils",
3
+ "version": "0.1.8",
4
+ "type": "module",
5
+ "description": "Wrapper around Actor.pushData that survives dataset schema-validation failures by stripping offending fields and retrying. Callers pass the actual push function as pushFn.",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/apify/apify-actor-utils.git"
19
9
  },
20
- "./push-data-with-schema-repair": {
21
- "types": "./dist/src/push-data-with-schema-repair/index.d.ts",
22
- "default": "./dist/src/push-data-with-schema-repair/index.js"
10
+ "engines": {
11
+ "node": ">=22.6.0"
23
12
  },
24
- "./qc-logger": {
25
- "types": "./dist/src/qc-logger/index.d.ts",
26
- "default": "./dist/src/qc-logger/index.js"
13
+ "types": "./dist/index.d.ts",
14
+ "main": "./dist/index.js",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./push-data-with-schema-repair": {
21
+ "types": "./dist/src/push-data-with-schema-repair/index.d.ts",
22
+ "default": "./dist/src/push-data-with-schema-repair/index.js"
23
+ },
24
+ "./qc-logger": {
25
+ "types": "./dist/src/qc-logger/index.d.ts",
26
+ "default": "./dist/src/qc-logger/index.js"
27
+ },
28
+ "./type-utils": {
29
+ "types": "./dist/src/type-utils/index.d.ts",
30
+ "default": "./dist/src/type-utils/index.js"
31
+ },
32
+ "./gteam-internal": {
33
+ "types": "./dist/src/gteam-internal/index.d.ts",
34
+ "default": "./dist/src/gteam-internal/index.js"
35
+ }
27
36
  },
28
- "./type-utils": {
29
- "types": "./dist/src/type-utils/index.d.ts",
30
- "default": "./dist/src/type-utils/index.js"
37
+ "files": [
38
+ "dist/index.js",
39
+ "dist/index.js.map",
40
+ "dist/index.d.ts",
41
+ "dist/index.d.ts.map",
42
+ "dist/src"
43
+ ],
44
+ "typesVersions": {
45
+ "*": {
46
+ "qc-logger": [
47
+ "dist/src/qc-logger/index.d.ts"
48
+ ],
49
+ "type-utils": [
50
+ "dist/src/type-utils/index.d.ts"
51
+ ],
52
+ "gteam-internal": [
53
+ "dist/src/gteam-internal/index.d.ts"
54
+ ]
55
+ }
31
56
  },
32
- "./gteam-internal": {
33
- "types": "./dist/src/gteam-internal/index.d.ts",
34
- "default": "./dist/src/gteam-internal/index.js"
35
- }
36
- },
37
- "files": [
38
- "dist/index.js",
39
- "dist/index.js.map",
40
- "dist/index.d.ts",
41
- "dist/index.d.ts.map",
42
- "dist/src"
43
- ],
44
- "typesVersions": {
45
- "*": {
46
- "qc-logger": [
47
- "dist/src/qc-logger/index.d.ts"
48
- ],
49
- "type-utils": [
50
- "dist/src/type-utils/index.d.ts"
51
- ],
52
- "gteam-internal": [
53
- "dist/src/gteam-internal/index.d.ts"
54
- ]
55
- }
56
- },
57
- "scripts": {
58
- "build": "tsc",
59
- "typecheck": "tsc --noEmit",
60
- "lint": "eslint",
61
- "lint:fix": "eslint --fix",
62
- "format": "prettier --write .",
63
- "format:check": "prettier --check .",
64
- "test": "vitest run --coverage",
65
- "check:pushdata": "node scripts/check-pushdata.mjs",
66
- "check-unused": "knip",
67
- "ci": "npm run typecheck && npm run lint && npm run format:check && npm run check:pushdata && npm test",
68
- "probe": "node scripts/probe-errors.mjs",
69
- "prepare": "husky .husky || true"
70
- },
71
- "lint-staged": {
72
- "*.js": "eslint",
73
- "*.ts": "eslint",
74
- "*.mjs": "eslint"
75
- },
76
- "devDependencies": {
77
- "@apify/eslint-config": "^1.2.0",
78
- "@apify/tsconfig": "^0.1.2",
79
- "@crawlee/core": "3.16.0",
80
- "@types/node": "^25.9.1",
81
- "@vitest/coverage-v8": "^4.0.18",
82
- "apify": "3.7.2",
83
- "apify-client": "^2.17.0",
84
- "eslint": "^9.39.4",
85
- "eslint-config-prettier": "^10.1.8",
86
- "globals": "^17.7.0",
87
- "husky": "^9.1.7",
88
- "knip": "^5.88.1",
89
- "lint-staged": "^15.5.2",
90
- "prettier": "^3.9.4",
91
- "typescript": "^6.0.3",
92
- "typescript-eslint": "^8.62.1",
93
- "vitest": "^4.0.18"
94
- },
95
- "license": "ISC",
96
- "peerDependencies": {
97
- "@apify/log": "^2",
98
- "@crawlee/core": "^3",
99
- "apify": "^3",
100
- "apify-client": "^2"
101
- },
102
- "peerDependenciesMeta": {
103
- "@crawlee/core": {
104
- "optional": true
57
+ "scripts": {
58
+ "build": "tsc",
59
+ "typecheck": "tsc --noEmit",
60
+ "lint": "eslint",
61
+ "lint:fix": "eslint --fix",
62
+ "format": "prettier --write .",
63
+ "format:check": "prettier --check .",
64
+ "test": "vitest run --coverage",
65
+ "check:pushdata": "node scripts/check-pushdata.mjs",
66
+ "check-unused": "knip",
67
+ "ci": "npm run typecheck && npm run lint && npm run format:check && npm run check:pushdata && npm test",
68
+ "probe": "node scripts/probe-errors.mjs",
69
+ "prepare": "husky .husky || true"
70
+ },
71
+ "lint-staged": {
72
+ "*.js": "eslint",
73
+ "*.ts": "eslint",
74
+ "*.mjs": "eslint"
75
+ },
76
+ "devDependencies": {
77
+ "@apify/eslint-config": "^1.2.0",
78
+ "@apify/tsconfig": "^0.1.2",
79
+ "@types/node": "^25.9.1",
80
+ "@vitest/coverage-v8": "^4.0.18",
81
+ "apify": "3.7.2",
82
+ "apify-client": "^2.17.0",
83
+ "eslint": "^9.39.4",
84
+ "eslint-config-prettier": "^10.1.8",
85
+ "globals": "^17.7.0",
86
+ "husky": "^9.1.7",
87
+ "knip": "^5.88.1",
88
+ "lint-staged": "^15.5.2",
89
+ "prettier": "^3.9.4",
90
+ "typescript": "^6.0.3",
91
+ "typescript-eslint": "^8.62.1",
92
+ "vitest": "^4.0.18"
105
93
  },
106
- "apify": {
107
- "optional": true
94
+ "license": "ISC",
95
+ "peerDependencies": {
96
+ "@apify/log": "^2",
97
+ "apify": "^3",
98
+ "apify-client": "^2"
108
99
  },
109
- "apify-client": {
110
- "optional": true
100
+ "peerDependenciesMeta": {
101
+ "apify": {
102
+ "optional": true
103
+ },
104
+ "apify-client": {
105
+ "optional": true
106
+ }
111
107
  }
112
- }
113
108
  }