@rnaga/wp-node 1.3.15 → 1.3.17

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 +1 @@
1
- {"version":3,"file":"term.crud.d.ts","sourceRoot":"","sources":["../../src/crud/term.crud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAQpC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAEvC,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,IAAI,CAAC,SAAS,MAAM,GACjE,IAAI,CAAC,OAAO,CAAC,GAAG;IACd,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,GACD;IACE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC;CAC9B,CAAC;AAEN,qBACa,QAAS,SAAQ,IAAI;IACI,OAAO,CAAC,MAAM;gBAAtC,UAAU,EAAE,UAAU,EAAU,MAAM,EAAE,MAAM;IAIpD,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EAC3C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,CAAC,CAAC;QACX,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC;KAClC,CAAC;;;;IA0CE,MAAM,CACV,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,IAAI,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;;;;YAsBW,aAAa;IAmBrB,MAAM,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;;;;;;;IAcK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,EACtC,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,MAAM,GAAE,OAAe;;;;IAUnB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY;;;;IAcvD,UAAU;;;;;;;;IA8BV,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EAC5C,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EACvD,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,CAAA;KAAE;;;;;;;;;;;;CAgK5B"}
1
+ {"version":3,"file":"term.crud.d.ts","sourceRoot":"","sources":["../../src/crud/term.crud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAQpC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAEvC,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,IAAI,CAAC,SAAS,MAAM,GACjE,IAAI,CAAC,OAAO,CAAC,GAAG;IAChB,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,GACC;IACA,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC;CAC9B,CAAC;AAEJ,qBACa,QAAS,SAAQ,IAAI;IACI,OAAO,CAAC,MAAM;gBAAtC,UAAU,EAAE,UAAU,EAAU,MAAM,EAAE,MAAM;IAIpD,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EAC3C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,CAAC,CAAC;QACX,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC;KAClC,CAAC;;;;IA0CE,MAAM,CACV,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,IAAI,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;;;;YAsBW,aAAa;IAmBrB,MAAM,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;;;;;;;IAcK,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,EACtC,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,MAAM,GAAE,OAAe;;;;IAUnB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY;;;;IAcvD,UAAU;;;;;;;;IA8BV,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EAC5C,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EACvD,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,CAAA;KAAE;;;;;;;;;;;;CAgK5B"}
package/crud/term.crud.js CHANGED
@@ -215,8 +215,8 @@ let TermCrud = class TermCrud extends crud_1.Crud {
215
215
  if (Array.isArray(parsedArgs.exclude)) {
216
216
  query.andWhereNot((query) => query.whereIn("term_id", parsedArgs.exclude));
217
217
  }
218
- if (parsedArgs.slug) {
219
- query.where("slug", parsedArgs.slug);
218
+ if (Array.isArray(parsedArgs.slug)) {
219
+ query.whereIn("slug", parsedArgs.slug);
220
220
  }
221
221
  if (parsedArgs.hide_empty) {
222
222
  query.where("count", 0, ">");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rnaga/wp-node",
3
- "version": "1.3.15",
3
+ "version": "1.3.17",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "build": "rm -rf ./dist && tsc --project tsconfig.build.json && npm run copyfiles && cp package.json ./dist/",
@@ -43,6 +43,14 @@ export declare class PostTrx extends Trx {
43
43
  syncAttachedFile(postId: number, file: string): Promise<void>;
44
44
  syncCategories(postId: number, namesOrTermIds: (string | number)[], append?: boolean): Promise<number[] | undefined>;
45
45
  syncTerms(postId: number, slugsOrTermIds: (string | number)[], taxonomyName?: types.TaxonomyName, append?: boolean): Promise<number[] | undefined>;
46
+ updateMenuOrder(postId: number, menuOrder: number, options?: {
47
+ checkParent?: boolean;
48
+ reOrder?: boolean;
49
+ }): Promise<boolean>;
50
+ swapMenuOrder(postId1: number, postId2: number, options?: {
51
+ reOrderOnEqual?: boolean;
52
+ checkParent?: boolean;
53
+ }): Promise<boolean>;
46
54
  }
47
55
  export {};
48
56
  //# sourceMappingURL=post.trx.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"post.trx.d.ts","sourceRoot":"","sources":["../../src/transactions/post.trx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,QAAQ,MAAM,aAAa,CAAC;AAEnC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AAMrC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,KAAK,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAwBrD,qBACa,OAAQ,SAAQ,GAAG;IAE5B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;gBANX,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW;IAM5B,WAAW;IAcX,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAoBjD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;IA+bjC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAsIpC,gBAAgB,CACpB,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,EAC1B,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAcG,sBAAsB,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EACA;QACE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,KAAK,CAAC;KAChB,GACD;QACE,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,IAAI,CAAC;KACd;IAmBD,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAiH9C,OAAO,CAAC,MAAM,EAAE,MAAM;IA2CtB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IA0D3C,KAAK,CAAC,MAAM,EAAE,MAAM;IA6CpB,aAAa,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM;IAoErC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAwB7C,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACnC,MAAM,UAAQ;IAuBV,SAAS,CACb,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACnC,YAAY,GAAE,KAAK,CAAC,YAAyB,EAC7C,MAAM,UAAQ;CA0BjB"}
1
+ {"version":3,"file":"post.trx.d.ts","sourceRoot":"","sources":["../../src/transactions/post.trx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,QAAQ,MAAM,aAAa,CAAC;AAEnC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AAMrC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,KAAK,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAwBrD,qBACa,OAAQ,SAAQ,GAAG;IAE5B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;gBANX,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW;IAM5B,WAAW;IAcX,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAoBjD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC;IA+bjC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAsIpC,gBAAgB,CACpB,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,EAC1B,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAcG,sBAAsB,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EACA;QACA,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,KAAK,CAAC;KAChB,GACC;QACA,IAAI,CAAC,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,IAAI,CAAC;KACd;IAmBC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAiH9C,OAAO,CAAC,MAAM,EAAE,MAAM;IA2CtB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IA0D3C,KAAK,CAAC,MAAM,EAAE,MAAM;IA6CpB,aAAa,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM;IAoErC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAwB7C,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACnC,MAAM,UAAQ;IAuBV,SAAS,CACb,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACnC,YAAY,GAAE,KAAK,CAAC,YAAyB,EAC7C,MAAM,UAAQ;IAkCV,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QACjE,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB;IA+GK,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAC9D,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB;CAwFF"}
@@ -889,6 +889,192 @@ let PostTrx = class PostTrx extends trx_1.Trx {
889
889
  const termTrx = this.components.get(term_trx_1.TermTrx);
890
890
  return await termTrx.syncObject(postId, slugsOrTermIds, taxonomyName, append);
891
891
  }
892
+ // Updates a post's menu_order and (when reOrder=true) keeps sibling order consistent:
893
+ // - Collision at target: shifts posts at >= target up by 1 to open a slot.
894
+ // For backward moves, only posts between new and old positions are shifted.
895
+ // - Forward move (oldMenuOrder > 0): posts strictly between old and new slide down by 1
896
+ // to fill the vacated slot.
897
+ // - No collision and no forward move: only the post itself is updated.
898
+ // checkParent=true (default) scopes all sibling queries to posts with the same post_parent.
899
+ async updateMenuOrder(postId, menuOrder, options) {
900
+ const { checkParent = true, reOrder = true } = options ?? {};
901
+ const post = await this.postUtil.get(postId);
902
+ if (!post.props) {
903
+ throw new Error(`Post not found - ${postId}`);
904
+ }
905
+ if (!reOrder) {
906
+ const trx = await this.database.transaction;
907
+ try {
908
+ await trx
909
+ .table(this.tables.get("posts"))
910
+ .where("ID", postId)
911
+ .update({ menu_order: menuOrder });
912
+ }
913
+ catch (e) {
914
+ await trx.rollback();
915
+ throw new Error(`Failed to update menu_order of post ${postId} - ${e}`);
916
+ }
917
+ await trx.commit();
918
+ return true;
919
+ }
920
+ const oldMenuOrder = post.props.menu_order;
921
+ // Step 1: If the post was already in the ordered list and is moving forward,
922
+ // decrement posts strictly between the old and new positions to fill the vacated slot.
923
+ if (oldMenuOrder > 0 && oldMenuOrder < menuOrder) {
924
+ const trx = await this.database.transaction;
925
+ try {
926
+ const query = trx
927
+ .table(this.tables.get("posts"))
928
+ .where("post_type", post.props.post_type)
929
+ .where("menu_order", ">", oldMenuOrder)
930
+ .where("menu_order", "<", menuOrder)
931
+ .whereNot("ID", postId);
932
+ if (checkParent) {
933
+ query.where("post_parent", post.props.post_parent);
934
+ }
935
+ await query.update({ menu_order: trx.raw("?? - 1", ["menu_order"]) });
936
+ }
937
+ catch (e) {
938
+ await trx.rollback();
939
+ throw new Error(`Failed to decrement menu_order for post ${postId} - ${e}`);
940
+ }
941
+ await trx.commit();
942
+ }
943
+ // Step 2: If a post already occupies the target menu_order (collision), shift posts
944
+ // at and above the target position up by 1 to open a slot.
945
+ // For a backward move, only shift posts below the old position to avoid double-counting.
946
+ const queryUtil = this.components.get(query_util_1.QueryUtil);
947
+ const collisionPosts = await queryUtil.posts((query) => {
948
+ query
949
+ .where("post_type", post.props.post_type)
950
+ .where("menu_order", menuOrder)
951
+ .where("ID", postId, "!=");
952
+ if (checkParent) {
953
+ query.where("post_parent", post.props.post_parent);
954
+ }
955
+ });
956
+ const hasCollision = !!collisionPosts && collisionPosts.length > 0;
957
+ if (hasCollision) {
958
+ const trx = await this.database.transaction;
959
+ try {
960
+ const query = trx
961
+ .table(this.tables.get("posts"))
962
+ .where("post_type", post.props.post_type)
963
+ .where("menu_order", ">=", menuOrder)
964
+ .whereNot("ID", postId);
965
+ if (oldMenuOrder > menuOrder) {
966
+ query.where("menu_order", "<", oldMenuOrder);
967
+ }
968
+ if (checkParent) {
969
+ query.where("post_parent", post.props.post_parent);
970
+ }
971
+ await query.update({ menu_order: trx.raw("?? + 1", ["menu_order"]) });
972
+ }
973
+ catch (e) {
974
+ await trx.rollback();
975
+ throw new Error(`Failed to increment menu_order for post ${postId} - ${e}`);
976
+ }
977
+ await trx.commit();
978
+ }
979
+ // Step 3: Set the post's own menu_order.
980
+ const trxUpdate = await this.database.transaction;
981
+ try {
982
+ await trxUpdate
983
+ .table(this.tables.get("posts"))
984
+ .where("ID", postId)
985
+ .update({ menu_order: menuOrder });
986
+ }
987
+ catch (e) {
988
+ await trxUpdate.rollback();
989
+ throw new Error(`Failed to update menu_order of post ${postId} - ${e}`);
990
+ }
991
+ await trxUpdate.commit();
992
+ return true;
993
+ }
994
+ // Note: menu order of post1 should be smaller than or equal to post2 before swapping, otherwise throws.
995
+ // Performance note: not suitable for high-frequency or bulk use.
996
+ // - Fetches both posts individually before writing (2 extra DB reads per call).
997
+ // - Uses 2 separate transactions instead of one, creating a TOCTOU window
998
+ // where concurrent writes between the reads and updates can cause inconsistency.
999
+ async swapMenuOrder(postId1, postId2, options) {
1000
+ const { reOrderOnEqual = true, checkParent = true } = options ?? {};
1001
+ const post1 = await this.postUtil.get(postId1);
1002
+ const post2 = await this.postUtil.get(postId2);
1003
+ if (!post1.props || !post2.props) {
1004
+ throw new Error(`Posts not found - ${postId1}, ${postId2}`);
1005
+ }
1006
+ if (post1.props.post_type !== post2.props.post_type) {
1007
+ throw new Error(`Posts should have the same post type - ${postId1}, ${postId2}`);
1008
+ }
1009
+ if (checkParent && post1.props.post_parent !== post2.props.post_parent) {
1010
+ throw new Error(`Posts should have the same parent - ${postId1}, ${postId2}`);
1011
+ }
1012
+ if (post1.props.menu_order > post2.props.menu_order) {
1013
+ throw new Error(`Menu order of post ${postId1} should be smaller than post ${postId2} before swapping`);
1014
+ }
1015
+ const menuOrder1 = post1.props.menu_order;
1016
+ const menuOrder2 = post2.props.menu_order;
1017
+ // Update menu order of post1.
1018
+ let trx = await this.database.transaction;
1019
+ try {
1020
+ await trx
1021
+ .table(this.tables.get("posts"))
1022
+ .where("ID", postId1)
1023
+ .update({
1024
+ menu_order: menuOrder2,
1025
+ });
1026
+ }
1027
+ catch (e) {
1028
+ await trx.rollback();
1029
+ throw new Error(`Failed to update menu order of post ${postId1} - ${e}`);
1030
+ }
1031
+ await trx.commit();
1032
+ // Update menu order of post2.
1033
+ // If menu order of post1 and post2 are the same or true on reOrderOnEqual.
1034
+ // 1. menu order of post2 should be increased by 1.
1035
+ // 2. then the rest of posts with the same parent_post and menu order that's same or larger than menu order of post2 (&post1) should be increased by 1
1036
+ if (!reOrderOnEqual || menuOrder1 !== menuOrder2) {
1037
+ // If menu order of post1 and post2 are different, just swap them.
1038
+ const trx = await this.database.transaction;
1039
+ try {
1040
+ await trx
1041
+ .table(this.tables.get("posts"))
1042
+ .where("ID", postId2)
1043
+ .update({
1044
+ menu_order: menuOrder1,
1045
+ });
1046
+ }
1047
+ catch (e) {
1048
+ await trx.rollback();
1049
+ throw new Error(`Failed to update menu order of post ${postId2} - ${e}`);
1050
+ }
1051
+ await trx.commit();
1052
+ return true;
1053
+ }
1054
+ // If menu order of post1 and post2 are the same, increment menu_order for post2 and all
1055
+ // other posts sharing the same parent/type whose menu_order >= menuOrder2 (excluding post1,
1056
+ // which was already updated above). post2 is included because its menu_order === menuOrder2.
1057
+ const trxRest = await this.database.transaction;
1058
+ try {
1059
+ const query = trxRest
1060
+ .table(this.tables.get("posts"))
1061
+ .where("post_type", post1.props.post_type)
1062
+ .where("menu_order", ">=", menuOrder2)
1063
+ .whereNot("ID", postId1);
1064
+ if (checkParent) {
1065
+ query.where("post_parent", post1.props.post_parent);
1066
+ }
1067
+ await query.update({
1068
+ menu_order: trxRest.raw("?? + 1", ["menu_order"]),
1069
+ });
1070
+ }
1071
+ catch (e) {
1072
+ await trxRest.rollback();
1073
+ throw new Error(`Failed to update menu order of posts with the same parent and menu order that's same or larger than menu order of post ${postId2} - ${e}`);
1074
+ }
1075
+ await trxRest.commit();
1076
+ return true;
1077
+ }
892
1078
  };
893
1079
  exports.PostTrx = PostTrx;
894
1080
  exports.PostTrx = PostTrx = __decorate([