erpnext-queue-client 2.6.3 → 2.6.4
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/client.test.js +6 -7
- package/dist/erpnext/model/DocTypeHelpers.d.ts +2 -2
- package/dist/erpnext/model/Servicecase.d.ts +8 -8
- package/dist/erpnext/model/Servicecase.js +1 -1
- package/dist/erpnext/resourceRequest.d.ts +3 -1
- package/dist/erpnext/resourceRequest.js +14 -6
- package/dist/erpnext/resourceRequest.test.js +47 -8
- package/package.json +1 -1
package/dist/client.test.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
3
|
const zod_1 = require("zod");
|
|
5
4
|
const client_1 = require("./client");
|
|
6
5
|
const responseSchema = zod_1.z
|
|
@@ -10,14 +9,14 @@ const responseSchema = zod_1.z
|
|
|
10
9
|
})),
|
|
11
10
|
})
|
|
12
11
|
.describe('Dispatcher Preset List with fields ["name"]');
|
|
13
|
-
|
|
12
|
+
describe("TemporalClient.executeERPNextRequestWorkflow", () => {
|
|
14
13
|
const originalNodeEnv = process.env.NODE_ENV;
|
|
15
14
|
const originalRunInTestEnv = process.env.RUN_IN_TEST_ENV;
|
|
16
|
-
|
|
15
|
+
afterEach(() => {
|
|
17
16
|
process.env.NODE_ENV = originalNodeEnv;
|
|
18
17
|
process.env.RUN_IN_TEST_ENV = originalRunInTestEnv;
|
|
19
18
|
});
|
|
20
|
-
|
|
19
|
+
test("includes a preview of invalid string responses in validation errors", async () => {
|
|
21
20
|
process.env.NODE_ENV = "test";
|
|
22
21
|
process.env.RUN_IN_TEST_ENV = "true";
|
|
23
22
|
const temporalClient = new client_1.TemporalClient({
|
|
@@ -34,8 +33,8 @@ const responseSchema = zod_1.z
|
|
|
34
33
|
responseValidationModel: responseSchema,
|
|
35
34
|
}, "erpnext")
|
|
36
35
|
.catch((err) => err);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
expect(error).toBeInstanceOf(Error);
|
|
37
|
+
expect(error.message).toContain("Response preview:");
|
|
38
|
+
expect(error.message).toContain("<html>Cloudflare Access denied</html>");
|
|
40
39
|
});
|
|
41
40
|
});
|
|
@@ -2,7 +2,7 @@ import { AnyZodObject, z, ZodArray, ZodNullable, ZodObject, ZodOptional, ZodRawS
|
|
|
2
2
|
import { Prettify } from "../../utils/utils";
|
|
3
3
|
import { KeysOf } from "../../utils/zodUtils";
|
|
4
4
|
import { DocTypeChildTableEntryMeta, DocTypeMeta, SubmittableMeta } from "./ERPNextDocTypeMeta";
|
|
5
|
-
export type KeysOfModel<T> = KeysOf<T extends AnyZodObject ? DocModelListEntryType<T> : never>;
|
|
5
|
+
export type KeysOfModel<T> = Extract<KeysOf<T extends AnyZodObject ? DocModelListEntryType<T> : never>, string>;
|
|
6
6
|
/**
|
|
7
7
|
* Extracts the alias from a field name if it contains " as ".
|
|
8
8
|
* For example: "`tabItemTaxTemplateDetail`.rate as rate" -> "rate"
|
|
@@ -16,7 +16,7 @@ type ExtractAlias<T extends string> = T extends `${infer _Before} as ${infer Ali
|
|
|
16
16
|
type PickWithAliases<TModel extends AnyZodObject, TFields extends readonly string[]> = {
|
|
17
17
|
[K in TFields[number] as ExtractAlias<K>]: ExtractAlias<K> extends keyof z.infer<DocModelListEntryType<TModel>> ? z.infer<DocModelListEntryType<TModel>>[ExtractAlias<K>] : never;
|
|
18
18
|
};
|
|
19
|
-
export type GetListReturnValue<TModel, TFieldOptions extends
|
|
19
|
+
export type GetListReturnValue<TModel, TFieldOptions extends string, TSelectedFields, TAsDict> = Prettify<TAsDict extends false ? Array<Array<string>> : TModel extends AnyZodObject ? TSelectedFields extends undefined ? Array<{
|
|
20
20
|
name: string;
|
|
21
21
|
}> : TSelectedFields extends readonly ["*"] ? Array<z.infer<DocModelListEntryType<TModel>>> : TSelectedFields extends readonly TFieldOptions[] ? Array<PickWithAliases<TModel, TSelectedFields>> : any : any>;
|
|
22
22
|
export declare const LoadDocumentWrapper: <T extends AnyZodObject>(BaseModel: T) => z.ZodObject<{
|
|
@@ -130,13 +130,13 @@ export declare const ReturnItemInput: z.ZodObject<{
|
|
|
130
130
|
return_fee: z.ZodDefault<z.ZodNumber>;
|
|
131
131
|
return_label: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
132
132
|
} & {
|
|
133
|
-
name: z.ZodString
|
|
133
|
+
name: z.ZodOptional<z.ZodString>;
|
|
134
134
|
}, "strip", z.ZodTypeAny, {
|
|
135
|
-
name: string;
|
|
136
135
|
item: string;
|
|
137
136
|
return_quantity: number;
|
|
138
137
|
is_complaint: 0 | 1;
|
|
139
138
|
return_fee: number;
|
|
139
|
+
name?: string | undefined;
|
|
140
140
|
attachments?: string | null | undefined;
|
|
141
141
|
internal_reasons?: string | null | undefined;
|
|
142
142
|
line_item_id?: string | null | undefined;
|
|
@@ -149,9 +149,9 @@ export declare const ReturnItemInput: z.ZodObject<{
|
|
|
149
149
|
complaint_description?: string | null | undefined;
|
|
150
150
|
return_label?: string | null | undefined;
|
|
151
151
|
}, {
|
|
152
|
-
name: string;
|
|
153
152
|
item: string;
|
|
154
153
|
return_quantity: number;
|
|
154
|
+
name?: string | undefined;
|
|
155
155
|
attachments?: string | null | undefined;
|
|
156
156
|
internal_reasons?: string | null | undefined;
|
|
157
157
|
line_item_id?: string | null | undefined;
|
|
@@ -494,13 +494,13 @@ export declare const ServicecaseInput: import("../../utils/zodContextOptionals")
|
|
|
494
494
|
return_fee: z.ZodDefault<z.ZodNumber>;
|
|
495
495
|
return_label: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
496
496
|
} & {
|
|
497
|
-
name: z.ZodString
|
|
497
|
+
name: z.ZodOptional<z.ZodString>;
|
|
498
498
|
}, "strip", z.ZodTypeAny, {
|
|
499
|
-
name: string;
|
|
500
499
|
item: string;
|
|
501
500
|
return_quantity: number;
|
|
502
501
|
is_complaint: 0 | 1;
|
|
503
502
|
return_fee: number;
|
|
503
|
+
name?: string | undefined;
|
|
504
504
|
attachments?: string | null | undefined;
|
|
505
505
|
internal_reasons?: string | null | undefined;
|
|
506
506
|
line_item_id?: string | null | undefined;
|
|
@@ -513,9 +513,9 @@ export declare const ServicecaseInput: import("../../utils/zodContextOptionals")
|
|
|
513
513
|
complaint_description?: string | null | undefined;
|
|
514
514
|
return_label?: string | null | undefined;
|
|
515
515
|
}, {
|
|
516
|
-
name: string;
|
|
517
516
|
item: string;
|
|
518
517
|
return_quantity: number;
|
|
518
|
+
name?: string | undefined;
|
|
519
519
|
attachments?: string | null | undefined;
|
|
520
520
|
internal_reasons?: string | null | undefined;
|
|
521
521
|
line_item_id?: string | null | undefined;
|
|
@@ -565,11 +565,11 @@ export declare const ServicecaseInput: import("../../utils/zodContextOptionals")
|
|
|
565
565
|
is_sent_to_cc: 0 | 1;
|
|
566
566
|
created_with: "Amazon FBA" | "Amazon FBM" | "Serviceportal" | "Missive Sidebar";
|
|
567
567
|
return_items: {
|
|
568
|
-
name: string;
|
|
569
568
|
item: string;
|
|
570
569
|
return_quantity: number;
|
|
571
570
|
is_complaint: 0 | 1;
|
|
572
571
|
return_fee: number;
|
|
572
|
+
name?: string | undefined;
|
|
573
573
|
attachments?: string | null | undefined;
|
|
574
574
|
internal_reasons?: string | null | undefined;
|
|
575
575
|
line_item_id?: string | null | undefined;
|
|
@@ -602,9 +602,9 @@ export declare const ServicecaseInput: import("../../utils/zodContextOptionals")
|
|
|
602
602
|
order_number: string;
|
|
603
603
|
shop: "Shopify" | "Amazon FBA" | "Amazon FBM" | "Otto" | "Amazon" | "WordPress";
|
|
604
604
|
return_items: {
|
|
605
|
-
name: string;
|
|
606
605
|
item: string;
|
|
607
606
|
return_quantity: number;
|
|
607
|
+
name?: string | undefined;
|
|
608
608
|
attachments?: string | null | undefined;
|
|
609
609
|
internal_reasons?: string | null | undefined;
|
|
610
610
|
line_item_id?: string | null | undefined;
|
|
@@ -61,7 +61,7 @@ exports.ReturnItem = zod_1.z
|
|
|
61
61
|
})
|
|
62
62
|
.describe("ReturnItem");
|
|
63
63
|
exports.ReturnItemInput = exports.ReturnItem.extend({
|
|
64
|
-
name: zod_1.z.string(),
|
|
64
|
+
name: zod_1.z.string().optional(),
|
|
65
65
|
}).describe("ReturnItemInput");
|
|
66
66
|
exports.ReturnItemExtended = (0, DocTypeHelpers_1.DocModel)(exports.ReturnItem.extend({
|
|
67
67
|
attachments: zod_1.z.array(zod_1.z.object({ url: zod_1.z.string(), type: zod_1.z.enum(["image", "video"]) })),
|
|
@@ -4,12 +4,13 @@ import { Prettify } from "../utils/utils";
|
|
|
4
4
|
import { DocModelType, GetListReturnValue, KeysOfModel } from "./model/DocTypeHelpers";
|
|
5
5
|
import { DeleteResponseModel } from "./model/ERPNextResponse";
|
|
6
6
|
import { ResourceInputType } from "../utils/zodContextOptionals";
|
|
7
|
+
type GetListFieldOptions<TModel extends AnyZodObject | undefined> = TModel extends AnyZodObject ? KeysOfModel<TModel> : string;
|
|
7
8
|
export declare const stringifyFiltersForParams: (filters?: (string | string[])[][]) => string;
|
|
8
9
|
export declare class ERPNextResourceRequest {
|
|
9
10
|
protected temporalClient: TemporalClient;
|
|
10
11
|
constructor(temporalClient: TemporalClient);
|
|
11
12
|
private getParams;
|
|
12
|
-
getList<TFieldOptions extends
|
|
13
|
+
getList<TModel extends AnyZodObject | undefined = undefined, TFieldOptions extends GetListFieldOptions<TModel> = GetListFieldOptions<TModel>, TSelectedFields extends readonly TFieldOptions[] | readonly ["*"] | undefined = undefined, TAsDict extends boolean | undefined = undefined>({ resourceName, fields, filters, resourceModel, skip, limit, priority, asDict, params, }: {
|
|
13
14
|
resourceName: string;
|
|
14
15
|
fields?: TSelectedFields;
|
|
15
16
|
filters?: (string | string[])[][];
|
|
@@ -49,3 +50,4 @@ export declare class ERPNextResourceRequest {
|
|
|
49
50
|
priority?: number;
|
|
50
51
|
}): Promise<z.TypeOf<typeof DeleteResponseModel>>;
|
|
51
52
|
}
|
|
53
|
+
export {};
|
|
@@ -9,12 +9,20 @@ const DocTypeHelpers_1 = require("./model/DocTypeHelpers");
|
|
|
9
9
|
const ERPNextResponse_1 = require("./model/ERPNextResponse");
|
|
10
10
|
const zodContextOptionals_1 = require("../utils/zodContextOptionals");
|
|
11
11
|
const stringifyFiltersForParams = (filters) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
try {
|
|
13
|
+
return JSON.stringify(filters, (_key, value) => {
|
|
14
|
+
if (value !== null &&
|
|
15
|
+
typeof value === "object" &&
|
|
16
|
+
!Array.isArray(value)) {
|
|
17
|
+
return JSON.stringify(value).replace(/"/g, "'");
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24
|
+
throw new Error(`Failed to serialize ERPNext filters for query params: ${message}`);
|
|
25
|
+
}
|
|
18
26
|
};
|
|
19
27
|
exports.stringifyFiltersForParams = stringifyFiltersForParams;
|
|
20
28
|
class ERPNextResourceRequest {
|
|
@@ -1,24 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
3
|
const resourceRequest_1 = require("./resourceRequest");
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
describe("stringifyFiltersForParams", () => {
|
|
5
|
+
test("stringifies nested objects with single quotes", () => {
|
|
7
6
|
const filters = [
|
|
8
7
|
["status", "=", "Open"],
|
|
9
8
|
["custom", "=", { foo: "bar", count: 2 }],
|
|
10
9
|
];
|
|
11
10
|
const result = (0, resourceRequest_1.stringifyFiltersForParams)(filters);
|
|
12
|
-
|
|
11
|
+
expect(result).toBe(`[["status","=","Open"],["custom","=","{'foo':'bar','count':2}"]]`);
|
|
13
12
|
});
|
|
14
|
-
|
|
13
|
+
test("keeps array values as normal arrays", () => {
|
|
15
14
|
const filters = [
|
|
16
15
|
["name", "in", ["ITEM-0001", "ITEM-0002"]],
|
|
17
16
|
];
|
|
18
17
|
const result = (0, resourceRequest_1.stringifyFiltersForParams)(filters);
|
|
19
|
-
|
|
18
|
+
expect(result).toBe(`[["name","in",["ITEM-0001","ITEM-0002"]]]`);
|
|
20
19
|
});
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
test("escapes backslashes in filter values as valid JSON", () => {
|
|
21
|
+
const filters = [
|
|
22
|
+
["phone", "=", "+49 160\\123456"],
|
|
23
|
+
];
|
|
24
|
+
const result = (0, resourceRequest_1.stringifyFiltersForParams)(filters);
|
|
25
|
+
const decodedQueryParam = decodeURIComponent(encodeURIComponent(result));
|
|
26
|
+
expect(result).toBe(`[["phone","=","+49 160\\\\123456"]]`);
|
|
27
|
+
expect(JSON.parse(decodedQueryParam)).toEqual(filters);
|
|
28
|
+
});
|
|
29
|
+
test("adds context when filter serialization fails", () => {
|
|
30
|
+
const cyclicFilterValue = {};
|
|
31
|
+
cyclicFilterValue.self = cyclicFilterValue;
|
|
32
|
+
const filters = [
|
|
33
|
+
["custom", "=", cyclicFilterValue],
|
|
34
|
+
];
|
|
35
|
+
expect(() => (0, resourceRequest_1.stringifyFiltersForParams)(filters)).toThrow("Failed to serialize ERPNext filters for query params");
|
|
36
|
+
});
|
|
37
|
+
test("passes typed getList filters as encoded JSON query params", async () => {
|
|
38
|
+
const executeERPNextRequestWorkflow = vi.fn().mockResolvedValue({
|
|
39
|
+
data: [],
|
|
40
|
+
});
|
|
41
|
+
const resourceRequest = new resourceRequest_1.ERPNextResourceRequest({
|
|
42
|
+
executeERPNextRequestWorkflow,
|
|
43
|
+
});
|
|
44
|
+
const filters = [
|
|
45
|
+
["address_line1", "=", "Client\\Warehouse 1"],
|
|
46
|
+
["phone", "=", "0049\\1573"],
|
|
47
|
+
["Contact", "email_id", "=", "client@example.com"],
|
|
48
|
+
];
|
|
49
|
+
await resourceRequest.getList({
|
|
50
|
+
resourceName: "Address",
|
|
51
|
+
fields: ["name"],
|
|
52
|
+
filters,
|
|
53
|
+
limit: 1,
|
|
54
|
+
});
|
|
55
|
+
const options = executeERPNextRequestWorkflow.mock.calls[0]?.[1];
|
|
56
|
+
const params = new URLSearchParams(options.params.slice(1));
|
|
57
|
+
expect(params.get("filters")).toBe(JSON.stringify(filters));
|
|
58
|
+
expect(JSON.parse(params.get("filters") ?? "")).toEqual(filters);
|
|
59
|
+
});
|
|
60
|
+
test("returns undefined when filters are undefined", () => {
|
|
61
|
+
expect((0, resourceRequest_1.stringifyFiltersForParams)(undefined)).toBeUndefined();
|
|
23
62
|
});
|
|
24
63
|
});
|