erpnext-queue-client 2.4.5 → 2.5.1

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 (35) hide show
  1. package/dist/client.js +7 -1
  2. package/dist/erpnext/doctypeResourceRequest.d.ts +12 -1
  3. package/dist/erpnext/doctypeResourceRequest.js +3 -3
  4. package/dist/erpnext/doctypes/address.d.ts +3 -233
  5. package/dist/erpnext/doctypes/address.js +5 -16
  6. package/dist/erpnext/doctypes/consolidatedCustomsInvoice.d.ts +3 -486
  7. package/dist/erpnext/doctypes/consolidatedCustomsInvoice.js +4 -18
  8. package/dist/erpnext/doctypes/contact.d.ts +3 -358
  9. package/dist/erpnext/doctypes/contact.js +6 -17
  10. package/dist/erpnext/doctypes/deliveryNote.d.ts +1 -1575
  11. package/dist/erpnext/doctypes/deliveryNote.js +2 -19
  12. package/dist/erpnext/doctypes/item.d.ts +1 -1019
  13. package/dist/erpnext/doctypes/item.js +3 -16
  14. package/dist/erpnext/doctypes/paymentEntry.d.ts +1 -728
  15. package/dist/erpnext/doctypes/paymentEntry.js +4 -21
  16. package/dist/erpnext/doctypes/productBundle.d.ts +1 -143
  17. package/dist/erpnext/doctypes/productBundle.js +2 -13
  18. package/dist/erpnext/doctypes/purchaseInvoice.d.ts +1 -1395
  19. package/dist/erpnext/doctypes/purchaseInvoice.js +4 -19
  20. package/dist/erpnext/doctypes/purchaseReceipt.d.ts +1 -1204
  21. package/dist/erpnext/doctypes/purchaseReceipt.js +4 -19
  22. package/dist/erpnext/doctypes/salesInvoice.d.ts +1 -2517
  23. package/dist/erpnext/doctypes/salesInvoice.js +4 -21
  24. package/dist/erpnext/doctypes/servicecase.d.ts +24 -425
  25. package/dist/erpnext/doctypes/servicecase.js +14 -15
  26. package/dist/erpnext/doctypes/shipment.d.ts +1 -758
  27. package/dist/erpnext/doctypes/shipment.js +3 -20
  28. package/dist/erpnext/item.getList.alias-parsing.test.d.ts +1 -0
  29. package/dist/erpnext/item.getList.alias-parsing.test.js +66 -0
  30. package/dist/erpnext/methodRequest.js +0 -2
  31. package/dist/erpnext/resourceRequest.js +1 -9
  32. package/dist/index.test.js +3 -2
  33. package/dist/utils/zodUtils.d.ts +1 -1
  34. package/dist/utils/zodUtils.js +35 -24
  35. package/package.json +1 -1
