@shushed/helpers 0.0.37 → 0.0.38

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/index.d.ts CHANGED
@@ -28794,6 +28794,7 @@ declare class PubSubHelper extends Runtime {
28794
28794
  private findTopic;
28795
28795
  private ensureTopicExists;
28796
28796
  private getNameFromFullyQualifiedName;
28797
+ private updateSubscription;
28797
28798
  private ensureSubscribtionExists;
28798
28799
  private ensureDLQSubscriptionExists;
28799
28800
  deleteSubscription(subscriptionURN: string): Promise<any>;
package/dist/index.js CHANGED
@@ -678,9 +678,13 @@ var env_default = EnvEngine;
678
678
 
679
679
  // src-public/pubsub.ts
680
680
  var import_co_body = __toESM(require("co-body"));
681
- var import_lodash = __toESM(require("lodash.omit"));
681
+ var import_lodash = __toESM(require("lodash.isequal"));
682
+ var import_lodash2 = __toESM(require("lodash.omit"));
683
+ function isSubscriptionOptionsPull(opts) {
684
+ return "endpointUrl" in opts && opts.endpoinrtUrl === null;
685
+ }
682
686
  function isSubscriptionOptionsPush(opts) {
683
- return "endpointUrl" in opts;
687
+ return "endpointUrl" in opts && opts.endpoinrtUrl !== null;
684
688
  }
685
689
  var PubSubHelper = class extends Runtime {
686
690
  constructor(opts, pubSub) {
@@ -708,7 +712,7 @@ var PubSubHelper = class extends Runtime {
708
712
  publishTime: parseDateOrDefault(rawMessage.publish_time),
709
713
  body: messageBody,
710
714
  exportableToBigQuery: !!rawMessage.attributes?.bigquery,
711
- extraAttributes: (0, import_lodash.default)(rawMessage.attributes || {}, ["source_system", "target_system", "process_started_at", "record_modified_at", "original_publish_time", "buildship_id", "publish_time", "bigquery"])
715
+ extraAttributes: (0, import_lodash2.default)(rawMessage.attributes || {}, ["source_system", "target_system", "process_started_at", "record_modified_at", "original_publish_time", "buildship_id", "publish_time", "bigquery"])
712
716
  };
713
717
  return message;
714
718
  }
@@ -730,7 +734,7 @@ var PubSubHelper = class extends Runtime {
730
734
  const normPayload = normPayloads[i];
731
735
  promises.push((async () => {
732
736
  const attributes = {
733
- ...(0, import_lodash.default)(options.extraAttributes || {}, ["source_system", "target_system", "process_started_at", "record_modified_at", "original_publish_time", "buildship_id", "publish_time", "bigquery"]),
737
+ ...(0, import_lodash2.default)(options.extraAttributes || {}, ["source_system", "target_system", "process_started_at", "record_modified_at", "original_publish_time", "buildship_id", "publish_time", "bigquery"]),
734
738
  source_system: options.sourceSystem,
735
739
  target_system: options.targetSystem || orgMessage?.targetSystem || "*",
736
740
  process_started_at: (options.processStartedAt || orgMessage?.processStartedAt || /* @__PURE__ */ new Date()).toISOString(),
@@ -768,12 +772,20 @@ var PubSubHelper = class extends Runtime {
768
772
  let bqSubscription = null;
769
773
  if (opts.bigQueryTableId) {
770
774
  const bigQuerySubscriptionName = `${subscriptionName}-bq`;
775
+ const bigQueryDlqTopicName = `${opts.topicName}-bq-dlq`;
776
+ const bigQueryDlqSubscriptionName = `${subscriptionName}-bq-dlq`;
777
+ dlqTopic = await this.ensureTopicExists(bigQueryDlqTopicName);
778
+ dlqSubscription = await this.ensureDLQSubscriptionExists(bigQueryDlqSubscriptionName, {
779
+ topic: dlqTopic
780
+ });
771
781
  bqSubscription = await this.ensureSubscribtionExists(bigQuerySubscriptionName, {
772
782
  topic,
773
- tableId: opts.bigQueryTableId
783
+ tableId: opts.bigQueryTableId,
784
+ dlqTopic
774
785
  });
775
786
  } else {
776
787
  await this.deleteSubscription(`${subscriptionName}-bq`);
788
+ await this.deleteSubscription(`${subscriptionName}-bq-dlq`);
777
789
  }
778
790
  const subscription = await this.ensureSubscribtionExists(subscriptionName, {
779
791
  topic,
@@ -798,8 +810,46 @@ var PubSubHelper = class extends Runtime {
798
810
  }
799
811
  async ensureTopicExists(topicName) {
800
812
  let topic = await this.findTopic(topicName);
801
- if (!topic) {
802
- await this.pubSub.createTopic(topicName);
813
+ const metadata = {
814
+ labels: {
815
+ "created-at": (/* @__PURE__ */ new Date()).toISOString(),
816
+ "last-modified-at": (/* @__PURE__ */ new Date()).toISOString(),
817
+ "created-by-bs-triggerid": this.triggerId,
818
+ "created-by-bs-workflowid": this.workflowId,
819
+ "bs-envname": this.systemEnvName,
820
+ "env": this.envName,
821
+ "used-by": ""
822
+ }
823
+ };
824
+ const [topicMetadata] = await topic?.getMetadata() || [null];
825
+ const currentUsedBy = (topicMetadata?.labels?.["used-by"] || "").split(",").map((x) => x.split(":").slice(0, 2)).reduce((acc, [wid, envName]) => {
826
+ acc[wid] = acc[wid] || [];
827
+ acc[wid].push(`${envName}---${this.triggerId}`);
828
+ return acc;
829
+ }, {});
830
+ if (currentUsedBy[this.workflowId] && currentUsedBy[this.workflowId].indexOf(`${this.systemEnvName}---${this.triggerId}`) !== -1) {
831
+ currentUsedBy[this.workflowId].push(`${this.systemEnvName}---${this.triggerId}`);
832
+ }
833
+ if (topic) {
834
+ const currentUsedByString = Object.entries(currentUsedBy).reduce((acc, [wid, x]) => {
835
+ x.forEach((y) => {
836
+ acc.push(wid + ":" + y);
837
+ });
838
+ return acc;
839
+ }, []).join(",");
840
+ metadata.labels["used-by"] = currentUsedByString;
841
+ const simMetadata = Object.assign({}, topicMetadata?.labels || {}, metadata.labels);
842
+ if (!(0, import_lodash.default)(topicMetadata?.labels, simMetadata)) {
843
+ simMetadata["last-modified-at"] = (/* @__PURE__ */ new Date()).toISOString();
844
+ await topic.setMetadata({
845
+ labels: simMetadata
846
+ });
847
+ }
848
+ } else {
849
+ await this.pubSub.createTopic({
850
+ name: topicName,
851
+ labels: metadata.labels
852
+ });
803
853
  topic = await this.findTopic(topicName);
804
854
  }
805
855
  if (!topic) {
@@ -811,67 +861,119 @@ var PubSubHelper = class extends Runtime {
811
861
  const name = fullyQName.split("/");
812
862
  return name[name.length - 1];
813
863
  }
814
- async ensureSubscribtionExists(subscriptionName, opts) {
815
- let [subscriptions] = await opts.topic.getSubscriptions();
816
- let subscription = subscriptions.find((subscription2) => this.getNameFromFullyQualifiedName(subscription2.name) === subscriptionName);
817
- let endpointHasChanged = false;
818
- let retryLimitHasChanged = false;
819
- let ackDeadlineHasChanged = false;
820
- let retryDelayHasChanged = false;
821
- let shouldRecreate = false;
822
- let dlqHasChanged = false;
823
- let tableIdHasChanged = false;
824
- if (subscription) {
825
- const [subscriptionMetaData] = await subscription.getMetadata();
826
- if (!isSubscriptionOptionsPush(opts)) {
827
- tableIdHasChanged = (subscriptionMetaData.bigqueryConfig?.table || null) !== (opts.tableId || null);
828
- } else {
829
- endpointHasChanged = subscriptionMetaData.pushConfig?.pushEndpoint != opts.endpointUrl;
830
- dlqHasChanged = !subscriptionMetaData.deadLetterPolicy && !!opts.dlqTopic || !!subscriptionMetaData.deadLetterPolicy?.deadLetterTopic && !opts.dlqTopic;
831
- retryDelayHasChanged = subscriptionMetaData.retryPolicy?.minimumBackoff?.seconds != opts.retryMinDelay;
832
- retryLimitHasChanged = subscriptionMetaData.deadLetterPolicy?.maxDeliveryAttempts != opts.retryLimit;
833
- ackDeadlineHasChanged = subscriptionMetaData.ackDeadlineSeconds !== (opts.ackDeadline || 90);
864
+ async updateSubscription(subscriptionName, subscription, subscriptionMetaData, inputOpts) {
865
+ const defaultOptions = {
866
+ retryLimit: 5,
867
+ retryMinDelay: 10,
868
+ retryMaxDelay: 360,
869
+ ackDeadline: 90
870
+ };
871
+ const opts = Object.assign({}, defaultOptions, inputOpts);
872
+ let nextMetadata = null;
873
+ if (isSubscriptionOptionsPush(opts)) {
874
+ if (opts.endpointUrl !== subscriptionMetaData?.pushConfig?.pushEndpoint || this.serviceAccountEmail !== subscriptionMetaData?.pushConfig.oidcToken?.serviceAccountEmail || process.env.GCLOUD_PROJECT + "/" + this.triggerId !== subscriptionMetaData.pushConfig.oidcToken.audience) {
875
+ if (subscriptionMetaData?.pushConfig?.pushEndpoint && subscription) {
876
+ await subscription.modifyPushConfig({
877
+ pushEndpoint: opts.endpointUrl,
878
+ oidcToken: {
879
+ serviceAccountEmail: this.serviceAccountEmail,
880
+ audience: process.env.GCLOUD_PROJECT + "/" + this.triggerId
881
+ }
882
+ });
883
+ } else {
884
+ nextMetadata = nextMetadata || {};
885
+ nextMetadata.pushConfig = {
886
+ pushEndpoint: opts.endpointUrl,
887
+ oidcToken: {
888
+ serviceAccountEmail: this.serviceAccountEmail,
889
+ audience: process.env.GCLOUD_PROJECT + "/" + this.triggerId
890
+ }
891
+ };
892
+ }
834
893
  }
835
- shouldRecreate = endpointHasChanged || retryDelayHasChanged || retryLimitHasChanged || dlqHasChanged || tableIdHasChanged || ackDeadlineHasChanged;
836
- }
837
- if (subscription && shouldRecreate) {
838
- await subscription.delete();
839
- }
840
- const payload = {};
841
- if (!isSubscriptionOptionsPush(opts)) {
842
- payload.ackDeadlineSeconds = 60;
843
- payload.bigqueryConfig = {
844
- table: opts.tableId,
845
- writeMetadata: true,
846
- dropUnknownFields: true,
847
- serviceAccountEmail: this.serviceAccountEmail,
848
- useTableSchema: false
849
- };
850
- payload.filter = `attributes:bigquery`;
851
894
  } else {
852
- payload.ackDeadlineSeconds = opts.ackDeadline || 90;
853
- payload.pushConfig = {
854
- pushEndpoint: opts.endpointUrl,
855
- oidcToken: {
856
- serviceAccountEmail: this.serviceAccountEmail,
857
- audience: process.env.GCLOUD_PROJECT + "/" + this.triggerId
858
- }
895
+ nextMetadata = nextMetadata || {};
896
+ nextMetadata.pushConfig = null;
897
+ }
898
+ if (opts.dlqTopic) {
899
+ if (opts.dlqTopic.name !== subscriptionMetaData?.deadLetterPolicy?.deadLetterTopic || opts.retryLimit !== subscriptionMetaData?.deadLetterPolicy.maxDeliveryAttempts) {
900
+ nextMetadata = nextMetadata || {};
901
+ nextMetadata.deadLetterPolicy = {
902
+ deadLetterTopic: opts.dlqTopic.name,
903
+ maxDeliveryAttempts: opts.retryLimit
904
+ };
905
+ }
906
+ } else if (subscriptionMetaData?.deadLetterPolicy?.deadLetterTopic) {
907
+ nextMetadata = nextMetadata || {
908
+ deadLetterPolicy: null
859
909
  };
860
- payload.retryPolicy = {
910
+ }
911
+ if (opts.retryMinDelay !== subscriptionMetaData?.retryPolicy?.minimumBackoff?.seconds || opts.retryMaxDelay !== subscriptionMetaData?.retryPolicy?.maximumBackoff?.seconds) {
912
+ nextMetadata = nextMetadata || {};
913
+ nextMetadata.retryPolicy = {
861
914
  minimumBackoff: { seconds: opts.retryMinDelay },
862
915
  maximumBackoff: { seconds: opts.retryMaxDelay }
863
916
  };
864
- if (opts.dlqTopic) {
865
- payload.deadLetterPolicy = {
866
- deadLetterTopic: opts.dlqTopic.name,
867
- maxDeliveryAttempts: opts.retryLimit
868
- };
917
+ }
918
+ const proposedLabels = {
919
+ "created-at": subscriptionMetaData?.labels?.["created-at"] || (/* @__PURE__ */ new Date()).toISOString(),
920
+ "last-modified-at": subscriptionMetaData?.labels?.["created-at"] || (/* @__PURE__ */ new Date()).toISOString(),
921
+ "env": this.envName,
922
+ "bs-triggerid": this.triggerId,
923
+ "bs-workflowid": this.workflowId,
924
+ "bs-envname": this.systemEnvName,
925
+ "bs-runtimeurl": this.runtimeUrl,
926
+ "bs-is-deadletter": subscriptionName.indexOf("-dlq") > -1 ? "true" : "false",
927
+ "bs-is-push-enabled": isSubscriptionOptionsPush(opts) && opts.endpointUrl ? "true" : "false",
928
+ "bs-bigquery-tableid": !(isSubscriptionOptionsPush(opts) || isSubscriptionOptionsPull(opts)) && opts.tableId ? opts.tableId : "",
929
+ "bs-is-bigquery": !(isSubscriptionOptionsPush(opts) || isSubscriptionOptionsPull(opts)) && opts.tableId ? "true" : "false"
930
+ };
931
+ const simLabels = Object.assign({}, subscriptionMetaData?.labels || {}, proposedLabels);
932
+ if (!(0, import_lodash.default)(simLabels, subscriptionMetaData?.labels)) {
933
+ simLabels["last-modified-at"] = (/* @__PURE__ */ new Date()).toISOString();
934
+ nextMetadata = nextMetadata || {};
935
+ nextMetadata.labels = simLabels;
936
+ }
937
+ if (opts.ackDeadline !== subscriptionMetaData?.ackDeadlineSeconds) {
938
+ nextMetadata = nextMetadata || {};
939
+ nextMetadata.ackDeadlineSeconds = opts.ackDeadline;
940
+ }
941
+ if (!isSubscriptionOptionsPull(opts) && !isSubscriptionOptionsPush(opts)) {
942
+ if (opts.tableId !== subscriptionMetaData?.bigqueryConfig?.table || this.serviceAccountEmail !== subscriptionMetaData.bigqueryConfig?.serviceAccountEmail) {
943
+ if (opts.tableId) {
944
+ nextMetadata = nextMetadata || {};
945
+ nextMetadata.bigqueryConfig = {
946
+ table: opts.tableId,
947
+ writeMetadata: true,
948
+ dropUnknownFields: true,
949
+ serviceAccountEmail: this.serviceAccountEmail,
950
+ useTableSchema: false
951
+ };
952
+ nextMetadata.filter = `attributes:bigquery`;
953
+ } else {
954
+ nextMetadata = nextMetadata || {};
955
+ nextMetadata.bigqueryConfig = null;
956
+ }
869
957
  }
958
+ } else if (subscriptionMetaData?.bigqueryConfig?.table) {
959
+ nextMetadata = nextMetadata || {};
960
+ nextMetadata.bigqueryConfig = null;
870
961
  }
871
- if (!subscription || shouldRecreate) {
872
- await opts.topic.createSubscription(subscriptionName, payload);
962
+ if (subscription && nextMetadata) {
963
+ await subscription.setMetadata(nextMetadata);
964
+ return null;
965
+ }
966
+ return nextMetadata;
967
+ }
968
+ async ensureSubscribtionExists(subscriptionName, opts) {
969
+ let [subscriptions] = await opts.topic.getSubscriptions();
970
+ let subscription = subscriptions.find((subscription2) => this.getNameFromFullyQualifiedName(subscription2.name) === subscriptionName) || null;
971
+ const [subscriptionMetaData] = await subscription?.getMetadata() || [null];
972
+ const createPayload = await this.updateSubscription(subscriptionName, subscription, subscriptionMetaData, opts);
973
+ if (createPayload) {
974
+ await opts.topic.createSubscription(subscriptionName, createPayload);
873
975
  [subscriptions] = await opts.topic.getSubscriptions();
874
- subscription = subscriptions.find((subscription2) => this.getNameFromFullyQualifiedName(subscription2.name) === subscriptionName);
976
+ subscription = subscriptions.find((subscription2) => this.getNameFromFullyQualifiedName(subscription2.name) === subscriptionName) || null;
875
977
  }
876
978
  if (!subscription) {
877
979
  throw new Error(`Invariant: While creating subscription - subscription is not found`);
package/dist/package.json CHANGED
@@ -11,7 +11,9 @@
11
11
  "co-body": "^6.2.0",
12
12
  "jose": "^6.0.11",
13
13
  "lodash.clonedeep": "^4.5.0",
14
- "lodash.omit": "^4.5.0"
14
+ "lodash.isequal": "^4.5.0",
15
+ "lodash.omit": "^4.5.0",
16
+ "lodash.pick": "^4.4.0"
15
17
  },
16
18
  "files": [
17
19
  "dist"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shushed/helpers",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "author": "",
5
5
  "license": "UNLICENSED",
6
6
  "description": "",
@@ -11,7 +11,9 @@
11
11
  "co-body": "^6.2.0",
12
12
  "jose": "^6.0.11",
13
13
  "lodash.clonedeep": "^4.5.0",
14
- "lodash.omit": "^4.5.0"
14
+ "lodash.isequal": "^4.5.0",
15
+ "lodash.omit": "^4.5.0",
16
+ "lodash.pick": "^4.4.0"
15
17
  },
16
18
  "files": [
17
19
  "dist"