@memberjunction/core-actions 6.2.0-edge.0 → 6.2.0-edge.2
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/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +16 -4
- package/dist/config.js.map +1 -1
- package/dist/custom/ai/base-find-actions.action.js +6 -6
- package/dist/custom/ai/base-find-agents.action.d.ts.map +1 -1
- package/dist/custom/ai/base-find-agents.action.js +8 -13
- package/dist/custom/ai/base-find-agents.action.js.map +1 -1
- package/dist/custom/ai/find-candidate-agents.action.d.ts.map +1 -1
- package/dist/custom/ai/find-candidate-agents.action.js +4 -3
- package/dist/custom/ai/find-candidate-agents.action.js.map +1 -1
- package/dist/custom/ai/generate-image.action.d.ts +63 -5
- package/dist/custom/ai/generate-image.action.d.ts.map +1 -1
- package/dist/custom/ai/generate-image.action.js +196 -139
- package/dist/custom/ai/generate-image.action.js.map +1 -1
- package/dist/custom/ai/run-decision.action.d.ts +45 -0
- package/dist/custom/ai/run-decision.action.d.ts.map +1 -0
- package/dist/custom/ai/run-decision.action.js +169 -0
- package/dist/custom/ai/run-decision.action.js.map +1 -0
- package/dist/custom/ai/semantic-entity-search.helper.d.ts +6 -0
- package/dist/custom/ai/semantic-entity-search.helper.d.ts.map +1 -1
- package/dist/custom/ai/semantic-entity-search.helper.js +16 -4
- package/dist/custom/ai/semantic-entity-search.helper.js.map +1 -1
- package/dist/custom/data/search-query-catalog.action.js +2 -2
- package/dist/custom/integration/api-rate-limiter.action.d.ts +4 -0
- package/dist/custom/integration/api-rate-limiter.action.d.ts.map +1 -1
- package/dist/custom/integration/api-rate-limiter.action.js +10 -2
- package/dist/custom/integration/api-rate-limiter.action.js.map +1 -1
- package/dist/custom/integration/gamma-generate-presentation.action.js +2 -2
- package/dist/custom/integration/integration-action-executor.d.ts +22 -22
- package/dist/custom/integration/integration-action-executor.js +83 -83
- package/dist/custom/interactive-forms/_shared.d.ts +69 -0
- package/dist/custom/interactive-forms/_shared.d.ts.map +1 -1
- package/dist/custom/interactive-forms/_shared.js +118 -38
- package/dist/custom/interactive-forms/_shared.js.map +1 -1
- package/dist/custom/interactive-forms/activate-interactive-form-version.action.js +25 -25
- package/dist/custom/interactive-forms/create-interactive-form.action.js +22 -22
- package/dist/custom/interactive-forms/modify-interactive-form.action.js +35 -35
- package/dist/custom/interactive-forms/revert-interactive-form.action.js +32 -32
- package/dist/custom/lists/_action-helpers.d.ts +10 -0
- package/dist/custom/lists/_action-helpers.d.ts.map +1 -1
- package/dist/custom/lists/_action-helpers.js +26 -6
- package/dist/custom/lists/_action-helpers.js.map +1 -1
- package/dist/custom/lists/add-view-results-to-list.action.js +8 -8
- package/dist/custom/lists/bulk-update-list-item-status.action.js +8 -8
- package/dist/custom/lists/compose-lists.action.js +14 -14
- package/dist/custom/lists/invite-to-list.action.js +10 -10
- package/dist/custom/lists/materialize-list-from-view.action.js +13 -13
- package/dist/custom/lists/move-list-members.action.js +12 -12
- package/dist/custom/lists/refresh-list-from-source.action.js +8 -8
- package/dist/custom/lists/resolve-audience.action.js +7 -7
- package/dist/custom/lists/revoke-list-invitation.action.js +3 -3
- package/dist/custom/lists/share-list.action.js +8 -8
- package/dist/custom/lists/unshare-list.action.js +3 -3
- package/dist/custom/record-cloning/clone-record.action.d.ts +15 -0
- package/dist/custom/record-cloning/clone-record.action.d.ts.map +1 -0
- package/dist/custom/record-cloning/clone-record.action.js +125 -0
- package/dist/custom/record-cloning/clone-record.action.js.map +1 -0
- package/dist/custom/record-cloning/clone-records.action.d.ts +15 -0
- package/dist/custom/record-cloning/clone-records.action.d.ts.map +1 -0
- package/dist/custom/record-cloning/clone-records.action.js +175 -0
- package/dist/custom/record-cloning/clone-records.action.js.map +1 -0
- package/dist/custom/utilities/address-services.action.js +2 -2
- package/dist/custom/utilities/artifact-builder-service.d.ts +16 -16
- package/dist/custom/utilities/artifact-builder-service.js +39 -39
- package/dist/custom/utilities/artifact-builder-service.js.map +1 -1
- package/dist/custom/utilities/docx-renderer.d.ts +17 -11
- package/dist/custom/utilities/docx-renderer.d.ts.map +1 -1
- package/dist/custom/utilities/docx-renderer.js +60 -48
- package/dist/custom/utilities/docx-renderer.js.map +1 -1
- package/dist/custom/utilities/json-param-helper.d.ts +6 -0
- package/dist/custom/utilities/json-param-helper.d.ts.map +1 -1
- package/dist/custom/utilities/json-param-helper.js +16 -4
- package/dist/custom/utilities/json-param-helper.js.map +1 -1
- package/dist/custom/utilities/pdf-renderer.d.ts +13 -7
- package/dist/custom/utilities/pdf-renderer.d.ts.map +1 -1
- package/dist/custom/utilities/pdf-renderer.js +27 -15
- package/dist/custom/utilities/pdf-renderer.js.map +1 -1
- package/dist/custom/utilities/vectorize-entity.action.js +1 -1
- package/dist/custom/utilities/vectorize-entity.action.js.map +1 -1
- package/dist/custom/utilities/xlsx-renderer.d.ts +19 -11
- package/dist/custom/utilities/xlsx-renderer.d.ts.map +1 -1
- package/dist/custom/utilities/xlsx-renderer.js +55 -39
- package/dist/custom/utilities/xlsx-renderer.js.map +1 -1
- package/dist/custom/visualization/create-svg-chart.action.js +23 -23
- package/dist/custom/visualization/create-svg-diagram.action.js +10 -10
- package/dist/custom/visualization/create-svg-infographic.action.js +4 -4
- package/dist/custom/visualization/create-svg-network.action.js +12 -12
- package/dist/custom/visualization/create-svg-sketch-diagram.action.js +10 -10
- package/dist/custom/visualization/create-svg-word-cloud.action.js +11 -11
- package/dist/custom/visualization/shared/svg-theming.d.ts +17 -0
- package/dist/custom/visualization/shared/svg-theming.d.ts.map +1 -1
- package/dist/custom/visualization/shared/svg-theming.js +34 -10
- package/dist/custom/visualization/shared/svg-theming.js.map +1 -1
- package/dist/custom/visualization/shared/svg-utils.d.ts +39 -0
- package/dist/custom/visualization/shared/svg-utils.d.ts.map +1 -1
- package/dist/custom/visualization/shared/svg-utils.js +81 -17
- package/dist/custom/visualization/shared/svg-utils.js.map +1 -1
- package/dist/custom/web/duckduckgo-rate-limiter.d.ts +17 -1
- package/dist/custom/web/duckduckgo-rate-limiter.d.ts.map +1 -1
- package/dist/custom/web/duckduckgo-rate-limiter.js +26 -6
- package/dist/custom/web/duckduckgo-rate-limiter.js.map +1 -1
- package/dist/custom/web/google-custom-search.action.js +2 -2
- package/dist/custom/web/rss-feed-parsing.d.ts +19 -0
- package/dist/custom/web/rss-feed-parsing.d.ts.map +1 -1
- package/dist/custom/web/rss-feed-parsing.js +45 -13
- package/dist/custom/web/rss-feed-parsing.js.map +1 -1
- package/dist/custom/web/rss-feed-read.action.js +5 -5
- package/dist/custom/web/tavily-search.action.js +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +42 -40
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { ListOperations } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { AddOutputParam, GetBooleanParam, GetStringParam, MissingParam, } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Materialize a new MJ List from a User View. Thin wrapper around
|
|
13
13
|
* `ListOperations.MaterializeFromView` — every drop-guard, permission, and
|
|
@@ -30,13 +30,13 @@ import { addOutputParam, getBooleanParam, getStringParam, missingParam, } from '
|
|
|
30
30
|
*/
|
|
31
31
|
let MaterializeListFromViewAction = class MaterializeListFromViewAction extends BaseAction {
|
|
32
32
|
async InternalRunAction(params) {
|
|
33
|
-
const viewId =
|
|
34
|
-
const listName =
|
|
33
|
+
const viewId = GetStringParam(params, 'ViewID');
|
|
34
|
+
const listName = GetStringParam(params, 'ListName');
|
|
35
35
|
if (!viewId)
|
|
36
|
-
return
|
|
36
|
+
return MissingParam('ViewID');
|
|
37
37
|
if (!listName)
|
|
38
|
-
return
|
|
39
|
-
const refreshMode = (
|
|
38
|
+
return MissingParam('ListName');
|
|
39
|
+
const refreshMode = (GetStringParam(params, 'RefreshMode') ?? 'Additive');
|
|
40
40
|
if (refreshMode !== 'Additive' && refreshMode !== 'Sync') {
|
|
41
41
|
return {
|
|
42
42
|
Success: false,
|
|
@@ -46,17 +46,17 @@ let MaterializeListFromViewAction = class MaterializeListFromViewAction extends
|
|
|
46
46
|
}
|
|
47
47
|
const opts = {
|
|
48
48
|
ListName: listName,
|
|
49
|
-
CategoryId:
|
|
50
|
-
Description:
|
|
51
|
-
RememberLineage:
|
|
52
|
-
UseSnapshot:
|
|
49
|
+
CategoryId: GetStringParam(params, 'CategoryID'),
|
|
50
|
+
Description: GetStringParam(params, 'Description'),
|
|
51
|
+
RememberLineage: GetBooleanParam(params, 'RememberLineage', true),
|
|
52
|
+
UseSnapshot: GetBooleanParam(params, 'UseSnapshot', false),
|
|
53
53
|
RefreshMode: refreshMode,
|
|
54
54
|
};
|
|
55
55
|
const ops = new ListOperations(params.ContextUser, params.Provider);
|
|
56
56
|
const result = await ops.MaterializeFromView(viewId, opts);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
AddOutputParam(params, 'CreatedListID', result.CreatedListId);
|
|
58
|
+
AddOutputParam(params, 'Added', result.Counts?.Added);
|
|
59
|
+
AddOutputParam(params, 'Failed', result.Counts?.Failed);
|
|
60
60
|
return {
|
|
61
61
|
Success: result.Success,
|
|
62
62
|
ResultCode: result.ResultCode,
|
|
@@ -8,7 +8,7 @@ import { BaseAction } from '@memberjunction/actions';
|
|
|
8
8
|
import { Metadata, RunView } from '@memberjunction/core';
|
|
9
9
|
import { RegisterClass } from '@memberjunction/global';
|
|
10
10
|
import { ListOperations } from '@memberjunction/lists';
|
|
11
|
-
import {
|
|
11
|
+
import { AddOutputParam, GetBooleanParam, GetJsonParam, GetStringParam, MissingParam, } from './_action-helpers.js';
|
|
12
12
|
/**
|
|
13
13
|
* Move a set of records from one list to another. Implemented as a
|
|
14
14
|
* thin wrapper over `ListOperations` semantics:
|
|
@@ -25,13 +25,13 @@ import { addOutputParam, getBooleanParam, getJsonParam, getStringParam, missingP
|
|
|
25
25
|
*/
|
|
26
26
|
let MoveListMembersAction = class MoveListMembersAction extends BaseAction {
|
|
27
27
|
async InternalRunAction(params) {
|
|
28
|
-
const sourceListId =
|
|
29
|
-
const targetListId =
|
|
30
|
-
const recordIds =
|
|
28
|
+
const sourceListId = GetStringParam(params, 'SourceListID');
|
|
29
|
+
const targetListId = GetStringParam(params, 'TargetListID');
|
|
30
|
+
const recordIds = GetJsonParam(params, 'RecordIDs');
|
|
31
31
|
if (!sourceListId)
|
|
32
|
-
return
|
|
32
|
+
return MissingParam('SourceListID');
|
|
33
33
|
if (!targetListId)
|
|
34
|
-
return
|
|
34
|
+
return MissingParam('TargetListID');
|
|
35
35
|
if (!recordIds || !Array.isArray(recordIds) || recordIds.length === 0) {
|
|
36
36
|
return {
|
|
37
37
|
Success: false,
|
|
@@ -39,7 +39,7 @@ let MoveListMembersAction = class MoveListMembersAction extends BaseAction {
|
|
|
39
39
|
Message: "'RecordIDs' must be a JSON-stringified non-empty string array",
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
const mode = (
|
|
42
|
+
const mode = (GetStringParam(params, 'Mode') ?? 'move').toLowerCase();
|
|
43
43
|
if (mode !== 'move' && mode !== 'copy') {
|
|
44
44
|
return {
|
|
45
45
|
Success: false,
|
|
@@ -47,7 +47,7 @@ let MoveListMembersAction = class MoveListMembersAction extends BaseAction {
|
|
|
47
47
|
Message: `Mode must be 'move' or 'copy' (got '${mode}')`,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
const confirmDrops =
|
|
50
|
+
const confirmDrops = GetBooleanParam(params, 'ConfirmDrops', false);
|
|
51
51
|
if (mode === 'move' && !confirmDrops) {
|
|
52
52
|
return {
|
|
53
53
|
Success: false,
|
|
@@ -129,10 +129,10 @@ let MoveListMembersAction = class MoveListMembersAction extends BaseAction {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
AddOutputParam(params, 'Added', added);
|
|
133
|
+
AddOutputParam(params, 'Removed', removed);
|
|
134
|
+
AddOutputParam(params, 'Failed', failedAdds);
|
|
135
|
+
AddOutputParam(params, 'Errors', errors);
|
|
136
136
|
const success = failedAdds === 0 && errors.length === failedAdds;
|
|
137
137
|
return {
|
|
138
138
|
Success: success,
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { ListOperations } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { AddOutputParam, GetBooleanParam, GetStringParam, MissingParam, } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Refresh an existing List against its captured source view.
|
|
13
13
|
*
|
|
@@ -19,10 +19,10 @@ import { addOutputParam, getBooleanParam, getStringParam, missingParam, } from '
|
|
|
19
19
|
*/
|
|
20
20
|
let RefreshListFromSourceAction = class RefreshListFromSourceAction extends BaseAction {
|
|
21
21
|
async InternalRunAction(params) {
|
|
22
|
-
const listId =
|
|
22
|
+
const listId = GetStringParam(params, 'ListID');
|
|
23
23
|
if (!listId)
|
|
24
|
-
return
|
|
25
|
-
const mode = (
|
|
24
|
+
return MissingParam('ListID');
|
|
25
|
+
const mode = (GetStringParam(params, 'Mode') ?? 'Additive');
|
|
26
26
|
if (mode !== 'Additive' && mode !== 'Sync') {
|
|
27
27
|
return {
|
|
28
28
|
Success: false,
|
|
@@ -30,12 +30,12 @@ let RefreshListFromSourceAction = class RefreshListFromSourceAction extends Base
|
|
|
30
30
|
Message: `Mode must be 'Additive' or 'Sync', got '${mode}'`,
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
const confirmDrops =
|
|
33
|
+
const confirmDrops = GetBooleanParam(params, 'ConfirmDrops', false);
|
|
34
34
|
const ops = new ListOperations(params.ContextUser, params.Provider);
|
|
35
35
|
const result = await ops.RefreshFromSource(listId, mode, { ConfirmDrops: confirmDrops });
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
AddOutputParam(params, 'Added', result.Counts?.Added);
|
|
37
|
+
AddOutputParam(params, 'Removed', result.Counts?.Removed);
|
|
38
|
+
AddOutputParam(params, 'Failed', result.Counts?.Failed);
|
|
39
39
|
return {
|
|
40
40
|
Success: result.Success,
|
|
41
41
|
ResultCode: result.ResultCode,
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { AudienceResolver } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { AddOutputParam, GetJsonParam, GetStringParam, MissingParam, } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Resolve an `AudienceSource` to its current record IDs.
|
|
13
13
|
*
|
|
@@ -20,14 +20,14 @@ import { addOutputParam, getJsonParam, getStringParam, missingParam, } from './_
|
|
|
20
20
|
*/
|
|
21
21
|
let ResolveAudienceAction = class ResolveAudienceAction extends BaseAction {
|
|
22
22
|
async InternalRunAction(params) {
|
|
23
|
-
const source =
|
|
23
|
+
const source = GetJsonParam(params, 'Source');
|
|
24
24
|
if (!source) {
|
|
25
25
|
// Surface a clear contract hint — `getJsonParam` swallows parse
|
|
26
26
|
// errors, so the caller might be supplying a non-JSON string by
|
|
27
27
|
// mistake. Distinguish missing vs unparseable for grep-ability.
|
|
28
|
-
const raw =
|
|
28
|
+
const raw = GetStringParam(params, 'Source');
|
|
29
29
|
if (raw == null || raw.length === 0)
|
|
30
|
-
return
|
|
30
|
+
return MissingParam('Source');
|
|
31
31
|
return {
|
|
32
32
|
Success: false,
|
|
33
33
|
ResultCode: 'INVALID_PARAMETER',
|
|
@@ -37,9 +37,9 @@ let ResolveAudienceAction = class ResolveAudienceAction extends BaseAction {
|
|
|
37
37
|
const resolver = new AudienceResolver(params.ContextUser, params.Provider);
|
|
38
38
|
try {
|
|
39
39
|
const resolved = await resolver.Resolve(source);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
AddOutputParam(params, 'EntityName', resolved.EntityName);
|
|
41
|
+
AddOutputParam(params, 'RecordCount', resolved.RecordIds.length);
|
|
42
|
+
AddOutputParam(params, 'RecordIDs', resolved.RecordIds);
|
|
43
43
|
return {
|
|
44
44
|
Success: true,
|
|
45
45
|
ResultCode: 'SUCCESS',
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { ListSharing } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { GetStringParam, MissingParam } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Revoke a pending List invitation before acceptance. Once an invitation
|
|
13
13
|
* has been accepted, callers should `Unshare List` the resulting
|
|
@@ -16,9 +16,9 @@ import { getStringParam, missingParam } from './_action-helpers.js';
|
|
|
16
16
|
*/
|
|
17
17
|
let RevokeListInvitationAction = class RevokeListInvitationAction extends BaseAction {
|
|
18
18
|
async InternalRunAction(params) {
|
|
19
|
-
const invitationId =
|
|
19
|
+
const invitationId = GetStringParam(params, 'InvitationID');
|
|
20
20
|
if (!invitationId)
|
|
21
|
-
return
|
|
21
|
+
return MissingParam('InvitationID');
|
|
22
22
|
const sharing = new ListSharing(params.ContextUser, params.Provider);
|
|
23
23
|
const result = await sharing.RevokeInvitation(invitationId);
|
|
24
24
|
return { Success: result.Success, ResultCode: result.ResultCode, Message: result.Message };
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { ListSharing } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { AddOutputParam, GetStringParam, MissingParam } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Grant a direct share on a List to a user or role. Mirrors
|
|
13
13
|
* `ListSharing.Share` — idempotent at the (list, target) pair.
|
|
@@ -20,11 +20,11 @@ import { addOutputParam, getStringParam, missingParam } from './_action-helpers.
|
|
|
20
20
|
*/
|
|
21
21
|
let ShareListAction = class ShareListAction extends BaseAction {
|
|
22
22
|
async InternalRunAction(params) {
|
|
23
|
-
const listId =
|
|
24
|
-
const targetKind =
|
|
25
|
-
const targetId =
|
|
23
|
+
const listId = GetStringParam(params, 'ListID');
|
|
24
|
+
const targetKind = GetStringParam(params, 'TargetKind');
|
|
25
|
+
const targetId = GetStringParam(params, 'TargetID');
|
|
26
26
|
if (!listId)
|
|
27
|
-
return
|
|
27
|
+
return MissingParam('ListID');
|
|
28
28
|
if (targetKind !== 'user' && targetKind !== 'role') {
|
|
29
29
|
return {
|
|
30
30
|
Success: false,
|
|
@@ -33,8 +33,8 @@ let ShareListAction = class ShareListAction extends BaseAction {
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
if (!targetId)
|
|
36
|
-
return
|
|
37
|
-
const level = (
|
|
36
|
+
return MissingParam('TargetID');
|
|
37
|
+
const level = (GetStringParam(params, 'PermissionLevel') ?? 'View');
|
|
38
38
|
if (level !== 'View' && level !== 'Edit' && level !== 'Owner') {
|
|
39
39
|
return {
|
|
40
40
|
Success: false,
|
|
@@ -45,7 +45,7 @@ let ShareListAction = class ShareListAction extends BaseAction {
|
|
|
45
45
|
const target = targetKind === 'user' ? { kind: 'user', userId: targetId } : { kind: 'role', roleId: targetId };
|
|
46
46
|
const sharing = new ListSharing(params.ContextUser, params.Provider);
|
|
47
47
|
const result = await sharing.Share({ ListID: listId, Target: target, PermissionLevel: level });
|
|
48
|
-
|
|
48
|
+
AddOutputParam(params, 'PermissionID', result.PermissionID);
|
|
49
49
|
return { Success: result.Success, ResultCode: result.ResultCode, Message: result.Message };
|
|
50
50
|
}
|
|
51
51
|
};
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { BaseAction } from '@memberjunction/actions';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { ListSharing } from '@memberjunction/lists';
|
|
10
|
-
import {
|
|
10
|
+
import { GetStringParam, MissingParam } from './_action-helpers.js';
|
|
11
11
|
/**
|
|
12
12
|
* Revoke a previously-granted permission row. Soft-revokes (sets
|
|
13
13
|
* `Status='Revoked'` on `MJResourcePermission`) so the audit trail
|
|
@@ -15,9 +15,9 @@ import { getStringParam, missingParam } from './_action-helpers.js';
|
|
|
15
15
|
*/
|
|
16
16
|
let UnshareListAction = class UnshareListAction extends BaseAction {
|
|
17
17
|
async InternalRunAction(params) {
|
|
18
|
-
const permissionId =
|
|
18
|
+
const permissionId = GetStringParam(params, 'PermissionID');
|
|
19
19
|
if (!permissionId)
|
|
20
|
-
return
|
|
20
|
+
return MissingParam('PermissionID');
|
|
21
21
|
const sharing = new ListSharing(params.ContextUser, params.Provider);
|
|
22
22
|
const result = await sharing.Unshare(permissionId);
|
|
23
23
|
return { Success: result.Success, ResultCode: result.ResultCode, Message: result.Message };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file clone-record.action.ts
|
|
3
|
+
* Core action to clone a single entity record.
|
|
4
|
+
* @see plans/record-cloning/README.md §11.2
|
|
5
|
+
*/
|
|
6
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
7
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
8
|
+
export declare class CloneRecordAction extends BaseAction {
|
|
9
|
+
protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
|
|
10
|
+
private getStringParam;
|
|
11
|
+
private getBooleanParam;
|
|
12
|
+
private getParamValue;
|
|
13
|
+
private pushOutput;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=clone-record.action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-record.action.d.ts","sourceRoot":"","sources":["../../../src/custom/record-cloning/clone-record.action.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAKrD,qBACa,iBAAkB,SAAQ,UAAU;cAC7B,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAqFvF,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,UAAU;CAGrB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file clone-record.action.ts
|
|
3
|
+
* Core action to clone a single entity record.
|
|
4
|
+
* @see plans/record-cloning/README.md §11.2
|
|
5
|
+
*/
|
|
6
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
7
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
9
|
+
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;
|
|
10
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
11
|
+
};
|
|
12
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
13
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
14
|
+
import { CompositeKey, Metadata } from '@memberjunction/core';
|
|
15
|
+
import { RecordCloneEngine, ToRecordKeyString } from '@memberjunction/record-cloning';
|
|
16
|
+
let CloneRecordAction = class CloneRecordAction extends BaseAction {
|
|
17
|
+
async InternalRunAction(params) {
|
|
18
|
+
try {
|
|
19
|
+
const entityName = this.getStringParam(params, 'entityname');
|
|
20
|
+
if (!entityName) {
|
|
21
|
+
return {
|
|
22
|
+
Success: false,
|
|
23
|
+
ResultCode: 'MISSING_PARAMETERS',
|
|
24
|
+
Message: 'EntityName is required',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const recordId = this.getStringParam(params, 'recordid');
|
|
28
|
+
if (!recordId) {
|
|
29
|
+
return {
|
|
30
|
+
Success: false,
|
|
31
|
+
ResultCode: 'MISSING_PARAMETERS',
|
|
32
|
+
Message: 'RecordID is required',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const md = params.Provider ?? new Metadata();
|
|
36
|
+
const entityInfo = md.EntityByName(entityName);
|
|
37
|
+
if (!entityInfo) {
|
|
38
|
+
return {
|
|
39
|
+
Success: false,
|
|
40
|
+
ResultCode: 'ENTITY_NOT_FOUND',
|
|
41
|
+
Message: `Entity '${entityName}' not found in metadata`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
let options = {};
|
|
45
|
+
const optionsRaw = this.getParamValue(params, 'options');
|
|
46
|
+
if (optionsRaw) {
|
|
47
|
+
if (typeof optionsRaw === 'string') {
|
|
48
|
+
try {
|
|
49
|
+
options = JSON.parse(optionsRaw);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return {
|
|
53
|
+
Success: false,
|
|
54
|
+
ResultCode: 'INVALID_JSON',
|
|
55
|
+
Message: `Failed to parse Options JSON: ${e.message}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (typeof optionsRaw === 'object') {
|
|
60
|
+
options = optionsRaw;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (this.getBooleanParam(params, 'dryrun', false)) {
|
|
64
|
+
options.DryRun = true;
|
|
65
|
+
}
|
|
66
|
+
const key = CompositeKey.FromRecordID(entityInfo, recordId);
|
|
67
|
+
const result = await new RecordCloneEngine(params.Provider).Clone({ EntityName: entityName, SourceRecordKey: key, Options: options }, params.ContextUser);
|
|
68
|
+
// Nothing below may throw: once Clone returns, a committed clone must be reported as one,
|
|
69
|
+
// or a retry would create duplicates.
|
|
70
|
+
const dryRun = options.DryRun === true;
|
|
71
|
+
const newRecordId = dryRun ? null : ToRecordKeyString(result.Roots?.[0]?.TargetKey) || null;
|
|
72
|
+
this.pushOutput(params, 'NewRecordID', newRecordId);
|
|
73
|
+
this.pushOutput(params, 'CloneLogID', result.CloneLogID ?? null);
|
|
74
|
+
this.pushOutput(params, 'CreatedCount', dryRun ? result.Counts?.Create ?? 0 : result.Created?.length ?? 0);
|
|
75
|
+
this.pushOutput(params, 'Warnings', result.Warnings ?? []);
|
|
76
|
+
return {
|
|
77
|
+
Success: result.Success,
|
|
78
|
+
ResultCode: result.ResultCode ?? (result.Success ? 'SUCCESS' : 'FAILED'),
|
|
79
|
+
Message: !result.Success
|
|
80
|
+
? result.ErrorMessage || `Clone failed with status ${result.ResultCode}`
|
|
81
|
+
: dryRun
|
|
82
|
+
? `Plan computed: ${result.Counts?.Create ?? 0} records to create`
|
|
83
|
+
: `Successfully cloned record ${recordId} to ${newRecordId}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
Success: false,
|
|
89
|
+
ResultCode: 'FAILED',
|
|
90
|
+
Message: error.message,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
getStringParam(params, name) {
|
|
95
|
+
const value = params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
96
|
+
if (value == null)
|
|
97
|
+
return undefined;
|
|
98
|
+
const s = String(value).trim();
|
|
99
|
+
return s.length > 0 ? s : undefined;
|
|
100
|
+
}
|
|
101
|
+
getBooleanParam(params, name, defaultValue) {
|
|
102
|
+
const value = params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
103
|
+
if (value == null)
|
|
104
|
+
return defaultValue;
|
|
105
|
+
if (typeof value === 'boolean')
|
|
106
|
+
return value;
|
|
107
|
+
const s = String(value).trim().toLowerCase();
|
|
108
|
+
if (s === 'true' || s === '1' || s === 'yes')
|
|
109
|
+
return true;
|
|
110
|
+
if (s === 'false' || s === '0' || s === 'no')
|
|
111
|
+
return false;
|
|
112
|
+
return defaultValue;
|
|
113
|
+
}
|
|
114
|
+
getParamValue(params, name) {
|
|
115
|
+
return params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
116
|
+
}
|
|
117
|
+
pushOutput(params, name, value) {
|
|
118
|
+
params.Params.push({ Name: name, Type: 'Output', Value: value });
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
CloneRecordAction = __decorate([
|
|
122
|
+
RegisterClass(BaseAction, 'Clone Record')
|
|
123
|
+
], CloneRecordAction);
|
|
124
|
+
export { CloneRecordAction };
|
|
125
|
+
//# sourceMappingURL=clone-record.action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-record.action.js","sourceRoot":"","sources":["../../../src/custom/record-cloning/clone-record.action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file clone-records.action.ts
|
|
3
|
+
* Core action to clone multiple entity records in bulk.
|
|
4
|
+
* @see plans/record-cloning/README.md §11.2
|
|
5
|
+
*/
|
|
6
|
+
import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
7
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
8
|
+
export declare class CloneRecordsAction extends BaseAction {
|
|
9
|
+
protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
|
|
10
|
+
private getStringParam;
|
|
11
|
+
private getBooleanParam;
|
|
12
|
+
private getParamValue;
|
|
13
|
+
private pushOutput;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=clone-records.action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-records.action.d.ts","sourceRoot":"","sources":["../../../src/custom/record-cloning/clone-records.action.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAiBrD,qBACa,kBAAmB,SAAQ,UAAU;cAC9B,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAsIvF,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,UAAU;CAGrB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file clone-records.action.ts
|
|
3
|
+
* Core action to clone multiple entity records in bulk.
|
|
4
|
+
* @see plans/record-cloning/README.md §11.2
|
|
5
|
+
*/
|
|
6
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
7
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
9
|
+
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;
|
|
10
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
11
|
+
};
|
|
12
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
13
|
+
import { BaseAction } from '@memberjunction/actions';
|
|
14
|
+
import { CompositeKey, Metadata } from '@memberjunction/core';
|
|
15
|
+
import { BATCH_AUTHORIZATION, CloneAuthorizer, RecordCloneEngine, ToRecordKeyString } from '@memberjunction/record-cloning';
|
|
16
|
+
let CloneRecordsAction = class CloneRecordsAction extends BaseAction {
|
|
17
|
+
async InternalRunAction(params) {
|
|
18
|
+
try {
|
|
19
|
+
const entityName = this.getStringParam(params, 'entityname');
|
|
20
|
+
if (!entityName) {
|
|
21
|
+
return {
|
|
22
|
+
Success: false,
|
|
23
|
+
ResultCode: 'MISSING_PARAMETERS',
|
|
24
|
+
Message: 'EntityName is required',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const recordIdsParam = this.getParamValue(params, 'recordids');
|
|
28
|
+
if (!recordIdsParam) {
|
|
29
|
+
return {
|
|
30
|
+
Success: false,
|
|
31
|
+
ResultCode: 'MISSING_PARAMETERS',
|
|
32
|
+
Message: 'RecordIDs is required',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const md = params.Provider ?? new Metadata();
|
|
36
|
+
const entityInfo = md.EntityByName(entityName);
|
|
37
|
+
if (!entityInfo) {
|
|
38
|
+
return {
|
|
39
|
+
Success: false,
|
|
40
|
+
ResultCode: 'ENTITY_NOT_FOUND',
|
|
41
|
+
Message: `Entity '${entityName}' not found in metadata`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
let recordIds = [];
|
|
45
|
+
if (Array.isArray(recordIdsParam)) {
|
|
46
|
+
recordIds = recordIdsParam.map((id) => String(id));
|
|
47
|
+
}
|
|
48
|
+
else if (typeof recordIdsParam === 'string') {
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(recordIdsParam);
|
|
51
|
+
if (Array.isArray(parsed)) {
|
|
52
|
+
recordIds = parsed.map((id) => String(id));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
recordIds = recordIdsParam.split(',').map((s) => s.trim()).filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
recordIds = recordIdsParam.split(',').map((s) => s.trim()).filter(Boolean);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (recordIds.length === 0) {
|
|
63
|
+
return {
|
|
64
|
+
Success: false,
|
|
65
|
+
ResultCode: 'MISSING_PARAMETERS',
|
|
66
|
+
Message: 'At least one RecordID must be specified',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let options = {};
|
|
70
|
+
const optionsRaw = this.getParamValue(params, 'options');
|
|
71
|
+
if (optionsRaw) {
|
|
72
|
+
if (typeof optionsRaw === 'string') {
|
|
73
|
+
try {
|
|
74
|
+
options = JSON.parse(optionsRaw);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return {
|
|
78
|
+
Success: false,
|
|
79
|
+
ResultCode: 'INVALID_JSON',
|
|
80
|
+
Message: `Failed to parse Options JSON: ${e.message}`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (typeof optionsRaw === 'object') {
|
|
85
|
+
options = optionsRaw;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (this.getBooleanParam(params, 'dryrun', false)) {
|
|
89
|
+
options.DryRun = true;
|
|
90
|
+
}
|
|
91
|
+
const dryRun = options.DryRun === true;
|
|
92
|
+
if (!new CloneAuthorizer(params.Provider ?? Metadata.Provider).CanBatchClone(params.ContextUser)) {
|
|
93
|
+
return {
|
|
94
|
+
Success: false,
|
|
95
|
+
ResultCode: 'FORBIDDEN',
|
|
96
|
+
Message: `Cloning several records at once requires the '${BATCH_AUTHORIZATION}' authorization.`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// Each root is its own clone and its own transaction, so one failure doesn't undo the others.
|
|
100
|
+
// Results say which records were cloned, so a retry can target only the failures.
|
|
101
|
+
const engine = new RecordCloneEngine(params.Provider);
|
|
102
|
+
const results = [];
|
|
103
|
+
for (const id of recordIds) {
|
|
104
|
+
try {
|
|
105
|
+
const result = await engine.Clone({ EntityName: entityName, SourceRecordKey: CompositeKey.FromRecordID(entityInfo, id), Options: options }, params.ContextUser);
|
|
106
|
+
results.push({
|
|
107
|
+
RecordID: id,
|
|
108
|
+
Success: result.Success,
|
|
109
|
+
ResultCode: result.ResultCode ?? (result.Success ? 'SUCCESS' : 'FAILED'),
|
|
110
|
+
NewRecordID: dryRun ? null : ToRecordKeyString(result.Roots?.[0]?.TargetKey) || null,
|
|
111
|
+
CloneLogID: result.CloneLogID ?? null,
|
|
112
|
+
CreatedCount: dryRun ? result.Counts?.Create ?? 0 : result.Created?.length ?? 0,
|
|
113
|
+
Warnings: result.Warnings ?? [],
|
|
114
|
+
ErrorMessage: result.ErrorMessage,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
results.push({ RecordID: id, Success: false, ResultCode: 'FAILED', NewRecordID: null, CloneLogID: null, CreatedCount: 0, Warnings: [], ErrorMessage: err.message });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const succeeded = results.filter((r) => r.Success);
|
|
122
|
+
const createdCount = results.reduce((sum, r) => sum + r.CreatedCount, 0);
|
|
123
|
+
this.pushOutput(params, 'CreatedCount', createdCount);
|
|
124
|
+
this.pushOutput(params, 'CloneLogID', succeeded[0]?.CloneLogID ?? null);
|
|
125
|
+
this.pushOutput(params, 'Results', results);
|
|
126
|
+
this.pushOutput(params, 'Warnings', results.flatMap((r) => r.Warnings));
|
|
127
|
+
const allOk = succeeded.length === results.length;
|
|
128
|
+
const verb = dryRun ? 'Planned' : 'Cloned';
|
|
129
|
+
return {
|
|
130
|
+
Success: allOk,
|
|
131
|
+
ResultCode: allOk ? 'SUCCESS' : succeeded.length > 0 ? 'PARTIAL' : results[0]?.ResultCode ?? 'FAILED',
|
|
132
|
+
Message: `${verb} ${succeeded.length} of ${results.length} root records (${createdCount} records ${dryRun ? 'to create' : 'created'}).` +
|
|
133
|
+
(allOk ? '' : ` Failed: ${results.filter((r) => !r.Success).map((r) => `${r.RecordID} (${r.ErrorMessage ?? r.ResultCode})`).join('; ')}`),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
Success: false,
|
|
139
|
+
ResultCode: 'FAILED',
|
|
140
|
+
Message: error.message,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
getStringParam(params, name) {
|
|
145
|
+
const value = params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
146
|
+
if (value == null)
|
|
147
|
+
return undefined;
|
|
148
|
+
const s = String(value).trim();
|
|
149
|
+
return s.length > 0 ? s : undefined;
|
|
150
|
+
}
|
|
151
|
+
getBooleanParam(params, name, defaultValue) {
|
|
152
|
+
const value = params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
153
|
+
if (value == null)
|
|
154
|
+
return defaultValue;
|
|
155
|
+
if (typeof value === 'boolean')
|
|
156
|
+
return value;
|
|
157
|
+
const s = String(value).trim().toLowerCase();
|
|
158
|
+
if (s === 'true' || s === '1' || s === 'yes')
|
|
159
|
+
return true;
|
|
160
|
+
if (s === 'false' || s === '0' || s === 'no')
|
|
161
|
+
return false;
|
|
162
|
+
return defaultValue;
|
|
163
|
+
}
|
|
164
|
+
getParamValue(params, name) {
|
|
165
|
+
return params.Params.find((p) => p.Name.trim().toLowerCase() === name)?.Value;
|
|
166
|
+
}
|
|
167
|
+
pushOutput(params, name, value) {
|
|
168
|
+
params.Params.push({ Name: name, Type: 'Output', Value: value });
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
CloneRecordsAction = __decorate([
|
|
172
|
+
RegisterClass(BaseAction, 'Clone Records')
|
|
173
|
+
], CloneRecordsAction);
|
|
174
|
+
export { CloneRecordsAction };
|
|
175
|
+
//# sourceMappingURL=clone-records.action.js.map
|