@aglyn/plugins-workflows 1.0.0-beta.182 → 1.0.0-beta.184
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/README.md +3 -1
- package/package.json +12 -12
- package/src/lib/components/host-actions-card.component.js +15 -10
- package/src/lib/components/host-actions-card.component.js.map +1 -1
- package/src/lib/engine/run-event-actions.d.ts +29 -0
- package/src/lib/engine/run-event-actions.js +38 -11
- package/src/lib/engine/run-event-actions.js.map +1 -1
- package/src/lib/model/action-test-run.d.ts +36 -0
- package/src/lib/model/action-test-run.js +49 -0
- package/src/lib/model/action-test-run.js.map +1 -0
- package/src/lib/server/action-test-run-route.d.ts +91 -0
- package/src/lib/server/action-test-run-route.js +243 -0
- package/src/lib/server/action-test-run-route.js.map +1 -0
- package/src/lib/server-console.d.ts +2 -2
- package/src/lib/server-console.js +5 -2
- package/src/lib/server-console.js.map +1 -1
|
@@ -14,7 +14,7 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
|
14
14
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
|
-
*/ import { ACTION_MAX_EVENT_DEPTH, ACTION_MAX_STEPS, checkEntitlement, planLabelGrantingFeature, checkQuota, WEBHOOK_URL_PATTERN, evaluateExpression, evaluateStepGuard, evaluateTriggerConditions, FLOW_TIMED_OUT_FIELD, flowEmailTopicId, hostPublicOrigin, isClientActionStep, isCrmActionStep, isFlowSuspendingStep, buildDatasetRecordValues, datasetDisplayName, contactCampaignFieldPath, datasetIntegrityFields, datasetIntegrityUpdate, describeStepOutcome, effectiveDatasetModel, normalizeTriggerConditions, resolveOrgEntitlements, runWorkflow, WORKFLOW_MAX_STEPS } from "@aglyn/aglyn/server";
|
|
17
|
+
*/ import { ACTION_MAX_EVENT_DEPTH, ACTION_MAX_STEPS, checkEntitlement, consentGroupForHost, planLabelGrantingFeature, checkQuota, WEBHOOK_URL_PATTERN, evaluateExpression, evaluateStepGuard, evaluateTriggerConditions, FLOW_TIMED_OUT_FIELD, flowEmailTopicId, hostPublicOrigin, isClientActionStep, isCrmActionStep, isFlowSuspendingStep, buildDatasetRecordValues, datasetDisplayName, contactCampaignFieldPath, datasetIntegrityFields, datasetIntegrityUpdate, describeStepOutcome, effectiveDatasetModel, normalizeTriggerConditions, resolveOrgEntitlements, runWorkflow, WORKFLOW_MAX_STEPS } from "@aglyn/aglyn/server";
|
|
18
18
|
import { isDeferrableSendResult, isEmailConfigured, sendEmail, sendFailureReason } from "@aglyn/shared-util-email";
|
|
19
19
|
import { dataStorageRefusal, enrollListMember, firebaseAdmin, flowEmailRefusal, getOrgForHost, hostSendingIdentity, meterHostEmail, notifyHostManagers, consentGroupForSite, orgDataCollectionForHost, orgDataQueryForHost, resolveOrgIdForHost } from "@aglyn/tenant-data-admin";
|
|
20
20
|
import { announceDatasetRecordChange } from "@aglyn/tenant-data-admin/server/dataset-live-pages";
|
|
@@ -465,7 +465,7 @@ async function datasetAppendRefusal(env, datasetRef) {
|
|
|
465
465
|
link: `/${hostId}`
|
|
466
466
|
}));
|
|
467
467
|
} else if (step.type === 'sendEmail') {
|
|
468
|
-
var _payload_, _hostPublicOrigin, _step_topicId, _step_subject, _step_body;
|
|
468
|
+
var _payload_, _hostPublicOrigin, _step_topicId, _step_subject, _step_body, _env_org;
|
|
469
469
|
var _step_toField, _this;
|
|
470
470
|
const to = String((_payload_ = payload[((_step_toField = step.toField) == null ? void 0 : _step_toField.trim()) || 'email']) != null ? _payload_ : '').trim();
|
|
471
471
|
if (!isEmailConfigured()) return failed('email is not configured');
|
|
@@ -572,10 +572,14 @@ async function datasetAppendRefusal(env, datasetRef) {
|
|
|
572
572
|
} : {}, {
|
|
573
573
|
// `topicId` is `''` for a step that belongs to no stream, which
|
|
574
574
|
// every reader of it treats as absent — see `flowEmailTopicId`.
|
|
575
|
+
// The consent group comes off the org the run already holds, so the
|
|
576
|
+
// gate honors an unsubscribe from any site of a declared group —
|
|
577
|
+
// the sender this site mails as — at no extra read.
|
|
575
578
|
marketing: {
|
|
576
579
|
hostId,
|
|
577
580
|
siteBase,
|
|
578
|
-
topicId
|
|
581
|
+
topicId,
|
|
582
|
+
consentHostIds: consentGroupForHost((_env_org = env.org) != null ? _env_org : null, hostId).hostIds
|
|
579
583
|
}
|
|
580
584
|
}));
|
|
581
585
|
/*
|
|
@@ -1249,27 +1253,45 @@ async function datasetAppendRefusal(env, datasetRef) {
|
|
|
1249
1253
|
* event name would wrongly fire sibling actions with different
|
|
1250
1254
|
* thresholds. Same gates and metering as the event runner.
|
|
1251
1255
|
*/ export async function runSingleAction(hostId, actionId, event, payload = {}) {
|
|
1256
|
+
return (await runSingleActionOutcome(hostId, actionId, event, payload)).alerts;
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* {@link runSingleAction}, answering what it did as well as the alerts: whether
|
|
1260
|
+
* the steps ran and, when they did not, which gate stopped them.
|
|
1261
|
+
*
|
|
1262
|
+
* One body for both, so the console's test run meets exactly the gates a
|
|
1263
|
+
* page's dispatch meets — the switch, the event, the conditions, the plan and
|
|
1264
|
+
* the month's allowance — and is metered and recorded the same way.
|
|
1265
|
+
*/ export async function runSingleActionOutcome(hostId, actionId, event, payload = {}) {
|
|
1252
1266
|
const alerts = [];
|
|
1267
|
+
const skipped = (reason, limit)=>_extends({
|
|
1268
|
+
ran: false,
|
|
1269
|
+
skipped: reason,
|
|
1270
|
+
alerts
|
|
1271
|
+
}, limit === undefined ? {} : {
|
|
1272
|
+
limit
|
|
1273
|
+
});
|
|
1253
1274
|
try {
|
|
1254
1275
|
var _ref, _ref1, _ref2;
|
|
1255
1276
|
var _action_trigger;
|
|
1256
1277
|
const firestore = firebaseAdmin.app().firestore();
|
|
1257
1278
|
const hostRef = firestore.collection('hosts').doc(hostId);
|
|
1258
1279
|
const doc = await hostRef.collection('actions').doc(actionId).get();
|
|
1259
|
-
if (!doc.exists || doc.get('deletedAt')
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1280
|
+
if (!doc.exists || doc.get('deletedAt')) return skipped('missing');
|
|
1281
|
+
if (doc.get('enabled') === false) return skipped('disabled');
|
|
1262
1282
|
const action = doc.data();
|
|
1263
1283
|
// Only site-event actions may be dispatched externally — server
|
|
1264
1284
|
// events flow through their own emitters.
|
|
1265
|
-
if (String((_ref = (_action_trigger = action.trigger) == null ? void 0 : _action_trigger.event) != null ? _ref : '') !== String(event))
|
|
1285
|
+
if (String((_ref = (_action_trigger = action.trigger) == null ? void 0 : _action_trigger.event) != null ? _ref : '') !== String(event)) {
|
|
1286
|
+
return skipped('event');
|
|
1287
|
+
}
|
|
1266
1288
|
// Structured payload conditions (AGL-557; AND/OR chaining AGL-565):
|
|
1267
1289
|
// the single-action dispatch path honors them too, so
|
|
1268
1290
|
// client-evaluated triggers can't bypass them.
|
|
1269
1291
|
if (!evaluateTriggerConditions(action.trigger, _extends({
|
|
1270
1292
|
event
|
|
1271
1293
|
}, payload))) {
|
|
1272
|
-
return
|
|
1294
|
+
return skipped('conditions');
|
|
1273
1295
|
}
|
|
1274
1296
|
const monthKey = new Date().toISOString().slice(0, 7);
|
|
1275
1297
|
const runCounterRef = hostRef.collection('counters').doc('actionRuns');
|
|
@@ -1280,13 +1302,13 @@ async function datasetAppendRefusal(env, datasetRef) {
|
|
|
1280
1302
|
{
|
|
1281
1303
|
var _counterSnapshot_get;
|
|
1282
1304
|
const org = owner == null ? void 0 : owner.org;
|
|
1283
|
-
if (!checkEntitlement(org, 'actions')) return
|
|
1305
|
+
if (!checkEntitlement(org, 'actions')) return skipped('plan');
|
|
1284
1306
|
webhooksAllowed = checkEntitlement(org, 'webhooks');
|
|
1285
1307
|
crmAllowed = checkEntitlement(org, 'crm');
|
|
1286
1308
|
const limit = resolveOrgEntitlements(org).actionRunsPerMonth;
|
|
1287
1309
|
const counterSnapshot = await runCounterRef.get();
|
|
1288
1310
|
const used = Number((_counterSnapshot_get = counterSnapshot.get(monthKey)) != null ? _counterSnapshot_get : 0);
|
|
1289
|
-
if (used + 1 > limit) return
|
|
1311
|
+
if (used + 1 > limit) return skipped('allowance', limit);
|
|
1290
1312
|
}
|
|
1291
1313
|
const env = {
|
|
1292
1314
|
hostId,
|
|
@@ -1307,10 +1329,15 @@ async function datasetAppendRefusal(env, datasetRef) {
|
|
|
1307
1329
|
}, {
|
|
1308
1330
|
merge: true
|
|
1309
1331
|
}).catch(()=>undefined);
|
|
1332
|
+
return {
|
|
1333
|
+
ran: true,
|
|
1334
|
+
skipped: null,
|
|
1335
|
+
alerts
|
|
1336
|
+
};
|
|
1310
1337
|
} catch (error) {
|
|
1311
1338
|
console.error('runSingleAction failed', hostId, actionId, error);
|
|
1339
|
+
return skipped('failed');
|
|
1312
1340
|
}
|
|
1313
|
-
return alerts;
|
|
1314
1341
|
}
|
|
1315
1342
|
/**
|
|
1316
1343
|
* Ends an enrollment its automation may no longer run, and says why in the
|