@@ -5,28 +5,11 @@ const doctypeSubmittableResourceRequest_1 = require("../doctypeSubmittableResour
5
5
  const methodRequest_1 = require("../methodRequest");
6
6
  const Shipment_1 = require("../model/Shipment");
7
7
  const zodContextOptionals_1 = require("../../utils/zodContextOptionals");
8
- class ERPNextShipment {
9
- temporalClient;
10
- baseRequest;
8
+ class ERPNextShipment extends doctypeSubmittableResourceRequest_1.ERPNextDoctypeSubmittableResourceRequest {
11
9
  methodRequest;
12
- getList;
13
- getById;
14
- updateById;
15
- deleteById;
16
- create;
17
- cancel;
18
- submit;
19
10
  constructor(temporalClient) {
20
- this.temporalClient = temporalClient;
21
- this.baseRequest = new doctypeSubmittableResourceRequest_1.ERPNextDoctypeSubmittableResourceRequest(temporalClient, "Shipment", Shipment_1.Shipment);
11
+ super(temporalClient, "Shipment", Shipment_1.Shipment);
22
12
  this.methodRequest = new methodRequest_1.ERPNextMethodRequest(temporalClient);
23
- this.getList = this.baseRequest.getList;
24
- this.getById = this.baseRequest.getById;
25
- this.updateById = this.baseRequest.updateById;
26
- this.deleteById = this.baseRequest.deleteById;
27
- this.create = this.baseRequest.create;
28
- this.cancel = this.baseRequest.cancel;
29
- this.submit = this.baseRequest.submit;
30
13
  }
31
14
  async createShipmentDraft(deliveryNoteName) {
32
15
  const draft = await this.methodRequest.request({
@@ -47,7 +30,7 @@ class ERPNextShipment {
47
30
  return shipmentInfo;
48
31
  }
49
32
  async addShippingLabelAndSubmit(shipmentErpNextName, body) {
50
- const shipment = await this.baseRequest.updateById({
33
+ const shipment = await this.updateById({
51
34
  resourceId: shipmentErpNextName,
52
35
  inputValidationModel: Shipment_1.ShipmentAddShippingLabelAndSubmitBody,
53
36
  body,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const item_1 = require("./doctypes/item");
4
+ const zod_1 = require("zod");
5
+ const zodUtils_1 = require("../utils/zodUtils");
6
+ describe("Item.getList field alias parsing", () => {
7
+ test("does not treat field names containing 'as' as aliases", async () => {
8
+ const temporalClientStub = {
9
+ executeERPNextRequestWorkflow: async (_requestName, options) => {
10
+ const { responseValidationModel } = options;
11
+ if (!responseValidationModel) {
12
+ throw new Error("Missing responseValidationModel in stub options");
13
+ }
14
+ // Intentionally omit the wrongly-selected key "undefined" that results from
15
+ // the buggy alias parsing logic in pickFromSchema.
16
+ const data = {
17
+ data: [
18
+ {
19
+ name: "ITEM-0001",
20
+ item_code: "ITEM-0001",
21
+ item_name: "Test Item",
22
+ ean: "EAN-1",
23
+ disabled: 0,
24
+ has_variants: 1,
25
+ is_purchase_item: 1,
26
+ is_stock_item: 1,
27
+ custom_product_version: "v1",
28
+ custom_supplier: "SUP-1",
29
+ },
30
+ ],
31
+ };
32
+ return (0, zodUtils_1.validateData)(data, responseValidationModel);
33
+ },
34
+ };
35
+ const itemApi = new item_1.ERPNextItem(temporalClientStub);
36
+ const fields = [
37
+ "name",
38
+ "item_code",
39
+ "item_name",
40
+ "ean",
41
+ "disabled",
42
+ "has_variants",
43
+ "is_purchase_item",
44
+ "is_stock_item",
45
+ "custom_product_version",
46
+ "custom_supplier",
47
+ ];
48
+ const result = await itemApi.getList({
49
+ fields: fields,
50
+ limit: 1,
51
+ });
52
+ expect(result).toHaveLength(1);
53
+ expect(result.at(0)?.name).toBeTypeOf("string");
54
+ expect(result.at(0)?.has_variants).toBeTypeOf("number");
55
+ expect(result.at(0)?.is_purchase_item).toBeTypeOf("number");
56
+ expect(result.at(0)?.custom_product_version).toBeTypeOf("string");
57
+ });
58
+ test("supports uppercase AS delimiter in alias expressions", () => {
59
+ const schema = zod_1.z.object({
60
+ "item_name AS item_title": zod_1.z.string(),
61
+ });
62
+ const picked = (0, zodUtils_1.pickFromSchema)(schema, ["item_name AS item_title"]);
63
+ const parsed = picked.parse({ item_title: "x" });
64
+ expect(parsed.item_title).toBe("x");
65
+ });
66
+ });
@@ -10,8 +10,6 @@ class ERPNextMethodRequest {
10
10
  this.temporalClient = temporalClient;
11
11
  }
12
12
  async request({ methodName, requestMethod, body, inputValidationModel, responseValidationModel, isAutoWrapResponseValidationWithMessage = true, params, priority = 5, }) {
13
- if (responseValidationModel && !responseValidationModel.description)
14
- throw new Error("Resource model must have a description");
15
13
  const result = await this.temporalClient.executeERPNextRequestWorkflow(`${requestMethod}-${methodName}`, {
16
14
  methodName,
17
15
  requestMethod,
@@ -34,8 +34,6 @@ class ERPNextResourceRequest {
34
34
  return allParams;
35
35
  };
36
36
  async getList({ resourceName, fields, filters, resourceModel, skip, limit, priority = 5, asDict, params, }) {
37
- if (resourceModel && !resourceModel.description)
38
- throw new Error("Resource model must have a description");
39
37
  const erpNextFields = fields?.length
40
38
  ? fields
41
39
  : ["name"]; // default field is name
@@ -57,7 +55,7 @@ class ERPNextResourceRequest {
57
55
  data: zod_1.z.array((0, zodUtils_1.pickFromSchema)((0, DocTypeHelpers_1.DocModelListEntry)(resourceModel), erpNextFields.filter((f) => f !== "*") // filter out * when other fields are present
58
56
  )),
59
57
  })
60
- .describe(`${resourceModel.description} List with fields ${JSON.stringify(erpNextFields.filter((f) => f !== "*"))}`)
58
+ .describe(`${resourceName} List with fields ${JSON.stringify(erpNextFields.filter((f) => f !== "*"))}`)
61
59
  : zod_1.z.any().describe("Any response");
62
60
  const defaultPaginationSize = 500;
63
61
  let loopLimit = defaultPaginationSize;
@@ -92,8 +90,6 @@ class ERPNextResourceRequest {
92
90
  return results;
93
91
  }
94
92
  async getById({ resourceName, resourceId, resourceModel, priority = 5, }) {
95
- if (resourceModel && !resourceModel.description)
96
- throw new Error("Resource model must have a description");
97
93
  if (!resourceId)
98
94
  throw new Error("Resource id is required");
99
95
  const result = await this.temporalClient
@@ -134,8 +130,6 @@ class ERPNextResourceRequest {
134
130
  return result.data;
135
131
  }
136
132
  async create({ resourceName, inputValidationModel, resourceModel, body, params, priority = 5, }) {
137
- if (resourceModel && !resourceModel.description)
138
- throw new Error("Resource model must have a description");
139
133
  const result = await this.temporalClient.executeERPNextRequestWorkflow(`POST-${resourceName}`, {
140
134
  requestMethod: "POST",
141
135
  resourceName,
@@ -154,8 +148,6 @@ class ERPNextResourceRequest {
154
148
  return result.data;
155
149
  }
156
150
  async deleteById({ resourceName, resourceId, resourceModel, priority = 5, }) {
157
- if (resourceModel && !resourceModel.description)
158
- throw new Error("Resource model must have a description");
159
151
  return await this.temporalClient.executeERPNextRequestWorkflow(`DELETE-${resourceName}`, {
160
152
  requestMethod: "DELETE",
161
153
  resourceName,
@@ -113,8 +113,9 @@ describe.skipIf(constants_1.constants.TEMPORAL_HOST === "test")("Type tests", as
113
113
  });
114
114
  test("Item List with invalid field list", async () => {
115
115
  // don't execute, this is just for type testing statically
116
- () => erp.item.getList({
117
- // @ts-expect-error
116
+ () =>
117
+ // @ts-expect-error barcode is not a valid Item list field
118
+ erp.item.getList({
118
119
  fields: ["name", "barcode"],
119
120
  limit: 10,
120
121
  });
@@ -1,4 +1,4 @@
1
1
  import { z, ZodObject, ZodRawShape } from "zod";
2
- export declare function validateData<T extends z.ZodTypeAny>(data: unknown, ValidationModel: T): z.infer<T>;
2
+ export declare function validateData<T extends z.ZodTypeAny>(data: unknown, ValidationModel: T, isDebug?: boolean): z.infer<T>;
3
3
  export declare function pickFromSchema<T extends ZodRawShape, K extends keyof T>(schema: ZodObject<T>, keys: readonly K[]): ZodObject<Pick<T, K>>;
4
4
  export type KeysOf<T> = T extends ZodObject<any> ? keyof z.infer<T> : string;
@@ -4,48 +4,59 @@ exports.validateData = validateData;
4
4
  exports.pickFromSchema = pickFromSchema;
5
5
  const zod_1 = require("zod");
6
6
  const constants_1 = require("../constants");
7
- const logger_1 = require("./logger");
8
- function validateData(data, ValidationModel) {
7
+ function validateData(data, ValidationModel, isDebug) {
9
8
  if (!ValidationModel.description)
10
9
  throw new Error("ValidationModel.description is required");
11
10
  // writeFileSync("test.json", JSON.stringify(data, null, 2));
12
11
  if (!(ValidationModel instanceof zod_1.ZodObject) &&
13
12
  !(ValidationModel instanceof zod_1.ZodArray)) {
14
- console.log(ValidationModel);
15
13
  throw new Error("Invalid Zod Model");
16
14
  }
17
15
  const validationResult = ValidationModel.safeParse(data);
18
16
  if (!validationResult.success) {
19
- const errorObject = {
20
- message: `Validation error in model ${ValidationModel.description}`,
21
- error: validationResult.error,
22
- input: constants_1.constants.DEBUG_MODE === "true"
23
- ? data
24
- : "set DEBUG_MODE to true to see the input",
25
- };
26
- logger_1.lg.error(errorObject);
27
- if (data &&
28
- typeof data === "object" &&
29
- "message" in data &&
30
- typeof data.message === "string") {
31
- throw new Error(data.message);
32
- }
33
- throw new Error(errorObject.message, { cause: errorObject.error });
17
+ const isDebugSet = constants_1.constants.DEBUG_MODE === "true" || isDebug;
18
+ // ZodError.issues contains the most actionable information; render a readable list.
19
+ const issues = validationResult.error.issues;
20
+ const issueStrings = issues.map((issue) => {
21
+ const path = issue.path.length ? issue.path.join(".") : "(root)";
22
+ return `"${path}": ${issue.message}`;
23
+ });
24
+ const previewCount = 8;
25
+ const previewLines = "\n──────────────\n\n" +
26
+ issueStrings.slice(0, previewCount).join("\n") +
27
+ "\n\n──────────────\n";
28
+ const moreCount = Math.max(0, issueStrings.length - previewCount);
29
+ const moreSuffix = moreCount > 0 ? `\n- (+${moreCount} more)` : "";
30
+ const cleanMessage = `Validation failed for ${ValidationModel.description}\n${previewLines}${moreSuffix}`;
31
+ // Include the full error as a `cause` only when debugging; otherwise keep stack output clean.
32
+ if (isDebugSet)
33
+ console.dir(data, { depth: null });
34
+ const error = new Error(cleanMessage + "\n" + validationResult.error.toString());
35
+ delete error.stack;
36
+ throw error;
34
37
  }
35
38
  return validationResult.data;
36
39
  }
37
40
  function pickFromSchema(schema, keys) {
38
41
  const pickedShape = keys?.reduce((acc, key) => {
39
- if (typeof key === "string" && key.includes("as")) {
40
- const [field, alias] = key.split(" as ");
41
- if (key in schema.shape) {
42
- acc[alias] = schema.shape[key];
42
+ // ERPNext alias fields use: `<field> as <alias>` (case-insensitive).
43
+ // Don't treat substring matches like `has_variants` as aliases.
44
+ if (typeof key === "string") {
45
+ const match = key.match(/^(.*?)\s+as\s+(.*?)$/i);
46
+ if (match) {
47
+ const alias = match[2].trim();
48
+ if (key in schema.shape) {
49
+ acc[alias] = schema.shape[key];
50
+ }
51
+ return acc;
43
52
  }
53
+ // Not an alias expression, treat it as a direct field key.
54
+ if (key in schema.shape)
55
+ acc[key] = schema.shape[key];
44
56
  }
45
57
  else {
46
- if (key in schema.shape) {
58
+ if (key in schema.shape)
47
59
  acc[key] = schema.shape[key];
48
- }
49
60
  }
50
61
  return acc;
51
62
  }, {});
package/package.json CHANGED
@@ -30,7 +30,7 @@
30
30
  "winston": "^3.15.0",
31
31
  "zod": "3.25.76"
32
32
  },
33
- "version": "2.4.5",
33
+ "version": "2.5.1",
34
34
  "devDependencies": {
35
35
  "@types/crypto-js": "^4.2.2",
36
36
  "@types/lodash": "^4.17.13",