@apify/actor-utils 0.1.9-beta.0 → 0.1.9-beta.2

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.
@@ -0,0 +1,3 @@
1
+ export { partialSafeParse, PartialSafeParseResult, RecursivePartial } from './partial-safe-parse.js';
2
+ export { StringyIntegerSchema } from './stringy-integer-schema.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/zod/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { partialSafeParse } from './partial-safe-parse.js';
2
+ export { StringyIntegerSchema } from './stringy-integer-schema.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/zod/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4C,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,25 @@
1
+ import z, { ZodError } from 'zod';
2
+ export type RecursivePartial<T> = T extends object ? {
3
+ [P in keyof T]?: RecursivePartial<T[P]>;
4
+ } : T;
5
+ export type PartialSafeParseResult<Schema extends z.ZodType> = {
6
+ success: true;
7
+ data: z.infer<Schema>;
8
+ error: never;
9
+ } | {
10
+ success: false;
11
+ data: RecursivePartial<z.infer<Schema>> | undefined;
12
+ error: ZodError;
13
+ };
14
+ /**
15
+ * Performs a recursive partial safe parse on the provided data using the given Zod schema.
16
+ * - This makes sure that all nested objects are parsed as deeply as possible, returning any successfully parsed data
17
+ * along with detailed errors for any failures.
18
+ *
19
+ * Parsing cases:
20
+ * - For objects, returns any fields containing at least partially parsed data with nested structures preserved.
21
+ * - For arrays, returns items containing at least partially parsed data.
22
+ * - For primitives, simply returns the error if parsing fails.
23
+ */
24
+ export declare function partialSafeParse<Schema extends z.ZodType>(schema: Schema, data: unknown): PartialSafeParseResult<Schema>;
25
+ //# sourceMappingURL=partial-safe-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial-safe-parse.d.ts","sourceRoot":"","sources":["../../../src/zod/partial-safe-parse.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAGlC,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,CAAC,CAAC;AAErG,MAAM,MAAM,sBAAsB,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,IACrD;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACtD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE/F;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,EACrD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACd,sBAAsB,CAAC,MAAM,CAAC,CAIhC"}
@@ -0,0 +1,120 @@
1
+ import z, { ZodError } from 'zod';
2
+ /**
3
+ * Performs a recursive partial safe parse on the provided data using the given Zod schema.
4
+ * - This makes sure that all nested objects are parsed as deeply as possible, returning any successfully parsed data
5
+ * along with detailed errors for any failures.
6
+ *
7
+ * Parsing cases:
8
+ * - For objects, returns any fields containing at least partially parsed data with nested structures preserved.
9
+ * - For arrays, returns items containing at least partially parsed data.
10
+ * - For primitives, simply returns the error if parsing fails.
11
+ */
12
+ export function partialSafeParse(schema, data) {
13
+ const basePath = [];
14
+ return partialSafeParseInternal(schema, data, basePath);
15
+ }
16
+ /**
17
+ * Implementation of the recursive partial safe parse logic.
18
+ * - Due to typescripts and zod's type limitations around generics, we cannot type the full function properly
19
+ * - So it's easier to just type cast it instead of doing it the proper way.
20
+ * - Wrappers are unwrapped through `def.innerType` rather than by naming wrapper classes, which covers chains such
21
+ * as `.nullish()` and wrappers we have not thought of
22
+ * - Wrappers that accept the value (an absent `.optional()`, an applied `.default()`, any `.catch()`) return at
23
+ * the success check first, so they are never unwrapped
24
+ */
25
+ function partialSafeParseInternal(schema, data, path) {
26
+ const result = z.safeParse(schema, data);
27
+ if (result.success)
28
+ return result;
29
+ if (schema instanceof z.ZodObject && isRecord(data)) {
30
+ return partialSafeParseObject(schema, data, path);
31
+ }
32
+ const isArrayLikeSchema = schema instanceof z.ZodArray || schema instanceof z.ZodTuple;
33
+ if (isArrayLikeSchema && Array.isArray(data)) {
34
+ return partialSafeParseArrayLike(schema, data, path);
35
+ }
36
+ // Wrapper schema - re-enter with the inner type so the checks above get a chance at it
37
+ const innerType = getWrappedInnerType(schema);
38
+ if (innerType) {
39
+ return partialSafeParseInternal(innerType, data, path);
40
+ }
41
+ // Primitive failure
42
+ const errorWithPath = mergeZodErrorWithPath(result.error, path);
43
+ return { error: errorWithPath, success: false };
44
+ }
45
+ /**
46
+ * Performs a recursive partial safe parse on an object schema, processing each field individually.
47
+ * At least partially parsed fields are collected in `partialData`, while errors for failed fields are aggregated.
48
+ */
49
+ function partialSafeParseObject(schema, data, path) {
50
+ const partialData = {};
51
+ const errors = [];
52
+ for (const key of Object.keys(schema.shape)) {
53
+ const keySchema = schema.shape[key];
54
+ const fieldResult = partialSafeParseInternal(keySchema, data[key], [...path, key]);
55
+ if (fieldResult.success) {
56
+ partialData[key] = fieldResult.data;
57
+ continue;
58
+ }
59
+ if ('data' in fieldResult) {
60
+ partialData[key] = fieldResult.data;
61
+ }
62
+ errors.push(fieldResult.error);
63
+ }
64
+ const error = new ZodError(errors.flatMap((err) => err.issues));
65
+ return { data: partialData, error, success: false };
66
+ }
67
+ /**
68
+ * Performs a recursive partial safe parse on array-like schemas (arrays and tuples), processing each item individually.
69
+ * - All at least partially parsed items are collected in `partialData`, while errors for failed items are aggregated.
70
+ */
71
+ function partialSafeParseArrayLike(schema, data, path) {
72
+ const partialData = [];
73
+ const errors = [];
74
+ for (const [index, item] of data.entries()) {
75
+ const itemSchema = getArrayLikeItemSchema(schema, index);
76
+ if ('skipRemainingItems' in itemSchema)
77
+ break;
78
+ const itemResult = partialSafeParseInternal(itemSchema, item, [...path, index]);
79
+ if (itemResult.success) {
80
+ partialData.push(itemResult.data);
81
+ continue;
82
+ }
83
+ if ('data' in itemResult) {
84
+ partialData.push(itemResult.data);
85
+ }
86
+ errors.push(itemResult.error);
87
+ }
88
+ const error = new ZodError(errors.flatMap((err) => err.issues));
89
+ return { data: partialData, error, success: false };
90
+ }
91
+ /**
92
+ * Gets the item schema for the given item index in the array like structure.
93
+ * - For regular arrays the schema is the same for all items
94
+ * - For tuples, we have to get the schema for each element separately. If we run out of items we continue onto the rest
95
+ * attribute, if available, otherwise we skip the remaining items.
96
+ */
97
+ function getArrayLikeItemSchema(schema, index) {
98
+ if (schema instanceof z.ZodArray) {
99
+ return schema.element;
100
+ }
101
+ return schema.def.items[index] ?? schema.def.rest ?? { skipRemainingItems: true };
102
+ }
103
+ function getWrappedInnerType(schema) {
104
+ if (!(schema instanceof z.ZodType))
105
+ return undefined;
106
+ const { def } = schema;
107
+ if (!('innerType' in def))
108
+ return undefined;
109
+ return def.innerType instanceof z.ZodType ? def.innerType : undefined;
110
+ }
111
+ function isRecord(value) {
112
+ return typeof value === 'object' && value !== null;
113
+ }
114
+ function mergeZodErrorWithPath(error, path) {
115
+ return new ZodError(error.issues.map((issue) => ({
116
+ ...issue,
117
+ path: [...path, ...issue.path],
118
+ })));
119
+ }
120
+ //# sourceMappingURL=partial-safe-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial-safe-parse.js","sourceRoot":"","sources":["../../../src/zod/partial-safe-parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * This validates the string is a plain non-negative integer and converts it to a `number`.
4
+ * - Also rejects values that would lose precision past `Number.MAX_SAFE_INTEGER`
5
+ */
6
+ export declare const StringyIntegerSchema: z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>;
7
+ //# sourceMappingURL=stringy-integer-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringy-integer-schema.d.ts","sourceRoot":"","sources":["../../../src/zod/stringy-integer-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,oBAAoB,wDAgB3B,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * This validates the string is a plain non-negative integer and converts it to a `number`.
4
+ * - Also rejects values that would lose precision past `Number.MAX_SAFE_INTEGER`
5
+ */
6
+ export const StringyIntegerSchema = z
7
+ .string()
8
+ .regex(/^\d+$/, {
9
+ error: (issue) => `Invalid input: expected numeric string, received ${JSON.stringify(issue.input)}`,
10
+ })
11
+ .transform((value, ctx) => {
12
+ const number = Number(value);
13
+ if (Number.isSafeInteger(number))
14
+ return number;
15
+ ctx.addIssue({
16
+ code: 'custom',
17
+ message: `Invalid input: stringy integer "${value}" exceeds Number.MAX_SAFE_INTEGER and would lose precision` +
18
+ ' - use z.string() for this field instead',
19
+ });
20
+ return z.NEVER;
21
+ });
22
+ //# sourceMappingURL=stringy-integer-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringy-integer-schema.js","sourceRoot":"","sources":["../../../src/zod/stringy-integer-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,KAAK,CAAC,OAAO,EAAE;IACZ,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,oDAAoD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;CACtG,CAAC;KACD,SAAS,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACtB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEhD,GAAG,CAAC,QAAQ,CAAC;QACT,IAAI,EAAE,QAAQ;QACd,OAAO,EACH,mCAAmC,KAAK,4DAA4D;YACpG,0CAA0C;KACjD,CAAC,CAAC;IACH,OAAO,CAAC,CAAC,KAAK,CAAC;AACnB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/actor-utils",
3
- "version": "0.1.9-beta.0",
3
+ "version": "0.1.9-beta.2",
4
4
  "type": "module",
