@memberjunction/core-actions 5.38.0 โ 5.40.0
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/custom/ai/run-cluster-analysis.action.d.ts +49 -0
- package/dist/custom/ai/run-cluster-analysis.action.d.ts.map +1 -0
- package/dist/custom/ai/run-cluster-analysis.action.js +187 -0
- package/dist/custom/ai/run-cluster-analysis.action.js.map +1 -0
- package/dist/custom/data/search-entity.action.d.ts +48 -0
- package/dist/custom/data/search-entity.action.d.ts.map +1 -0
- package/dist/custom/data/search-entity.action.js +138 -0
- package/dist/custom/data/search-entity.action.js.map +1 -0
- package/dist/custom/esignature/base-esignature.action.d.ts +24 -0
- package/dist/custom/esignature/base-esignature.action.d.ts.map +1 -0
- package/dist/custom/esignature/base-esignature.action.js +68 -0
- package/dist/custom/esignature/base-esignature.action.js.map +1 -0
- package/dist/custom/esignature/download-signed-document.action.d.ts +15 -0
- package/dist/custom/esignature/download-signed-document.action.d.ts.map +1 -0
- package/dist/custom/esignature/download-signed-document.action.js +50 -0
- package/dist/custom/esignature/download-signed-document.action.js.map +1 -0
- package/dist/custom/esignature/get-signature-status.action.d.ts +15 -0
- package/dist/custom/esignature/get-signature-status.action.d.ts.map +1 -0
- package/dist/custom/esignature/get-signature-status.action.js +48 -0
- package/dist/custom/esignature/get-signature-status.action.js.map +1 -0
- package/dist/custom/esignature/send-document-for-signature.action.d.ts +24 -0
- package/dist/custom/esignature/send-document-for-signature.action.d.ts.map +1 -0
- package/dist/custom/esignature/send-document-for-signature.action.js +112 -0
- package/dist/custom/esignature/send-document-for-signature.action.js.map +1 -0
- package/dist/custom/esignature/void-signature-request.action.d.ts +15 -0
- package/dist/custom/esignature/void-signature-request.action.d.ts.map +1 -0
- package/dist/custom/esignature/void-signature-request.action.js +47 -0
- package/dist/custom/esignature/void-signature-request.action.js.map +1 -0
- package/dist/custom/geo/scheduled-geocoding.action.d.ts +27 -0
- package/dist/custom/geo/scheduled-geocoding.action.d.ts.map +1 -1
- package/dist/custom/geo/scheduled-geocoding.action.js +96 -13
- package/dist/custom/geo/scheduled-geocoding.action.js.map +1 -1
- package/dist/custom/integration/generate-integration-action.action.d.ts +60 -0
- package/dist/custom/integration/generate-integration-action.action.d.ts.map +1 -0
- package/dist/custom/integration/generate-integration-action.action.js +182 -0
- package/dist/custom/integration/generate-integration-action.action.js.map +1 -0
- package/dist/custom/integration/integration-action-executor.d.ts +28 -5
- package/dist/custom/integration/integration-action-executor.d.ts.map +1 -1
- package/dist/custom/integration/integration-action-executor.js +65 -11
- package/dist/custom/integration/integration-action-executor.js.map +1 -1
- package/dist/custom/utilities/vectorize-entity.action.d.ts.map +1 -1
- package/dist/custom/utilities/vectorize-entity.action.js +7 -2
- package/dist/custom/utilities/vectorize-entity.action.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/package.json +36 -34
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
2
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
3
|
+
/**
|
|
4
|
+
* Action: "Get Signature Status".
|
|
5
|
+
*
|
|
6
|
+
* Polls the provider for the current envelope status of a signature request and persists it.
|
|
7
|
+
* Thin wrapper over {@link SignatureEngine.RefreshStatus}.
|
|
8
|
+
*
|
|
9
|
+
* Inputs: SignatureRequestID (required).
|
|
10
|
+
* Outputs: Status.
|
|
11
|
+
*/
|
|
12
|
+
export declare class GetSignatureStatusAction extends BaseSignatureAction {
|
|
13
|
+
protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=get-signature-status.action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-signature-status.action.d.ts","sourceRoot":"","sources":["../../../src/custom/esignature/get-signature-status.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;;GAQG;AACH,qBACa,wBAAyB,SAAQ,mBAAmB;cAC7C,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAyB1F"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
9
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
10
|
+
/**
|
|
11
|
+
* Action: "Get Signature Status".
|
|
12
|
+
*
|
|
13
|
+
* Polls the provider for the current envelope status of a signature request and persists it.
|
|
14
|
+
* Thin wrapper over {@link SignatureEngine.RefreshStatus}.
|
|
15
|
+
*
|
|
16
|
+
* Inputs: SignatureRequestID (required).
|
|
17
|
+
* Outputs: Status.
|
|
18
|
+
*/
|
|
19
|
+
let GetSignatureStatusAction = class GetSignatureStatusAction extends BaseSignatureAction {
|
|
20
|
+
async InternalRunAction(params) {
|
|
21
|
+
const requestId = this.getStringParam(params, 'SignatureRequestID');
|
|
22
|
+
if (!requestId) {
|
|
23
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: "Parameter 'SignatureRequestID' is required." };
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const engine = await this.ensureEngine(params);
|
|
27
|
+
const result = await engine.RefreshStatus(requestId, params.ContextUser);
|
|
28
|
+
if (!result.Success) {
|
|
29
|
+
const notSent = (result.ErrorMessage ?? '').includes('not been sent');
|
|
30
|
+
return {
|
|
31
|
+
Success: false,
|
|
32
|
+
ResultCode: notSent ? 'NOT_SENT' : 'PROVIDER_ERROR',
|
|
33
|
+
Message: result.ErrorMessage ?? 'Status check failed.',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
this.addOutput(params, 'Status', result.status);
|
|
37
|
+
return { Success: true, ResultCode: 'OK', Message: `Status: ${result.status}.`, Params: params.Params };
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: e instanceof Error ? e.message : String(e) };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
GetSignatureStatusAction = __decorate([
|
|
45
|
+
RegisterClass(BaseAction, 'Get Signature Status')
|
|
46
|
+
], GetSignatureStatusAction);
|
|
47
|
+
export { GetSignatureStatusAction };
|
|
48
|
+
//# sourceMappingURL=get-signature-status.action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-signature-status.action.js","sourceRoot":"","sources":["../../../src/custom/esignature/get-signature-status.action.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;;GAQG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,mBAAmB;IACnD,KAAK,CAAC,iBAAiB,CAAC,MAAuB;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC;QACpH,CAAC;QAED,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAEzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;gBACtE,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB;oBACnD,OAAO,EAAE,MAAM,CAAC,YAAY,IAAI,sBAAsB;iBACzD,CAAC;YACN,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,MAAM,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5G,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACjH,CAAC;IACL,CAAC;CACJ,CAAA;AA1BY,wBAAwB;IADpC,aAAa,CAAC,UAAU,EAAE,sBAAsB,CAAC;GACrC,wBAAwB,CA0BpC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
2
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
3
|
+
/**
|
|
4
|
+
* Action: "Send Document for Signature".
|
|
5
|
+
*
|
|
6
|
+
* Sends one or more documents through a configured signature account/provider and records the
|
|
7
|
+
* envelope lifecycle. Thin wrapper over {@link SignatureEngine.SendForSignature}.
|
|
8
|
+
*
|
|
9
|
+
* Inputs:
|
|
10
|
+
* - SignatureAccountID (required)
|
|
11
|
+
* - Title (required)
|
|
12
|
+
* - Documents (required) โ array of `{ filename, contentType?, contentBase64 }`
|
|
13
|
+
* - Recipients (required) โ array of `{ email, name?, routingOrder?, role? }`
|
|
14
|
+
* - Message?, EntityID?, RecordID?, ArtifactID?, ArtifactVersionID?, SendImmediately?, Metadata?
|
|
15
|
+
*
|
|
16
|
+
* Outputs: SignatureRequestID, ExternalEnvelopeID, Status.
|
|
17
|
+
*/
|
|
18
|
+
export declare class SendDocumentForSignatureAction extends BaseSignatureAction {
|
|
19
|
+
protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
|
|
20
|
+
private parseDocuments;
|
|
21
|
+
private parseRecipients;
|
|
22
|
+
private fail;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=send-document-for-signature.action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-document-for-signature.action.d.ts","sourceRoot":"","sources":["../../../src/custom/esignature/send-document-for-signature.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAInF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAU/D;;;;;;;;;;;;;;GAcG;AACH,qBACa,8BAA+B,SAAQ,mBAAmB;cACnD,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+DvF,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,IAAI;CAMf"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
9
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
10
|
+
/**
|
|
11
|
+
* Action: "Send Document for Signature".
|
|
12
|
+
*
|
|
13
|
+
* Sends one or more documents through a configured signature account/provider and records the
|
|
14
|
+
* envelope lifecycle. Thin wrapper over {@link SignatureEngine.SendForSignature}.
|
|
15
|
+
*
|
|
16
|
+
* Inputs:
|
|
17
|
+
* - SignatureAccountID (required)
|
|
18
|
+
* - Title (required)
|
|
19
|
+
* - Documents (required) โ array of `{ filename, contentType?, contentBase64 }`
|
|
20
|
+
* - Recipients (required) โ array of `{ email, name?, routingOrder?, role? }`
|
|
21
|
+
* - Message?, EntityID?, RecordID?, ArtifactID?, ArtifactVersionID?, SendImmediately?, Metadata?
|
|
22
|
+
*
|
|
23
|
+
* Outputs: SignatureRequestID, ExternalEnvelopeID, Status.
|
|
24
|
+
*/
|
|
25
|
+
let SendDocumentForSignatureAction = class SendDocumentForSignatureAction extends BaseSignatureAction {
|
|
26
|
+
async InternalRunAction(params) {
|
|
27
|
+
const signatureAccountId = this.getStringParam(params, 'SignatureAccountID');
|
|
28
|
+
const title = this.getStringParam(params, 'Title');
|
|
29
|
+
const documents = this.parseDocuments(params);
|
|
30
|
+
const recipients = this.parseRecipients(params);
|
|
31
|
+
const artifactId = this.getStringParam(params, 'ArtifactID');
|
|
32
|
+
const artifactVersionId = this.getStringParam(params, 'ArtifactVersionID');
|
|
33
|
+
if (!signatureAccountId) {
|
|
34
|
+
return this.fail('ACCOUNT_NOT_FOUND', "Parameter 'SignatureAccountID' is required.");
|
|
35
|
+
}
|
|
36
|
+
if (!title) {
|
|
37
|
+
return this.fail('PROVIDER_ERROR', "Parameter 'Title' is required.");
|
|
38
|
+
}
|
|
39
|
+
// Documents may be supplied inline (base64) OR by reference to an Artifact Version already
|
|
40
|
+
// in MJ. Require at least one source.
|
|
41
|
+
if (!documents.length && !artifactVersionId) {
|
|
42
|
+
return this.fail('MISSING_DOCUMENT', "Provide 'Documents' (each with contentBase64) or an 'ArtifactVersionID' to send a document already in MemberJunction.");
|
|
43
|
+
}
|
|
44
|
+
if (!recipients.length) {
|
|
45
|
+
return this.fail('PROVIDER_ERROR', "Parameter 'Recipients' must contain at least one recipient with an email.");
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const engine = await this.ensureEngine(params);
|
|
49
|
+
const result = await engine.SendForSignature({
|
|
50
|
+
signatureAccountId,
|
|
51
|
+
title,
|
|
52
|
+
message: this.getStringParam(params, 'Message'),
|
|
53
|
+
documents,
|
|
54
|
+
recipients,
|
|
55
|
+
artifactId,
|
|
56
|
+
artifactVersionId,
|
|
57
|
+
entityId: this.getStringParam(params, 'EntityID'),
|
|
58
|
+
recordId: this.getStringParam(params, 'RecordID'),
|
|
59
|
+
sendImmediately: this.getBooleanParam(params, 'SendImmediately', true),
|
|
60
|
+
metadata: this.getObjectParam(params, 'Metadata'),
|
|
61
|
+
contextUser: params.ContextUser,
|
|
62
|
+
});
|
|
63
|
+
if (!result.Success) {
|
|
64
|
+
return this.fail('PROVIDER_ERROR', result.ErrorMessage ?? 'Send failed.', params, result.signatureRequestId);
|
|
65
|
+
}
|
|
66
|
+
this.addOutput(params, 'SignatureRequestID', result.signatureRequestId);
|
|
67
|
+
this.addOutput(params, 'ExternalEnvelopeID', result.externalEnvelopeId);
|
|
68
|
+
this.addOutput(params, 'Status', result.status);
|
|
69
|
+
const sentImmediately = this.getBooleanParam(params, 'SendImmediately', true);
|
|
70
|
+
return {
|
|
71
|
+
Success: true,
|
|
72
|
+
ResultCode: sentImmediately ? 'SENT' : 'DRAFT_CREATED',
|
|
73
|
+
Message: `Signature request ${result.signatureRequestId} (${result.status}).`,
|
|
74
|
+
Params: params.Params,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
return this.fail('PROVIDER_ERROR', e instanceof Error ? e.message : String(e), params);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
parseDocuments(params) {
|
|
82
|
+
const raw = this.getObjectParam(params, 'Documents');
|
|
83
|
+
if (!Array.isArray(raw)) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
return raw
|
|
87
|
+
.filter((d) => d && d.filename && d.contentBase64)
|
|
88
|
+
.map((d) => ({
|
|
89
|
+
filename: d.filename,
|
|
90
|
+
contentType: d.contentType ?? 'application/pdf',
|
|
91
|
+
bytes: Buffer.from(d.contentBase64, 'base64'),
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
parseRecipients(params) {
|
|
95
|
+
const raw = this.getObjectParam(params, 'Recipients');
|
|
96
|
+
if (!Array.isArray(raw)) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return raw.filter((r) => r && r.email);
|
|
100
|
+
}
|
|
101
|
+
fail(resultCode, message, params, signatureRequestId) {
|
|
102
|
+
if (params && signatureRequestId) {
|
|
103
|
+
this.addOutput(params, 'SignatureRequestID', signatureRequestId);
|
|
104
|
+
}
|
|
105
|
+
return { Success: false, ResultCode: resultCode, Message: message, Params: params?.Params };
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
SendDocumentForSignatureAction = __decorate([
|
|
109
|
+
RegisterClass(BaseAction, 'Send Document for Signature')
|
|
110
|
+
], SendDocumentForSignatureAction);
|
|
111
|
+
export { SendDocumentForSignatureAction };
|
|
112
|
+
//# sourceMappingURL=send-document-for-signature.action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-document-for-signature.action.js","sourceRoot":"","sources":["../../../src/custom/esignature/send-document-for-signature.action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
2
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
3
|
+
/**
|
|
4
|
+
* Action: "Void Signature Request".
|
|
5
|
+
*
|
|
6
|
+
* Voids/cancels an in-flight signature request with a reason. Thin wrapper over
|
|
7
|
+
* {@link SignatureEngine.Void}.
|
|
8
|
+
*
|
|
9
|
+
* Inputs: SignatureRequestID (required), Reason (required).
|
|
10
|
+
* Outputs: Status.
|
|
11
|
+
*/
|
|
12
|
+
export declare class VoidSignatureRequestAction extends BaseSignatureAction {
|
|
13
|
+
protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=void-signature-request.action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"void-signature-request.action.d.ts","sourceRoot":"","sources":["../../../src/custom/esignature/void-signature-request.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;;GAQG;AACH,qBACa,0BAA2B,SAAQ,mBAAmB;cAC/C,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAwB1F"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
9
|
+
import { BaseSignatureAction } from './base-esignature.action.js';
|
|
10
|
+
/**
|
|
11
|
+
* Action: "Void Signature Request".
|
|
12
|
+
*
|
|
13
|
+
* Voids/cancels an in-flight signature request with a reason. Thin wrapper over
|
|
14
|
+
* {@link SignatureEngine.Void}.
|
|
15
|
+
*
|
|
16
|
+
* Inputs: SignatureRequestID (required), Reason (required).
|
|
17
|
+
* Outputs: Status.
|
|
18
|
+
*/
|
|
19
|
+
let VoidSignatureRequestAction = class VoidSignatureRequestAction extends BaseSignatureAction {
|
|
20
|
+
async InternalRunAction(params) {
|
|
21
|
+
const requestId = this.getStringParam(params, 'SignatureRequestID');
|
|
22
|
+
const reason = this.getStringParam(params, 'Reason');
|
|
23
|
+
if (!requestId) {
|
|
24
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: "Parameter 'SignatureRequestID' is required." };
|
|
25
|
+
}
|
|
26
|
+
if (!reason) {
|
|
27
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: "Parameter 'Reason' is required." };
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const engine = await this.ensureEngine(params);
|
|
31
|
+
const result = await engine.Void(requestId, reason, params.ContextUser);
|
|
32
|
+
if (!result.Success) {
|
|
33
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: result.ErrorMessage ?? 'Void failed.' };
|
|
34
|
+
}
|
|
35
|
+
this.addOutput(params, 'Status', 'Voided');
|
|
36
|
+
return { Success: true, ResultCode: 'VOIDED', Message: 'Signature request voided.', Params: params.Params };
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return { Success: false, ResultCode: 'PROVIDER_ERROR', Message: e instanceof Error ? e.message : String(e) };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
VoidSignatureRequestAction = __decorate([
|
|
44
|
+
RegisterClass(BaseAction, 'Void Signature Request')
|
|
45
|
+
], VoidSignatureRequestAction);
|
|
46
|
+
export { VoidSignatureRequestAction };
|
|
47
|
+
//# sourceMappingURL=void-signature-request.action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"void-signature-request.action.js","sourceRoot":"","sources":["../../../src/custom/esignature/void-signature-request.action.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;;GAQG;AAEI,IAAM,0BAA0B,GAAhC,MAAM,0BAA2B,SAAQ,mBAAmB;IACrD,KAAK,CAAC,iBAAiB,CAAC,MAAuB;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC;QACpH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;QACxG,CAAC;QAED,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAExE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,IAAI,cAAc,EAAE,CAAC;YAC5G,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAChH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACjH,CAAC;IACL,CAAC;CACJ,CAAA;AAzBY,0BAA0B;IADtC,aAAa,CAAC,UAAU,EAAE,wBAAwB,CAAC;GACvC,0BAA0B,CAyBtC"}
|
|
@@ -44,6 +44,8 @@ export declare class ScheduledGeocodingAction extends BaseAction {
|
|
|
44
44
|
private static readonly DEFAULT_MAX_TOTAL;
|
|
45
45
|
/** Page size for RunView pagination โ controls how many BaseEntity objects exist simultaneously. */
|
|
46
46
|
private static readonly PAGE_SIZE;
|
|
47
|
+
/** Indentation prefix for child log lines nested under a group/entity header. */
|
|
48
|
+
private static readonly INDENT;
|
|
47
49
|
/**
|
|
48
50
|
* Geocoding provider name in effect for the current run. Set at the top of
|
|
49
51
|
* InternalRunAction from the 'GeocodingProvider' action parameter and read
|
|
@@ -128,6 +130,9 @@ export declare class ScheduledGeocodingAction extends BaseAction {
|
|
|
128
130
|
* @param contextUser - User context
|
|
129
131
|
* @param batchSize - Number of concurrent geocoding operations per batch
|
|
130
132
|
* @param existingGeoCodesMap - Optional pre-loaded map passed to GeoCodeSyncService
|
|
133
|
+
* @param progress - Optional console progress context. When supplied, each batch logs a
|
|
134
|
+
* cumulative `records XโY of Total` line (anchored to `progress.Offset`) instead of a
|
|
135
|
+
* per-call `batch N/M` line that resets every page.
|
|
131
136
|
*/
|
|
132
137
|
private geocodeBatch;
|
|
133
138
|
/**
|
|
@@ -155,6 +160,28 @@ export declare class ScheduledGeocodingAction extends BaseAction {
|
|
|
155
160
|
* exactly the same contract as a real save event.
|
|
156
161
|
*/
|
|
157
162
|
private fireSyntheticSaveEvent;
|
|
163
|
+
/**
|
|
164
|
+
* Format an integer with locale thousands separators for console output
|
|
165
|
+
* (e.g. `2000` โ `2,000`). Pinned to `en-US` for deterministic logs.
|
|
166
|
+
*/
|
|
167
|
+
private fmt;
|
|
168
|
+
/**
|
|
169
|
+
* Emit the group header that precedes a single entity's batch lines, e.g.
|
|
170
|
+
* `๐ Members โ 2,000 records with address data`.
|
|
171
|
+
*/
|
|
172
|
+
private logEntityHeader;
|
|
173
|
+
/**
|
|
174
|
+
* Emit one indented, cumulative batch line beneath the entity header, e.g.
|
|
175
|
+
* ` โ records 1,991โ2,000 of 2,000 ยท 10/10 (page 4)`. The range is anchored
|
|
176
|
+
* to `progress.Offset` so the numbers run continuously across every page.
|
|
177
|
+
*/
|
|
178
|
+
private logBatchProgress;
|
|
179
|
+
/**
|
|
180
|
+
* Emit the indented per-entity completion line, reconciling geocoded vs.
|
|
181
|
+
* failed vs. already-current against the candidate total, e.g.
|
|
182
|
+
* ` โ
Members โ 1,974 geocoded, 26 already current`.
|
|
183
|
+
*/
|
|
184
|
+
private logEntityComplete;
|
|
158
185
|
/**
|
|
159
186
|
* Get the geo address fields (non-lat/lng) for an entity.
|
|
160
187
|
* These are the fields that, when non-null, indicate a record
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduled-geocoding.action.d.ts","sourceRoot":"","sources":["../../../src/custom/geo/scheduled-geocoding.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduled-geocoding.action.d.ts","sourceRoot":"","sources":["../../../src/custom/geo/scheduled-geocoding.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AA2BrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBACa,wBAAyB,SAAQ,UAAU;IACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAK;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAM;IAChD,qGAAqG;IACrG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IACnD,oGAAoG;IACpG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAO;IACxC,iFAAiF;IACjF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEvC;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB,CAAuB;cAEvC,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgDvF;;;;OAIG;YACW,qBAAqB;IA2BnC;;;;;;;;;;OAUG;YACW,uBAAuB;IAoGrC;;;;;;;;;OASG;YACW,oBAAoB;IAyBlC;;;OAGG;YACW,oBAAoB;IA4BlC;;;;OAIG;YACW,oBAAoB;IAwElC;;;OAGG;YACW,kBAAkB;IA6BhC;;;;OAIG;YACW,sBAAsB;IAgDpC;;;;OAIG;YACW,uBAAuB;IAmDrC;;;;;;;;;;;;;;;;;;OAkBG;YACW,YAAY;IA4B1B;;;;;;;;;;OAUG;YACW,oBAAoB;IA2BlC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,sBAAsB;IAsB9B;;;OAGG;IACH,OAAO,CAAC,GAAG;IAIX;;;OAGG;IACH,OAAO,CAAC,eAAe;IAOvB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;;;;;;;;OASG;YACW,uBAAuB;IAoCrC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,cAAc;CAMzB"}
|
|
@@ -69,6 +69,8 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
69
69
|
static { this.DEFAULT_MAX_TOTAL = 50_000; }
|
|
70
70
|
/** Page size for RunView pagination โ controls how many BaseEntity objects exist simultaneously. */
|
|
71
71
|
static { this.PAGE_SIZE = 500; }
|
|
72
|
+
/** Indentation prefix for child log lines nested under a group/entity header. */
|
|
73
|
+
static { this.INDENT = ' '; }
|
|
72
74
|
async InternalRunAction(params) {
|
|
73
75
|
const contextUser = params.ContextUser;
|
|
74
76
|
if (!contextUser) {
|
|
@@ -79,7 +81,7 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
79
81
|
const maxTotal = this.getNumericParam(params, 'MaxTotalRecords', ScheduledGeocodingAction_1.DEFAULT_MAX_TOTAL);
|
|
80
82
|
const geocodingProvider = this.getStringParam(params, 'GeocodingProvider');
|
|
81
83
|
this.currentGeocodingProvider = geocodingProvider ?? null;
|
|
82
|
-
LogStatus(
|
|
84
|
+
LogStatus(`๐ Scheduled Geocoding โ starting (batch ${batchSize} ยท max ${this.fmt(maxTotal)} ยท provider ${geocodingProvider ?? 'config-default'})`);
|
|
83
85
|
const stats = { MissingProcessed: 0, MissingSuccess: 0, RetriesProcessed: 0, RetriesSuccess: 0, OrphansRemoved: 0 };
|
|
84
86
|
// Step 1: Find and geocode missing records
|
|
85
87
|
const missingStats = await this.processMissingRecords(contextUser, batchSize, maxTotal, params.Provider);
|
|
@@ -94,9 +96,9 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
94
96
|
stats.OrphansRemoved = await this.cleanupOrphanedRecords(contextUser, batchSize, params.Provider);
|
|
95
97
|
const totalRecordsProcessed = stats.MissingProcessed + stats.RetriesProcessed;
|
|
96
98
|
if (totalRecordsProcessed >= maxTotal) {
|
|
97
|
-
LogStatus(
|
|
99
|
+
LogStatus(`โ ๏ธ MaxTotal limit (${this.fmt(maxTotal)}) reached โ remaining records will be picked up on the next run.`);
|
|
98
100
|
}
|
|
99
|
-
LogStatus(
|
|
101
|
+
LogStatus(`๐ Scheduled Geocoding โ complete ยท missing ${this.fmt(stats.MissingProcessed)} (${this.fmt(stats.MissingSuccess)} โ) ยท retries ${this.fmt(stats.RetriesProcessed)} (${this.fmt(stats.RetriesSuccess)} โ) ยท orphans ${this.fmt(stats.OrphansRemoved)} removed`);
|
|
100
102
|
return {
|
|
101
103
|
Success: true,
|
|
102
104
|
ResultCode: 'SUCCESS',
|
|
@@ -125,7 +127,7 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
125
127
|
totalSuccess += entityStats.Success;
|
|
126
128
|
}
|
|
127
129
|
if (totalProcessed > 0) {
|
|
128
|
-
LogStatus(
|
|
130
|
+
LogStatus(`โ
Missing-record geocoding complete โ ${this.fmt(totalProcessed)} processed, ${this.fmt(totalSuccess)} geocoded`);
|
|
129
131
|
}
|
|
130
132
|
return { Processed: totalProcessed, Success: totalSuccess };
|
|
131
133
|
}
|
|
@@ -160,15 +162,23 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
160
162
|
let totalSuccess = 0;
|
|
161
163
|
let pageOffset = 0; // OFFSET-mode (composite-PK fallback)
|
|
162
164
|
let lastSeenKey; // keyset mode
|
|
165
|
+
let pageNumber = 0; // 1-based, shown in batch lines
|
|
166
|
+
let candidateTotal = 0; // denominator: records with address data (from page-1 TotalRowCount)
|
|
167
|
+
let headerLogged = false; // emit the entity header lazily, only when there's work to do
|
|
163
168
|
// Paginate through entity records to avoid loading all into memory at once.
|
|
164
169
|
// Keyset pagination keeps each page O(log N) regardless of depth โ a critical
|
|
165
170
|
// win when the entity has millions of rows. See guides/KEYSET_PAGINATION_GUIDE.md.
|
|
166
171
|
while (totalProcessed < maxRows) {
|
|
172
|
+
pageNumber++;
|
|
167
173
|
const pageResult = canUseKeyset
|
|
168
174
|
? await this.loadEntityPageKeyset(entityInfo.Name, pkField.Name, nonNullConditions, lastSeenKey, contextUser)
|
|
169
175
|
: await this.loadEntityPageOffset(entityInfo.Name, nonNullConditions, pageOffset, contextUser);
|
|
170
176
|
if (!pageResult.Success || pageResult.Results.length === 0)
|
|
171
177
|
break;
|
|
178
|
+
// TotalRowCount reports the full count matching the filter regardless of the
|
|
179
|
+
// keyset seek predicate / page offset, so the first page gives us a stable denominator.
|
|
180
|
+
if (candidateTotal === 0)
|
|
181
|
+
candidateTotal = pageResult.TotalRowCount;
|
|
172
182
|
const pageEntities = pageResult.Results;
|
|
173
183
|
// Filter to records missing geocodes (not in existingMap for any LocationType)
|
|
174
184
|
const missingRecords = pageEntities.filter(entity => {
|
|
@@ -179,9 +189,18 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
179
189
|
return !existingMap.has(key);
|
|
180
190
|
});
|
|
181
191
|
if (missingRecords.length > 0) {
|
|
192
|
+
if (!headerLogged) {
|
|
193
|
+
this.logEntityHeader(entityInfo, candidateTotal);
|
|
194
|
+
headerLogged = true;
|
|
195
|
+
}
|
|
182
196
|
const budget = maxRows - totalProcessed;
|
|
183
197
|
const toProcess = missingRecords.slice(0, budget);
|
|
184
|
-
const stats = await this.geocodeBatch(toProcess, entityInfo, contextUser, batchSize, existingMap
|
|
198
|
+
const stats = await this.geocodeBatch(toProcess, entityInfo, contextUser, batchSize, existingMap, {
|
|
199
|
+
Label: entityInfo.Name,
|
|
200
|
+
Total: candidateTotal,
|
|
201
|
+
Offset: totalProcessed,
|
|
202
|
+
Page: pageNumber
|
|
203
|
+
});
|
|
185
204
|
totalProcessed += stats.Processed;
|
|
186
205
|
totalSuccess += stats.Success;
|
|
187
206
|
}
|
|
@@ -200,6 +219,9 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
200
219
|
pageOffset += ScheduledGeocodingAction_1.PAGE_SIZE;
|
|
201
220
|
}
|
|
202
221
|
}
|
|
222
|
+
if (headerLogged) {
|
|
223
|
+
this.logEntityComplete(entityInfo, totalProcessed, totalSuccess, candidateTotal);
|
|
224
|
+
}
|
|
203
225
|
return { Processed: totalProcessed, Success: totalSuccess };
|
|
204
226
|
}
|
|
205
227
|
catch (e) {
|
|
@@ -231,7 +253,8 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
231
253
|
}, contextUser);
|
|
232
254
|
return {
|
|
233
255
|
Success: result.Success,
|
|
234
|
-
Results: result.Success ? result.Results : []
|
|
256
|
+
Results: result.Success ? result.Results : [],
|
|
257
|
+
TotalRowCount: result.Success ? result.TotalRowCount : 0
|
|
235
258
|
};
|
|
236
259
|
}
|
|
237
260
|
/**
|
|
@@ -251,7 +274,8 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
251
274
|
}, contextUser);
|
|
252
275
|
return {
|
|
253
276
|
Success: result.Success,
|
|
254
|
-
Results: result.Success ? result.Results : []
|
|
277
|
+
Results: result.Success ? result.Results : [],
|
|
278
|
+
TotalRowCount: result.Success ? result.TotalRowCount : 0
|
|
255
279
|
};
|
|
256
280
|
}
|
|
257
281
|
// ================================================================
|
|
@@ -270,6 +294,7 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
270
294
|
let totalProcessed = 0;
|
|
271
295
|
let totalSuccess = 0;
|
|
272
296
|
let pageOffset = 0;
|
|
297
|
+
let retryTotal = 0; // denominator: total failed-and-retriable rows (from page-1 TotalRowCount)
|
|
273
298
|
while (totalProcessed < maxTotal) {
|
|
274
299
|
const pageResult = await rv.RunView({
|
|
275
300
|
EntityName: 'MJ: Record Geo Codes',
|
|
@@ -285,7 +310,8 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
285
310
|
const budget = maxTotal - totalProcessed;
|
|
286
311
|
const records = pageResult.Results.slice(0, budget);
|
|
287
312
|
if (totalProcessed === 0) {
|
|
288
|
-
|
|
313
|
+
retryTotal = Math.min(pageResult.TotalRowCount, maxTotal);
|
|
314
|
+
LogStatus(`๐ Retrying failed geocodes โ ${this.fmt(retryTotal)} pending`);
|
|
289
315
|
}
|
|
290
316
|
// Group by entity for efficient processing
|
|
291
317
|
const byEntity = new Map();
|
|
@@ -305,7 +331,11 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
305
331
|
const entities = await this.loadSourceEntities(geoRecords, entityInfo, contextUser, provider);
|
|
306
332
|
if (entities.length === 0)
|
|
307
333
|
continue;
|
|
308
|
-
const stats = await this.geocodeBatch(entities, entityInfo, contextUser, batchSize
|
|
334
|
+
const stats = await this.geocodeBatch(entities, entityInfo, contextUser, batchSize, undefined, {
|
|
335
|
+
Label: entityInfo.Name,
|
|
336
|
+
Total: retryTotal,
|
|
337
|
+
Offset: totalProcessed
|
|
338
|
+
});
|
|
309
339
|
totalProcessed += stats.Processed;
|
|
310
340
|
totalSuccess += stats.Success;
|
|
311
341
|
}
|
|
@@ -418,7 +448,7 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
418
448
|
hasMore = orphans.length >= ScheduledGeocodingAction_1.PAGE_SIZE;
|
|
419
449
|
}
|
|
420
450
|
if (entityRemoved > 0) {
|
|
421
|
-
LogStatus(
|
|
451
|
+
LogStatus(`๐งน ${entityInfo.Name} โ removed ${this.fmt(entityRemoved)} orphaned geo records`);
|
|
422
452
|
}
|
|
423
453
|
return entityRemoved;
|
|
424
454
|
}
|
|
@@ -440,16 +470,19 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
440
470
|
* @param contextUser - User context
|
|
441
471
|
* @param batchSize - Number of concurrent geocoding operations per batch
|
|
442
472
|
* @param existingGeoCodesMap - Optional pre-loaded map passed to GeoCodeSyncService
|
|
473
|
+
* @param progress - Optional console progress context. When supplied, each batch logs a
|
|
474
|
+
* cumulative `records XโY of Total` line (anchored to `progress.Offset`) instead of a
|
|
475
|
+
* per-call `batch N/M` line that resets every page.
|
|
443
476
|
*/
|
|
444
|
-
async geocodeBatch(entities, entityInfo, contextUser, batchSize, existingGeoCodesMap) {
|
|
477
|
+
async geocodeBatch(entities, entityInfo, contextUser, batchSize, existingGeoCodesMap, progress) {
|
|
445
478
|
let totalSuccess = 0;
|
|
446
479
|
for (let i = 0; i < entities.length; i += batchSize) {
|
|
447
480
|
const batch = entities.slice(i, i + batchSize);
|
|
448
481
|
const results = await Promise.allSettled(batch.map(entity => this.geocodeAndInvalidate(entity, contextUser, existingGeoCodesMap)));
|
|
449
482
|
const batchSuccess = results.filter(r => r.status === 'fulfilled' && r.value).length;
|
|
450
483
|
totalSuccess += batchSuccess;
|
|
451
|
-
if (
|
|
452
|
-
|
|
484
|
+
if (progress) {
|
|
485
|
+
this.logBatchProgress(progress, i, batch.length, batchSuccess);
|
|
453
486
|
}
|
|
454
487
|
}
|
|
455
488
|
return { Processed: entities.length, Success: totalSuccess };
|
|
@@ -513,6 +546,56 @@ let ScheduledGeocodingAction = class ScheduledGeocodingAction extends BaseAction
|
|
|
513
546
|
});
|
|
514
547
|
}
|
|
515
548
|
// ================================================================
|
|
549
|
+
// Console UX helpers
|
|
550
|
+
// ================================================================
|
|
551
|
+
/**
|
|
552
|
+
* Format an integer with locale thousands separators for console output
|
|
553
|
+
* (e.g. `2000` โ `2,000`). Pinned to `en-US` for deterministic logs.
|
|
554
|
+
*/
|
|
555
|
+
fmt(n) {
|
|
556
|
+
return n.toLocaleString('en-US');
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Emit the group header that precedes a single entity's batch lines, e.g.
|
|
560
|
+
* `๐ Members โ 2,000 records with address data`.
|
|
561
|
+
*/
|
|
562
|
+
logEntityHeader(entityInfo, candidateTotal) {
|
|
563
|
+
const scope = candidateTotal > 0
|
|
564
|
+
? `${this.fmt(candidateTotal)} records with address data`
|
|
565
|
+
: 'records with address data';
|
|
566
|
+
LogStatus(`๐ ${entityInfo.Name} โ ${scope}`);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Emit one indented, cumulative batch line beneath the entity header, e.g.
|
|
570
|
+
* ` โ records 1,991โ2,000 of 2,000 ยท 10/10 (page 4)`. The range is anchored
|
|
571
|
+
* to `progress.Offset` so the numbers run continuously across every page.
|
|
572
|
+
*/
|
|
573
|
+
logBatchProgress(progress, localIndex, batchCount, batchSuccess) {
|
|
574
|
+
const start = progress.Offset + localIndex + 1;
|
|
575
|
+
const end = progress.Offset + localIndex + batchCount;
|
|
576
|
+
const total = progress.Total > 0 ? this.fmt(progress.Total) : '?';
|
|
577
|
+
const allOk = batchSuccess === batchCount;
|
|
578
|
+
const icon = allOk ? 'โ' : 'โ ';
|
|
579
|
+
const failNote = allOk ? '' : ` ยท ${this.fmt(batchCount - batchSuccess)} failed`;
|
|
580
|
+
const pageNote = progress.Page != null ? ` (page ${progress.Page})` : '';
|
|
581
|
+
LogStatus(`${ScheduledGeocodingAction_1.INDENT}${icon} records ${this.fmt(start)}โ${this.fmt(end)} of ${total} ยท ${batchSuccess}/${batchCount}${failNote}${pageNote}`);
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Emit the indented per-entity completion line, reconciling geocoded vs.
|
|
585
|
+
* failed vs. already-current against the candidate total, e.g.
|
|
586
|
+
* ` โ
Members โ 1,974 geocoded, 26 already current`.
|
|
587
|
+
*/
|
|
588
|
+
logEntityComplete(entityInfo, processed, success, candidateTotal) {
|
|
589
|
+
const failed = processed - success;
|
|
590
|
+
const alreadyCurrent = candidateTotal > 0 ? Math.max(0, candidateTotal - processed) : 0;
|
|
591
|
+
const parts = [`${this.fmt(success)} geocoded`];
|
|
592
|
+
if (failed > 0)
|
|
593
|
+
parts.push(`${this.fmt(failed)} failed`);
|
|
594
|
+
if (alreadyCurrent > 0)
|
|
595
|
+
parts.push(`${this.fmt(alreadyCurrent)} already current`);
|
|
596
|
+
LogStatus(`${ScheduledGeocodingAction_1.INDENT}โ
${entityInfo.Name} โ ${parts.join(', ')}`);
|
|
597
|
+
}
|
|
598
|
+
// ================================================================
|
|
516
599
|
// Helpers
|
|
517
600
|
// ================================================================
|
|
518
601
|
/**
|