5
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
6
  "repository": {
@@ -32,6 +32,10 @@
32
32
  "./gteam-internal": {
33
33
  "types": "./dist/src/gteam-internal/index.d.ts",
34
34
  "default": "./dist/src/gteam-internal/index.js"
35
+ },
36
+ "./zod": {
37
+ "types": "./dist/src/zod/index.d.ts",
38
+ "default": "./dist/src/zod/index.js"
35
39
  }
36
40
  },
37
41
  "files": [
@@ -51,6 +55,9 @@
51
55
  ],
52
56
  "gteam-internal": [
53
57
  "dist/src/gteam-internal/index.d.ts"
58
+ ],
59
+ "zod": [
60
+ "dist/src/zod/index.d.ts"
54
61
  ]
55
62
  }
56
63
  },
@@ -89,13 +96,15 @@
89
96
  "prettier": "^3.9.4",
90
97
  "typescript": "^6.0.3",
91
98
  "typescript-eslint": "^8.62.1",
92
- "vitest": "^4.0.18"
99
+ "vitest": "^4.0.18",
100
+ "zod": "^4.6.2"
93
101
  },
94
102
  "license": "ISC",
95
103
  "peerDependencies": {
96
104
  "@apify/log": "^2",
97
105
  "apify": "^3",
98
- "apify-client": "^2"
106
+ "apify-client": "^2",
107
+ "zod": "^4"
99
108
  },
100
109
  "peerDependenciesMeta": {
101
110
  "apify": {
@@ -103,6 +112,9 @@
103
112
  },
104
113
  "apify-client": {
105
114
  "optional": true
115
+ },
116
+ "zod": {
117
+ "optional": true
106
118
  }
107
119
  }
108
120
  }