@dereekb/dbx-components-mcp 14.14.0 → 14.15.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/dbx-components-mcp.js
CHANGED
|
@@ -10,7 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
// packages/dbx-components-mcp/package.json
|
|
11
11
|
var package_default = {
|
|
12
12
|
name: "@dereekb/dbx-components-mcp",
|
|
13
|
-
version: "14.
|
|
13
|
+
version: "14.15.0",
|
|
14
14
|
sideEffects: false,
|
|
15
15
|
type: "module",
|
|
16
16
|
bin: {
|
|
@@ -22,8 +22,8 @@ var package_default = {
|
|
|
22
22
|
"ts-morph": "^21.0.0"
|
|
23
23
|
},
|
|
24
24
|
peerDependencies: {
|
|
25
|
-
"@dereekb/dbx-cli": "14.
|
|
26
|
-
"@dereekb/util": "14.
|
|
25
|
+
"@dereekb/dbx-cli": "14.15.0",
|
|
26
|
+
"@dereekb/util": "14.15.0"
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
|
|
@@ -2496,10 +2496,18 @@ var FIREBASE_MODELS = [
|
|
|
2496
2496
|
tsType: "Maybe<NotificationHealthCheck>",
|
|
2497
2497
|
optional: true,
|
|
2498
2498
|
description: "The result of the most recent notification delivery health check run for this user."
|
|
2499
|
+
},
|
|
2500
|
+
{
|
|
2501
|
+
name: "tso",
|
|
2502
|
+
longName: "textStoppedPhoneNumbers",
|
|
2503
|
+
converter: "optionalFirestoreArray<E164PhoneNumber>({ filterUnique: true, dontStoreIfEmpty: true })",
|
|
2504
|
+
tsType: "Maybe<E164PhoneNumber[]>",
|
|
2505
|
+
optional: true,
|
|
2506
|
+
description: "Phone numbers that replied STOP to a text. Texts to a number in this list resolve to off, at send time and in the health check."
|
|
2499
2507
|
}
|
|
2500
2508
|
],
|
|
2501
2509
|
enums: [],
|
|
2502
|
-
detectionHints: ["b", "x", "dc", "gc", "bc", "ns", "hc"],
|
|
2510
|
+
detectionHints: ["b", "x", "dc", "gc", "bc", "ns", "hc", "tso"],
|
|
2503
2511
|
description: "A global notification user profile that tracks notification preferences and box subscriptions.",
|
|
2504
2512
|
modelGroup: "Notification",
|
|
2505
2513
|
collectionKind: "root",
|
|
@@ -6492,15 +6500,16 @@ function parseSignalInput(property) {
|
|
|
6492
6500
|
...defaultValue === void 0 ? {} : { defaultValue }
|
|
6493
6501
|
};
|
|
6494
6502
|
}
|
|
6503
|
+
var SIGNAL_INPUT_FUNCTION_NAMES = /* @__PURE__ */ new Set(["input", "model"]);
|
|
6495
6504
|
function classifySignalInputCall(call) {
|
|
6496
6505
|
const expression = call.getExpression();
|
|
6497
6506
|
let result;
|
|
6498
|
-
if (Node9.isIdentifier(expression) && expression.getText()
|
|
6507
|
+
if (Node9.isIdentifier(expression) && SIGNAL_INPUT_FUNCTION_NAMES.has(expression.getText())) {
|
|
6499
6508
|
result = "plain";
|
|
6500
6509
|
} else if (Node9.isPropertyAccessExpression(expression)) {
|
|
6501
6510
|
const baseExpr = expression.getExpression();
|
|
6502
6511
|
const propertyName = expression.getName();
|
|
6503
|
-
if (Node9.isIdentifier(baseExpr) && baseExpr.getText()
|
|
6512
|
+
if (Node9.isIdentifier(baseExpr) && SIGNAL_INPUT_FUNCTION_NAMES.has(baseExpr.getText()) && propertyName === "required") {
|
|
6504
6513
|
result = "required";
|
|
6505
6514
|
}
|
|
6506
6515
|
}
|
|
@@ -24747,9 +24756,9 @@ var RULE_CATALOG = [
|
|
|
24747
24756
|
{
|
|
24748
24757
|
code: "NOTIF_TASK_IN_VALIDATE_WITHOUT_HANDLER",
|
|
24749
24758
|
source: "dbx_notification_m_validate_app",
|
|
24750
|
-
severity: "
|
|
24759
|
+
severity: "error",
|
|
24751
24760
|
title: "A task type appears in `validate:` but has no matching `handlers:` registration",
|
|
24752
|
-
whatItFlags: "A task type appears in `validate:` but has no matching `handlers:` registration.",
|
|
24761
|
+
whatItFlags: "A task type appears in `validate:` but has no matching `handlers:` registration.\n`notificationTaskService()` throws at startup for this.",
|
|
24753
24762
|
whenItApplies: "When `notificationTaskService({ validate, handlers })` lists a task type in `validate:` that the `handlers:` traversal doesn't reach.",
|
|
24754
24763
|
whenItDoesNotApply: "Tasks whose handler is provided by an upstream module (covered by the trust list).",
|
|
24755
24764
|
canonicalFix: "Add the matching `NotificationTaskServiceTaskHandlerConfig` for the task and include it in `handlers:`."
|
|
@@ -24870,6 +24879,22 @@ var RULE_CATALOG = [
|
|
|
24870
24879
|
whenItDoesNotApply: "Spreads from trust-listed `@dereekb/*` modules.",
|
|
24871
24880
|
canonicalFix: "Declare the missing function or import it from a trusted module."
|
|
24872
24881
|
},
|
|
24882
|
+
{
|
|
24883
|
+
code: "NOTIF_TEMPLATE_FACTORY_UNLISTED_DELIVERY_METHOD",
|
|
24884
|
+
source: "dbx_notification_m_validate_app",
|
|
24885
|
+
severity: "warning",
|
|
24886
|
+
title: "A template's message factory returns channel content for a delivery method its `NotificationTemplateTypeInfo` does not list in `userConfigurableDeliveryMethods`",
|
|
24887
|
+
whatItFlags: "A template's message factory returns channel content for a delivery method its `NotificationTemplateTypeInfo` does not list in `userConfigurableDeliveryMethods`.",
|
|
24888
|
+
whenItApplies: "Template types whose info declares an explicit `userConfigurableDeliveryMethods` array and whose handler factory (or the function its `factory:` names) builds an object literal with `emailContent`, `textContent` or `notificationSummaryContent` for a method the array leaves out.",
|
|
24889
|
+
whenItDoesNotApply: "Infos without `userConfigurableDeliveryMethods` (the defaults list email, text and notification summary), lists the scanner cannot read statically, and content built outside the factory's own source \u2014 the send pipeline's runtime warning (`notificationMessageFunctionWithUnlistedDeliveryMethodsWarning`) still covers those.",
|
|
24890
|
+
canonicalFix: "Stop returning the unlisted content from the factory, or add the delivery method to the info's `userConfigurableDeliveryMethods`.",
|
|
24891
|
+
seeAlso: [
|
|
24892
|
+
{
|
|
24893
|
+
kind: "artifact",
|
|
24894
|
+
target: "notification-template"
|
|
24895
|
+
}
|
|
24896
|
+
]
|
|
24897
|
+
},
|
|
24873
24898
|
{
|
|
24874
24899
|
code: "NOTIF_TEMPLATE_INFO_MISSING",
|
|
24875
24900
|
source: "dbx_notification_m_validate_app",
|
|
@@ -31566,7 +31591,8 @@ __export(notification_m_validate_app_exports, {
|
|
|
31566
31591
|
extractAppNotifications: () => extractAppNotifications,
|
|
31567
31592
|
formatResult: () => formatResult6,
|
|
31568
31593
|
inspectAppNotifications: () => inspectAppNotifications,
|
|
31569
|
-
validateAppNotifications: () => validateAppNotifications
|
|
31594
|
+
validateAppNotifications: () => validateAppNotifications,
|
|
31595
|
+
validateExtractedAppNotifications: () => validateExtractedAppNotifications
|
|
31570
31596
|
});
|
|
31571
31597
|
|
|
31572
31598
|
// packages/dbx-cli/validate/src/lib/notification-m-validate-app/extract.ts
|
|
@@ -31587,6 +31613,25 @@ var TEMPLATE_CONFIGS_ARRAY_FACTORY_SUFFIX = "NotificationTemplateServiceConfigsA
|
|
|
31587
31613
|
var TEMPLATE_CONFIGS_ARRAY_TOKEN = "NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN";
|
|
31588
31614
|
var CHECKPOINT_ALIAS_SUFFIX = "NotificationTaskCheckpoint";
|
|
31589
31615
|
var TASK_DATA_INTERFACE_SUFFIX = "NotificationTaskData";
|
|
31616
|
+
var USER_CONFIGURABLE_DELIVERY_METHODS_PROPERTY = "userConfigurableDeliveryMethods";
|
|
31617
|
+
var DELIVERY_METHOD_ENUM = "NotificationDeliveryMethod";
|
|
31618
|
+
var DELIVERY_METHOD_BY_MEMBER = /* @__PURE__ */ new Map([
|
|
31619
|
+
["EMAIL", "EMAIL"],
|
|
31620
|
+
["TEXT", "TEXT"],
|
|
31621
|
+
["PUSH", "PUSH"],
|
|
31622
|
+
["NOTIFICATION_SUMMARY", "NOTIFICATION_SUMMARY"]
|
|
31623
|
+
]);
|
|
31624
|
+
var DELIVERY_METHOD_BY_CODE = /* @__PURE__ */ new Map([
|
|
31625
|
+
["e", "EMAIL"],
|
|
31626
|
+
["t", "TEXT"],
|
|
31627
|
+
["p", "PUSH"],
|
|
31628
|
+
["n", "NOTIFICATION_SUMMARY"]
|
|
31629
|
+
]);
|
|
31630
|
+
var CONTENT_PROPERTY_DELIVERY_METHODS = /* @__PURE__ */ new Map([
|
|
31631
|
+
["emailContent", "EMAIL"],
|
|
31632
|
+
["textContent", "TEXT"],
|
|
31633
|
+
["notificationSummaryContent", "NOTIFICATION_SUMMARY"]
|
|
31634
|
+
]);
|
|
31590
31635
|
function extractAppNotifications(inspection) {
|
|
31591
31636
|
const { componentSources, apiSources } = buildInMemoryProject(inspection);
|
|
31592
31637
|
const trustedExternalIdentifiers = collectTrustedExternalIdentifiers([...componentSources, ...apiSources]);
|
|
@@ -31660,13 +31705,16 @@ function extractTemplateTypeInfos(sources) {
|
|
|
31660
31705
|
if (!nameMatches && !typeMatches) continue;
|
|
31661
31706
|
const obj = asObjectLiteral(decl.getInitializer());
|
|
31662
31707
|
if (!obj) continue;
|
|
31708
|
+
const deliveryMethods = readUserConfigurableDeliveryMethods(obj, sf);
|
|
31663
31709
|
const entry = {
|
|
31664
31710
|
symbolName: name,
|
|
31665
31711
|
typeConstantName: readIdentifierProperty(obj, "type"),
|
|
31666
31712
|
humanName: readStringProperty2(obj, "name"),
|
|
31667
31713
|
description: readStringProperty2(obj, "description"),
|
|
31668
|
-
|
|
31714
|
+
notificationModelIdentity: readIdentifierProperty(obj, "notificationModelIdentity"),
|
|
31669
31715
|
targetModelIdentity: readIdentifierProperty(obj, "targetModelIdentity"),
|
|
31716
|
+
userConfigurableDeliveryMethods: deliveryMethods.methods,
|
|
31717
|
+
userConfigurableDeliveryMethodsSource: deliveryMethods.source,
|
|
31670
31718
|
sourceFile: rel,
|
|
31671
31719
|
line: decl.getStartLineNumber()
|
|
31672
31720
|
};
|
|
@@ -31676,6 +31724,44 @@ function extractTemplateTypeInfos(sources) {
|
|
|
31676
31724
|
}
|
|
31677
31725
|
return out;
|
|
31678
31726
|
}
|
|
31727
|
+
function readUserConfigurableDeliveryMethods(obj, sf) {
|
|
31728
|
+
const value = unwrapAsExpressions(getPropertyInitializer(obj, USER_CONFIGURABLE_DELIVERY_METHODS_PROPERTY));
|
|
31729
|
+
let result;
|
|
31730
|
+
if (!value || isNullishLiteral(value)) {
|
|
31731
|
+
result = { methods: void 0, source: "default" };
|
|
31732
|
+
} else if (Node28.isIdentifier(value)) {
|
|
31733
|
+
result = readDeliveryMethodsArray(asArrayLiteral(findLocalVariable(sf, value.getText())?.getInitializer()));
|
|
31734
|
+
} else {
|
|
31735
|
+
result = readDeliveryMethodsArray(asArrayLiteral(value));
|
|
31736
|
+
}
|
|
31737
|
+
return result;
|
|
31738
|
+
}
|
|
31739
|
+
function readDeliveryMethodsArray(arr) {
|
|
31740
|
+
const methods = [];
|
|
31741
|
+
let readable = arr !== void 0;
|
|
31742
|
+
for (const el of arr?.getElements() ?? []) {
|
|
31743
|
+
const method = readDeliveryMethodElement(unwrapAsExpressions(el));
|
|
31744
|
+
if (!method) {
|
|
31745
|
+
readable = false;
|
|
31746
|
+
} else if (!methods.includes(method)) {
|
|
31747
|
+
methods.push(method);
|
|
31748
|
+
}
|
|
31749
|
+
}
|
|
31750
|
+
const result = readable ? { methods, source: "declared" } : { methods: void 0, source: "unresolved" };
|
|
31751
|
+
return result;
|
|
31752
|
+
}
|
|
31753
|
+
function readDeliveryMethodElement(el) {
|
|
31754
|
+
let result;
|
|
31755
|
+
if (el && Node28.isPropertyAccessExpression(el) && el.getExpression().getText() === DELIVERY_METHOD_ENUM) {
|
|
31756
|
+
result = DELIVERY_METHOD_BY_MEMBER.get(el.getName());
|
|
31757
|
+
} else if (el && Node28.isStringLiteral(el)) {
|
|
31758
|
+
result = DELIVERY_METHOD_BY_CODE.get(el.getLiteralText());
|
|
31759
|
+
}
|
|
31760
|
+
return result;
|
|
31761
|
+
}
|
|
31762
|
+
function isNullishLiteral(node) {
|
|
31763
|
+
return node !== void 0 && (Node28.isIdentifier(node) && node.getText() === "undefined" || node.getKind() === SyntaxKind12.NullKeyword);
|
|
31764
|
+
}
|
|
31679
31765
|
function extractTemplateInfoAggregates(sources) {
|
|
31680
31766
|
const out = [];
|
|
31681
31767
|
for (const sf of sources) {
|
|
@@ -32037,6 +32123,7 @@ function collectFromSingleEntryFactory(name, out, index) {
|
|
|
32037
32123
|
out.push({
|
|
32038
32124
|
typeIdentifier: typeIdent,
|
|
32039
32125
|
factoryFunctionName: name,
|
|
32126
|
+
contentDeliveryMethods: collectContentDeliveryMethods([fn.node, factoryPropertyFunctionNode(obj, index)]),
|
|
32040
32127
|
sourceFile: fn.relPath,
|
|
32041
32128
|
line: obj.getStartLineNumber()
|
|
32042
32129
|
});
|
|
@@ -32063,7 +32150,7 @@ function consumeArrayEntryFactoryElement(options) {
|
|
|
32063
32150
|
chaseDirectSingleEntryFactoryCall(inner, out, index);
|
|
32064
32151
|
return;
|
|
32065
32152
|
}
|
|
32066
|
-
recordInlineEntryFactoryObject({ inner, factoryName, relPath, out });
|
|
32153
|
+
recordInlineEntryFactoryObject({ inner, factoryName, relPath, out, index });
|
|
32067
32154
|
}
|
|
32068
32155
|
function chaseSpreadEntryFactoryCall(inner, out, index) {
|
|
32069
32156
|
if (!Node28.isCallExpression(inner)) return;
|
|
@@ -32080,12 +32167,40 @@ function chaseDirectSingleEntryFactoryCall(inner, out, index) {
|
|
|
32080
32167
|
}
|
|
32081
32168
|
}
|
|
32082
32169
|
function recordInlineEntryFactoryObject(options) {
|
|
32083
|
-
const { inner, factoryName, relPath, out } = options;
|
|
32170
|
+
const { inner, factoryName, relPath, out, index } = options;
|
|
32084
32171
|
const obj = asObjectLiteral(inner);
|
|
32085
32172
|
if (!obj) return;
|
|
32086
32173
|
const typeIdent = readIdentifierProperty(obj, "type");
|
|
32087
32174
|
if (!typeIdent) return;
|
|
32088
|
-
|
|
32175
|
+
const contentDeliveryMethods = collectContentDeliveryMethods([obj, factoryPropertyFunctionNode(obj, index)]);
|
|
32176
|
+
out.push({ typeIdentifier: typeIdent, factoryFunctionName: factoryName, contentDeliveryMethods, sourceFile: relPath, line: obj.getStartLineNumber() });
|
|
32177
|
+
}
|
|
32178
|
+
function factoryPropertyFunctionNode(obj, index) {
|
|
32179
|
+
const name = readIdentifierProperty(obj, "factory");
|
|
32180
|
+
return name ? index.functionsByName.get(name)?.node : void 0;
|
|
32181
|
+
}
|
|
32182
|
+
function collectContentDeliveryMethods(nodes) {
|
|
32183
|
+
const found = /* @__PURE__ */ new Set();
|
|
32184
|
+
for (const node of nodes) {
|
|
32185
|
+
if (node) {
|
|
32186
|
+
scanContentDeliveryMethods(node, found);
|
|
32187
|
+
}
|
|
32188
|
+
}
|
|
32189
|
+
return Array.from(CONTENT_PROPERTY_DELIVERY_METHODS.values()).filter((method) => found.has(method));
|
|
32190
|
+
}
|
|
32191
|
+
function scanContentDeliveryMethods(node, found) {
|
|
32192
|
+
for (const prop of node.getDescendantsOfKind(SyntaxKind12.PropertyAssignment)) {
|
|
32193
|
+
const method = CONTENT_PROPERTY_DELIVERY_METHODS.get(prop.getName());
|
|
32194
|
+
if (method && !isNullishLiteral(unwrapAsExpressions(prop.getInitializer()))) {
|
|
32195
|
+
found.add(method);
|
|
32196
|
+
}
|
|
32197
|
+
}
|
|
32198
|
+
for (const prop of node.getDescendantsOfKind(SyntaxKind12.ShorthandPropertyAssignment)) {
|
|
32199
|
+
const method = CONTENT_PROPERTY_DELIVERY_METHODS.get(prop.getName());
|
|
32200
|
+
if (method) {
|
|
32201
|
+
found.add(method);
|
|
32202
|
+
}
|
|
32203
|
+
}
|
|
32089
32204
|
}
|
|
32090
32205
|
function extractTaskServiceCalls(sources, index, trustedExternal) {
|
|
32091
32206
|
const out = [];
|
|
@@ -32373,6 +32488,7 @@ function runRules6(inspection, extracted) {
|
|
|
32373
32488
|
checkTemplateInfoPairing(extracted, violations);
|
|
32374
32489
|
checkTemplateInfoRecord(extracted, violations);
|
|
32375
32490
|
checkTemplateHandlerFactory(extracted, violations);
|
|
32491
|
+
checkTemplateDeliveryMethods(extracted, violations);
|
|
32376
32492
|
checkTasks(extracted, violations);
|
|
32377
32493
|
checkDuplicates2(extracted, violations);
|
|
32378
32494
|
return violations;
|
|
@@ -32541,6 +32657,27 @@ function checkTemplateHandlerFactory(extracted, violations) {
|
|
|
32541
32657
|
});
|
|
32542
32658
|
}
|
|
32543
32659
|
}
|
|
32660
|
+
function checkTemplateDeliveryMethods(extracted, violations) {
|
|
32661
|
+
const infoByTypeConstant = /* @__PURE__ */ new Map();
|
|
32662
|
+
for (const info of extracted.templateTypeInfos) {
|
|
32663
|
+
if (info.typeConstantName) infoByTypeConstant.set(info.typeConstantName, info);
|
|
32664
|
+
}
|
|
32665
|
+
for (const entry of extracted.templateHandlerEntries) {
|
|
32666
|
+
const info = infoByTypeConstant.get(entry.typeIdentifier);
|
|
32667
|
+
const listed = info?.userConfigurableDeliveryMethodsSource === "declared" ? info.userConfigurableDeliveryMethods : void 0;
|
|
32668
|
+
if (!listed) continue;
|
|
32669
|
+
const unlisted = entry.contentDeliveryMethods.filter((method) => !listed.includes(method));
|
|
32670
|
+
if (unlisted.length === 0) continue;
|
|
32671
|
+
const listedText = listed.length > 0 ? listed.join(", ") : "none";
|
|
32672
|
+
pushViolation8(violations, {
|
|
32673
|
+
code: "NOTIF_TEMPLATE_FACTORY_UNLISTED_DELIVERY_METHOD",
|
|
32674
|
+
severity: "warning",
|
|
32675
|
+
message: `Template handler factory \`${entry.factoryFunctionName ?? "<anonymous>"}\` for \`${entry.typeIdentifier}\` builds content for ${unlisted.join(", ")}, but \`${info?.symbolName}\` only lists ${listedText} in \`userConfigurableDeliveryMethods\`. This is the build-time counterpart of the send pipeline's runtime unlisted-delivery-method warning.`,
|
|
32676
|
+
side: "api",
|
|
32677
|
+
file: entry.sourceFile
|
|
32678
|
+
});
|
|
32679
|
+
}
|
|
32680
|
+
}
|
|
32544
32681
|
function checkTasks(extracted, violations) {
|
|
32545
32682
|
if (extracted.taskTypeConstants.length === 0) return;
|
|
32546
32683
|
flagTasksMissingFromAllArrays(extracted, violations);
|
|
@@ -32687,8 +32824,7 @@ function flagValidateWithoutHandler(options) {
|
|
|
32687
32824
|
if (!lenientHandlerTypeIdentifiers.has(name) && !extracted.trustedExternalIdentifiers.has(name)) {
|
|
32688
32825
|
pushViolation8(violations, {
|
|
32689
32826
|
code: "NOTIF_TASK_IN_VALIDATE_WITHOUT_HANDLER",
|
|
32690
|
-
|
|
32691
|
-
message: `Task type \`${name}\` appears in \`notificationTaskService({ validate })\` but has no matching handler in the \`handlers\` array.`,
|
|
32827
|
+
message: `Task type \`${name}\` appears in \`notificationTaskService({ validate })\` but has no matching handler in the \`handlers\` array. \`notificationTaskService()\` throws at startup for this.`,
|
|
32692
32828
|
side: "api",
|
|
32693
32829
|
file: call.sourceFile
|
|
32694
32830
|
});
|
|
@@ -32874,12 +33010,11 @@ async function inspectAppNotifications(componentDir, apiDir) {
|
|
|
32874
33010
|
}
|
|
32875
33011
|
|
|
32876
33012
|
// packages/dbx-cli/validate/src/lib/notification-m-validate-app/index.ts
|
|
32877
|
-
function
|
|
32878
|
-
const extracted = extractAppNotifications(inspection);
|
|
33013
|
+
function validateExtractedAppNotifications(input) {
|
|
32879
33014
|
const violations = [];
|
|
32880
33015
|
let errorCount = 0;
|
|
32881
33016
|
let warningCount = 0;
|
|
32882
|
-
for (const v of runRules6(inspection, extracted)) {
|
|
33017
|
+
for (const v of runRules6(input.inspection, input.extracted)) {
|
|
32883
33018
|
violations.push(v);
|
|
32884
33019
|
if (v.severity === "error") {
|
|
32885
33020
|
errorCount += 1;
|
|
@@ -32891,11 +33026,14 @@ function validateAppNotifications(inspection, options) {
|
|
|
32891
33026
|
violations,
|
|
32892
33027
|
errorCount,
|
|
32893
33028
|
warningCount,
|
|
32894
|
-
componentDir:
|
|
32895
|
-
apiDir:
|
|
33029
|
+
componentDir: input.componentDir,
|
|
33030
|
+
apiDir: input.apiDir
|
|
32896
33031
|
};
|
|
32897
33032
|
return result;
|
|
32898
33033
|
}
|
|
33034
|
+
function validateAppNotifications(inspection, options) {
|
|
33035
|
+
return validateExtractedAppNotifications({ inspection, extracted: extractAppNotifications(inspection), componentDir: options.componentDir, apiDir: options.apiDir });
|
|
33036
|
+
}
|
|
32899
33037
|
|
|
32900
33038
|
// packages/dbx-cli/validate/src/lib/notification-m-validate-folder/index.ts
|
|
32901
33039
|
var notification_m_validate_folder_exports = {};
|
|
@@ -38012,6 +38150,7 @@ function listAppAssets(inspection, options) {
|
|
|
38012
38150
|
// packages/dbx-cli/validate/src/lib/notification-m-list-app/index.ts
|
|
38013
38151
|
var notification_m_list_app_exports = {};
|
|
38014
38152
|
__export(notification_m_list_app_exports, {
|
|
38153
|
+
collectAppNotifications: () => collectAppNotifications,
|
|
38015
38154
|
formatReportAsJson: () => formatReportAsJson5,
|
|
38016
38155
|
formatReportAsMarkdown: () => formatReportAsMarkdown5,
|
|
38017
38156
|
listAppNotifications: () => listAppNotifications
|
|
@@ -38043,8 +38182,12 @@ function buildTemplateSummaries(extracted) {
|
|
|
38043
38182
|
const record = extracted.templateInfoRecord;
|
|
38044
38183
|
const resolved = new Set(record ? record.resolvedInfoIdentifiers : []);
|
|
38045
38184
|
const handlerByType = /* @__PURE__ */ new Map();
|
|
38185
|
+
const handlerEntriesByType = /* @__PURE__ */ new Map();
|
|
38046
38186
|
for (const entry of extracted.templateHandlerEntries) {
|
|
38047
38187
|
handlerByType.set(entry.typeIdentifier, { factoryFunctionName: entry.factoryFunctionName });
|
|
38188
|
+
const entries = handlerEntriesByType.get(entry.typeIdentifier) ?? [];
|
|
38189
|
+
entries.push(entry);
|
|
38190
|
+
handlerEntriesByType.set(entry.typeIdentifier, entries);
|
|
38048
38191
|
}
|
|
38049
38192
|
const templates = [];
|
|
38050
38193
|
for (const constant of extracted.templateTypeConstants) {
|
|
@@ -38056,8 +38199,11 @@ function buildTemplateSummaries(extracted) {
|
|
|
38056
38199
|
infoSymbolName: info?.symbolName,
|
|
38057
38200
|
humanName: info?.humanName,
|
|
38058
38201
|
description: info?.description,
|
|
38059
|
-
|
|
38202
|
+
notificationModelIdentity: info?.notificationModelIdentity,
|
|
38060
38203
|
targetModelIdentity: info?.targetModelIdentity,
|
|
38204
|
+
userConfigurableDeliveryMethods: info?.userConfigurableDeliveryMethods,
|
|
38205
|
+
userConfigurableDeliveryMethodsSource: info?.userConfigurableDeliveryMethodsSource,
|
|
38206
|
+
factoryContentDeliveryMethods: unionContentDeliveryMethods(handlerEntriesByType.get(constant.symbolName) ?? []),
|
|
38061
38207
|
inInfoRecord: info ? resolved.has(info.symbolName) : false,
|
|
38062
38208
|
hasFactory: handler !== void 0,
|
|
38063
38209
|
factoryFunctionName: handler?.factoryFunctionName,
|
|
@@ -38066,6 +38212,15 @@ function buildTemplateSummaries(extracted) {
|
|
|
38066
38212
|
}
|
|
38067
38213
|
return templates;
|
|
38068
38214
|
}
|
|
38215
|
+
function unionContentDeliveryMethods(entries) {
|
|
38216
|
+
const result = [];
|
|
38217
|
+
for (const entry of entries) {
|
|
38218
|
+
for (const method of entry.contentDeliveryMethods) {
|
|
38219
|
+
if (!result.includes(method)) result.push(method);
|
|
38220
|
+
}
|
|
38221
|
+
}
|
|
38222
|
+
return result;
|
|
38223
|
+
}
|
|
38069
38224
|
function buildTaskSummaries(extracted) {
|
|
38070
38225
|
const indices = buildTaskIndices(extracted);
|
|
38071
38226
|
const tasks = [];
|
|
@@ -38193,13 +38348,34 @@ function formatTemplateBlock(t) {
|
|
|
38193
38348
|
parts.push(heading);
|
|
38194
38349
|
if (t.humanName) parts.push(`- Human name: ${t.humanName}`);
|
|
38195
38350
|
if (t.description) parts.push(`- Description: ${t.description}`);
|
|
38196
|
-
if (t.
|
|
38351
|
+
if (t.notificationModelIdentity) parts.push(`- Notification model: \`${t.notificationModelIdentity}\``);
|
|
38197
38352
|
if (t.targetModelIdentity) parts.push(`- Target model: \`${t.targetModelIdentity}\``);
|
|
38353
|
+
const deliveryMethodsText = formatUserConfigurableDeliveryMethods(t);
|
|
38354
|
+
if (deliveryMethodsText) parts.push(`- User-configurable delivery methods: ${deliveryMethodsText}`);
|
|
38355
|
+
if (t.factoryContentDeliveryMethods.length > 0) parts.push(`- Factory returns content for: ${t.factoryContentDeliveryMethods.join(", ")}`);
|
|
38198
38356
|
const infoText = t.infoSymbolName ? code6(t.infoSymbolName) : "_Missing._";
|
|
38199
38357
|
const factorySuffix = t.factoryFunctionName ? ` (${code6(t.factoryFunctionName)})` : "";
|
|
38200
38358
|
parts.push(`- Info object: ${infoText}`, `- In info record: ${formatBool2(t.inInfoRecord)}`, `- Has factory: ${formatBool2(t.hasFactory)}${factorySuffix}`, `- Source: \`${t.sourceFile}\``);
|
|
38201
38359
|
return parts.join("\n");
|
|
38202
38360
|
}
|
|
38361
|
+
function formatUserConfigurableDeliveryMethods(t) {
|
|
38362
|
+
let result;
|
|
38363
|
+
switch (t.userConfigurableDeliveryMethodsSource) {
|
|
38364
|
+
case "declared":
|
|
38365
|
+
result = t.userConfigurableDeliveryMethods && t.userConfigurableDeliveryMethods.length > 0 ? t.userConfigurableDeliveryMethods.join(", ") : "_none_";
|
|
38366
|
+
break;
|
|
38367
|
+
case "default":
|
|
38368
|
+
result = "default";
|
|
38369
|
+
break;
|
|
38370
|
+
case "unresolved":
|
|
38371
|
+
result = "_unresolved_";
|
|
38372
|
+
break;
|
|
38373
|
+
case void 0:
|
|
38374
|
+
result = void 0;
|
|
38375
|
+
break;
|
|
38376
|
+
}
|
|
38377
|
+
return result;
|
|
38378
|
+
}
|
|
38203
38379
|
function formatTaskBlock(t) {
|
|
38204
38380
|
const parts = [];
|
|
38205
38381
|
const heading = t.typeCode ? `### ${t.typeCode} \u2014 \`${t.symbolName}\`` : `### \`${t.symbolName}\``;
|
|
@@ -44619,6 +44795,8 @@ var DBX_NOTIFICATION_M_VALIDATE_APP_TOOL = {
|
|
|
44619
44795
|
"",
|
|
44620
44796
|
"External identifiers imported from `@dereekb/*` are trusted \u2014 spreads and handler `type:` references that resolve into upstream packages do not produce orphan/unresolved errors.",
|
|
44621
44797
|
"",
|
|
44798
|
+
"The same checks run at build time through `dbx-cli-generate-notification-manifest` (see the `@dereekb/dbx-cli` README); this tool always scans the current source.",
|
|
44799
|
+
"",
|
|
44622
44800
|
"Provide both:",
|
|
44623
44801
|
"- `componentDir`: relative path to the `-firebase` component package (e.g. `components/demo-firebase`).",
|
|
44624
44802
|
"- `apiDir`: relative path to the API app (e.g. `apps/demo-api`).",
|
|
@@ -44655,7 +44833,9 @@ var { formatReportAsJson: formatReportAsJson11, formatReportAsMarkdown: formatRe
|
|
|
44655
44833
|
var DBX_NOTIFICATION_M_LIST_APP_TOOL = {
|
|
44656
44834
|
name: "dbx_notification_m_list_app",
|
|
44657
44835
|
description: [
|
|
44658
|
-
"List every notification template + notification task configured in a downstream `-firebase` component + API app pair. Each entry reports its type code, metadata (human name, description, notification/target model identity), and registration flags \u2014 `inInfoRecord` + `hasFactory` for templates, `inAllArray` + `inValidateList` + `hasHandler` for tasks.",
|
|
44836
|
+
"List every notification template + notification task configured in a downstream `-firebase` component + API app pair. Each entry reports its type code, metadata (human name, description, notification/target model identity), and registration flags \u2014 `inInfoRecord` + `hasFactory` for templates, `inAllArray` + `inValidateList` + `hasHandler` for tasks. Templates also report `userConfigurableDeliveryMethods` (with a `default` / `declared` / `unresolved` source) and `factoryContentDeliveryMethods`, the channels their factory builds content for.",
|
|
44837
|
+
"",
|
|
44838
|
+
"Its JSON is the report part of the `notification.manifest.json` that `dbx-cli-generate-notification-manifest` writes at build time; this tool always scans the current source.",
|
|
44659
44839
|
"",
|
|
44660
44840
|
"Cross-file resolution mirrors `dbx_notification_m_validate_app` \u2014 spreads and factory composition are traced through every `.ts` file under `src/lib/model/notification/` on the component side and `src/app/common/model/notification/` + `src/app/common/firebase/` on the API side.",
|
|
44661
44841
|
"",
|
|
@@ -51420,7 +51600,7 @@ export const <<SCREAMING>>_NOTIFICATION_TEMPLATE_TYPE_INFO: NotificationTemplate
|
|
|
51420
51600
|
type: <<SCREAMING>>_NOTIFICATION_TEMPLATE_TYPE,
|
|
51421
51601
|
name: '<<Pascal>>',
|
|
51422
51602
|
description: 'TODO: describe the <<Pascal>> notification.',
|
|
51423
|
-
|
|
51603
|
+
notificationModelIdentity: profileIdentity // TODO: replace with the model identity this notification targets
|
|
51424
51604
|
};
|
|
51425
51605
|
|
|
51426
51606
|
export interface <<Pascal>>NotificationData {
|
|
@@ -52075,6 +52255,31 @@ var STORAGEFILE_PROCESSOR_SUBTASK = {
|
|
|
52075
52255
|
seeAlso: ["storagefile-processor", "storagefile-purpose"],
|
|
52076
52256
|
verify: "Run `dbx_validate_app_storagefiles` \u2014 `STORAGEFILE_PROCESSING_SUBTASK_NOT_HANDLED` should clear once the flow entry is added."
|
|
52077
52257
|
};
|
|
52258
|
+
var NOTIFICATION_BUILD_TIME_CHECK_STEP = {
|
|
52259
|
+
heading: "Build-time check",
|
|
52260
|
+
path: "<apiDir>/project.json",
|
|
52261
|
+
body: [
|
|
52262
|
+
"Wire `dbx-cli-generate-notification-manifest` (from `@dereekb/dbx-cli`) as an nx target so broken notification wiring fails the build before deploy. It runs the same rules as `dbx_notification_m_validate_app`, writes `notification.manifest.json`, and exits non-zero on a validator error (warnings are written into the manifest). One target covers every template and task type; add it once per app.",
|
|
52263
|
+
"",
|
|
52264
|
+
"```json",
|
|
52265
|
+
'"generate-notification-manifest": {',
|
|
52266
|
+
' "executor": "nx:run-commands",',
|
|
52267
|
+
' "outputs": ["{workspaceRoot}/dist/<apiDir>/notification.manifest.json"],',
|
|
52268
|
+
' "inputs": [',
|
|
52269
|
+
' "{workspaceRoot}/<componentDir>/src/lib/model/notification/**/*.ts",',
|
|
52270
|
+
' "{workspaceRoot}/<apiDir>/src/app/common/model/notification/**/*.ts",',
|
|
52271
|
+
' "{workspaceRoot}/<apiDir>/src/app/common/firebase/**/*.ts"',
|
|
52272
|
+
" ],",
|
|
52273
|
+
' "options": {',
|
|
52274
|
+
' "command": "npx dbx-cli-generate-notification-manifest --component-dir=<componentDir> --api-dir=<apiDir> --output=dist/<apiDir>/notification.manifest.json",',
|
|
52275
|
+
' "cwd": "{workspaceRoot}"',
|
|
52276
|
+
" }",
|
|
52277
|
+
"}",
|
|
52278
|
+
"```",
|
|
52279
|
+
"",
|
|
52280
|
+
"**Wire into:** the API project's `build.dependsOn` (not `serve`: nothing reads the manifest at runtime, and the server's startup checks already cover `serve`)."
|
|
52281
|
+
].join("\n")
|
|
52282
|
+
};
|
|
52078
52283
|
var NOTIFICATION_TEMPLATE = {
|
|
52079
52284
|
artifact: "notification-template",
|
|
52080
52285
|
title: "Notification template",
|
|
@@ -52087,7 +52292,7 @@ var NOTIFICATION_TEMPLATE = {
|
|
|
52087
52292
|
body: [
|
|
52088
52293
|
"**Required exports:**",
|
|
52089
52294
|
"- `<NAME>_NOTIFICATION_TEMPLATE_TYPE: NotificationTemplateType = '<short_code>'`.",
|
|
52090
|
-
"- `<NAME>_NOTIFICATION_TEMPLATE_TYPE_INFO: NotificationTemplateTypeInfo` with `{ type, name, description,
|
|
52295
|
+
"- `<NAME>_NOTIFICATION_TEMPLATE_TYPE_INFO: NotificationTemplateTypeInfo` with `{ type, name, description, notificationModelIdentity, targetModelIdentity? }`.",
|
|
52091
52296
|
"- For multi-file workspaces, also declare `ALL_<MODULE>_NOTIFICATION_TEMPLATE_TYPE_INFOS: NotificationTemplateTypeInfo[]` and re-export the per-file infos.",
|
|
52092
52297
|
"",
|
|
52093
52298
|
"**Barrel:** Re-export from `<componentDir>/src/lib/model/notification/index.ts`."
|
|
@@ -52109,10 +52314,11 @@ var NOTIFICATION_TEMPLATE = {
|
|
|
52109
52314
|
"",
|
|
52110
52315
|
"**Wire into:** the top-level `<app>NotificationTemplateServiceConfigsArrayFactory(context)` \u2014 call the new factory inside its returned array. The configs-array factory is itself bound via `NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN` in the notification module."
|
|
52111
52316
|
].join("\n")
|
|
52112
|
-
}
|
|
52317
|
+
},
|
|
52318
|
+
NOTIFICATION_BUILD_TIME_CHECK_STEP
|
|
52113
52319
|
],
|
|
52114
52320
|
seeAlso: ["notification-task"],
|
|
52115
|
-
verify: "Run `dbx_notification_m_validate_app` to confirm both registration paths (info-record + handler factory) are wired, then `dbx_notification_m_list_app` to confirm the new template appears with `inInfoRecord: true` and `hasFactory: true
|
|
52321
|
+
verify: "Run `dbx_notification_m_validate_app` to confirm both registration paths (info-record + handler factory) are wired, then `dbx_notification_m_list_app` to confirm the new template appears with `inInfoRecord: true` and `hasFactory: true`, then `npx nx run <api-project>:generate-notification-manifest` runs the same checks the build does."
|
|
52116
52322
|
};
|
|
52117
52323
|
var NOTIFICATION_TASK = {
|
|
52118
52324
|
artifact: "notification-task",
|
|
@@ -52152,10 +52358,11 @@ var NOTIFICATION_TASK = {
|
|
|
52152
52358
|
{
|
|
52153
52359
|
heading: "Wire into task service",
|
|
52154
52360
|
body: ["Push the new handler config into the `handlers: [...]` array passed to `notificationTaskService({ validate, handlers })`. The `validate:` spread should already cover it via `ALL_NOTIFICATION_TASK_TYPES`."].join("\n")
|
|
52155
|
-
}
|
|
52361
|
+
},
|
|
52362
|
+
NOTIFICATION_BUILD_TIME_CHECK_STEP
|
|
52156
52363
|
],
|
|
52157
52364
|
seeAlso: ["notification-template"],
|
|
52158
|
-
verify: "Run `dbx_notification_m_validate_app` to confirm `inAllArray: true` + `hasHandler: true` for the new task type."
|
|
52365
|
+
verify: "Run `dbx_notification_m_validate_app` to confirm `inAllArray: true` + `hasHandler: true` for the new task type, then `npx nx run <api-project>:generate-notification-manifest` runs the same checks the build does."
|
|
52159
52366
|
};
|
|
52160
52367
|
var NESTJS_MODEL_MODULE = {
|
|
52161
52368
|
artifact: "nestjs-model-module",
|
|
@@ -93,13 +93,13 @@
|
|
|
93
93
|
{
|
|
94
94
|
"name": "buttonStyle",
|
|
95
95
|
"type": "Maybe<DbxButtonStyle>",
|
|
96
|
-
"description": "",
|
|
96
|
+
"description": "Style of the button. Individual style inputs (e.g. {@link color}, {@link raised}) take precedence.\n\nDeclared as a `model` so a directive composed onto the button (e.g. `dbxRotatingButton`) can set it.",
|
|
97
97
|
"required": false
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "color",
|
|
101
101
|
"type": "Maybe<ThemePalette | DbxColorInput>",
|
|
102
|
-
"description": "",
|
|
102
|
+
"description": "Color of the button. Takes precedence over the {@link buttonStyle} color.\n\nDeclared as a `model` so a directive composed onto the button (e.g. `dbxRotatingButton`) can set it.",
|
|
103
103
|
"required": false
|
|
104
104
|
},
|
|
105
105
|
{
|
|
@@ -854,6 +854,36 @@
|
|
|
854
854
|
"example": "<dbx-progress-spinner-button [config]=\"cfg\" (btnClick)=\"onClick()\"></dbx-progress-spinner-button>",
|
|
855
855
|
"minimalExample": "<dbx-progress-spinner-button [config]=\"cfg\"></dbx-progress-spinner-button>"
|
|
856
856
|
},
|
|
857
|
+
{
|
|
858
|
+
"slug": "rotating-button",
|
|
859
|
+
"category": "button",
|
|
860
|
+
"kind": "directive",
|
|
861
|
+
"selector": "[dbxRotatingButton]",
|
|
862
|
+
"className": "DbxRotatingButtonDirective",
|
|
863
|
+
"module": "@dereekb/dbx-web",
|
|
864
|
+
"description": "Turns a `dbx-button` into a rotating / multi-state button. Each click moves to the next configured state, and the\nstate's icon, text, style and aria-label are set on the button.\n\nUse {@link dbxTristateRotatingButtonConfig} for a three-state / 3-phase (default/on/off) toggle. The directive sets the\nbutton's `icon`, `text`, `buttonStyle` and `ariaLabel`, so configure those through the config rather than on the button.\n\nThe button stops click propagation by default, so a rotating button works inside clickable list rows.",
|
|
865
|
+
"inputs": [
|
|
866
|
+
{
|
|
867
|
+
"name": "dbxRotatingButton",
|
|
868
|
+
"type": "Maybe<DbxRotatingButtonConfig<T>>",
|
|
869
|
+
"description": "",
|
|
870
|
+
"required": false
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"name": "dbxRotatingButtonValue",
|
|
874
|
+
"type": "Maybe<T>",
|
|
875
|
+
"description": "The current value. Two-way bindable with `[(dbxRotatingButtonValue)]`.",
|
|
876
|
+
"required": false
|
|
877
|
+
}
|
|
878
|
+
],
|
|
879
|
+
"outputs": [],
|
|
880
|
+
"relatedSlugs": [
|
|
881
|
+
"button",
|
|
882
|
+
"icon-button"
|
|
883
|
+
],
|
|
884
|
+
"example": "readonly tristateConfig = dbxTristateRotatingButtonConfig({ label: 'Text', defaultValue: false });",
|
|
885
|
+
"minimalExample": "<dbx-button iconOnly [dbxRotatingButton]=\"tristateConfig\" [(dbxRotatingButtonValue)]=\"emailEnabled\"></dbx-button>"
|
|
886
|
+
},
|
|
857
887
|
{
|
|
858
888
|
"slug": "browser-agent-view",
|
|
859
889
|
"category": "misc",
|
|
@@ -874,6 +904,12 @@
|
|
|
874
904
|
"type": "Maybe<boolean>",
|
|
875
905
|
"description": "",
|
|
876
906
|
"required": false
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
"name": "overrideKey",
|
|
910
|
+
"type": "Maybe<DbxBrowserAgentViewEntryKey>",
|
|
911
|
+
"description": "Key of the manually selected entry. Can be bound two-way to persist the user's choice.",
|
|
912
|
+
"required": false
|
|
877
913
|
}
|
|
878
914
|
],
|
|
879
915
|
"outputs": [],
|
|
@@ -1033,7 +1069,7 @@
|
|
|
1033
1069
|
"selector": "dbx-prompt-confirm",
|
|
1034
1070
|
"className": "DbxPromptConfirmComponent",
|
|
1035
1071
|
"module": "@dereekb/dbx-web",
|
|
1036
|
-
"description": "Renders a confirmation prompt with customizable title, message, confirm, and cancel buttons.",
|
|
1072
|
+
"description": "Renders a confirmation prompt with customizable title, message, confirm, and cancel buttons.\n\nProjected content shows above the buttons. Content marked with the `buttons` attribute shows in the same row, before the\nconfirm button.",
|
|
1037
1073
|
"inputs": [
|
|
1038
1074
|
{
|
|
1039
1075
|
"name": "config",
|
|
@@ -1055,7 +1091,7 @@
|
|
|
1055
1091
|
"description": ""
|
|
1056
1092
|
}
|
|
1057
1093
|
],
|
|
1058
|
-
"contentProjection": "<ng-content></ng-content>",
|
|
1094
|
+
"contentProjection": "<ng-content></ng-content>; <ng-content select=\"[buttons]\"></ng-content>",
|
|
1059
1095
|
"relatedSlugs": [
|
|
1060
1096
|
"prompt",
|
|
1061
1097
|
"action-confirm"
|
|
@@ -2121,7 +2157,20 @@
|
|
|
2121
2157
|
"className": "DbxColorDirective",
|
|
2122
2158
|
"module": "@dereekb/dbx-web",
|
|
2123
2159
|
"description": "Provides themed color *tokens* to the host element — it never paints a background itself.\n\nAccepts either a {@link DbxThemeColor} string (e.g. `'primary'`, `'success'`) or a {@link DbxColorConfig}\nobject carrying arbitrary CSS color values (any hex, `rgb()`, `hsl()`, `var(...)`, `color-mix(...)`, etc.).\nThe directive sets the `--dbx-bg-color-current` / `--dbx-color-current` (and tone) custom properties and adds the\n`.dbx-color` marker class, leaving the actual painting to either the explicit `.dbx-color-bg` utility on the same\nelement or a colored-surface component's own `.dbx-color`-scoped SCSS (e.g. `<dbx-bar>`, `<dbx-button>`, `<dbx-loading>`,\n`<dbx-icon-tile>`, `<mat-card>`) that reads the inherited tokens.\n\nOptionally set {@link dbxColorTone} (0-100) to control background opacity for a tonal/muted appearance.\nWhen tonal mode is active, the `dbx-color-tonal` CSS class is added and a CSS rule overrides the text\ncolor to the vibrant color (via `--dbx-bg-color-current`).\n\nThe standalone `[dbxColorTone]` input wins over `config.tone` when both are set; the same precedence\napplies to tonal mode.",
|
|
2124
|
-
"inputs": [
|
|
2160
|
+
"inputs": [
|
|
2161
|
+
{
|
|
2162
|
+
"name": "dbxColor",
|
|
2163
|
+
"type": "Maybe<DbxColorInput>",
|
|
2164
|
+
"description": "The color to provide tokens for. Declared as a `model` so a colored-surface component on the same host (e.g.\n`dbx-button`) can push its resolved color into the directive, keeping it the single token provider on the element.",
|
|
2165
|
+
"required": false
|
|
2166
|
+
},
|
|
2167
|
+
{
|
|
2168
|
+
"name": "dbxColorTone",
|
|
2169
|
+
"type": "Maybe<DbxColorTone>",
|
|
2170
|
+
"description": "Background tone level (0-100). When set, the background becomes semi-transparent\nand text color switches to the vibrant theme color for a tonal appearance.\n\nDeclared as a `model` for the same reason as {@link dbxColor}: a colored-surface component on the same host (e.g.\n`dbx-avatar-view`) resolves its tone from its own inputs/context and pushes it here, keeping this directive the\nsingle token provider on the element.",
|
|
2171
|
+
"required": false
|
|
2172
|
+
}
|
|
2173
|
+
],
|
|
2125
2174
|
"outputs": [],
|
|
2126
2175
|
"relatedSlugs": [
|
|
2127
2176
|
"text-color",
|
|
@@ -513,6 +513,125 @@
|
|
|
513
513
|
"derivedComposites": [],
|
|
514
514
|
"derivedFieldOverrides": []
|
|
515
515
|
},
|
|
516
|
+
{
|
|
517
|
+
"slug": "notification-users-with-text-phone-number-query",
|
|
518
|
+
"name": "notificationUsersWithTextPhoneNumberQuery",
|
|
519
|
+
"module": "@dereekb/firebase",
|
|
520
|
+
"subpath": "model/notification/notification.query",
|
|
521
|
+
"signature": "notificationUsersWithTextPhoneNumberQuery(phoneNumber: E164PhoneNumber): FirestoreQueryConstraint[]",
|
|
522
|
+
"description": "Query constraints for finding {@link NotificationUser} documents whose texting number (`gc.t`) is the given phone number.\n\nUsed by the text opt-out sync to find the users a STOP reply came from.",
|
|
523
|
+
"model": "NotificationUser",
|
|
524
|
+
"collection": "nu",
|
|
525
|
+
"isNested": false,
|
|
526
|
+
"scope": "COLLECTION",
|
|
527
|
+
"manual": false,
|
|
528
|
+
"skip": false,
|
|
529
|
+
"category": "lookup",
|
|
530
|
+
"params": [
|
|
531
|
+
{
|
|
532
|
+
"name": "phoneNumber",
|
|
533
|
+
"type": "E164PhoneNumber",
|
|
534
|
+
"description": "- The texting number to match.",
|
|
535
|
+
"optional": false
|
|
536
|
+
}
|
|
537
|
+
],
|
|
538
|
+
"returns": "Array of Firestore query constraints filtering for users with that texting number.",
|
|
539
|
+
"tags": [
|
|
540
|
+
"lookup",
|
|
541
|
+
"notificationuser",
|
|
542
|
+
"notification",
|
|
543
|
+
"users",
|
|
544
|
+
"with",
|
|
545
|
+
"text",
|
|
546
|
+
"phone",
|
|
547
|
+
"number",
|
|
548
|
+
"query",
|
|
549
|
+
"notificationuserswithtextphonenumberquery",
|
|
550
|
+
"user",
|
|
551
|
+
"constraints",
|
|
552
|
+
"finding",
|
|
553
|
+
"link",
|
|
554
|
+
"documents",
|
|
555
|
+
"whose",
|
|
556
|
+
"texting",
|
|
557
|
+
"given",
|
|
558
|
+
"used"
|
|
559
|
+
],
|
|
560
|
+
"constraintSequences": [
|
|
561
|
+
{
|
|
562
|
+
"pathLabel": "all",
|
|
563
|
+
"entries": [
|
|
564
|
+
{
|
|
565
|
+
"kind": "where",
|
|
566
|
+
"fieldPath": "gc.t",
|
|
567
|
+
"operator": "=="
|
|
568
|
+
}
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
"derivedComposites": [],
|
|
573
|
+
"derivedFieldOverrides": []
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"slug": "notification-users-with-stopped-text-phone-number-query",
|
|
577
|
+
"name": "notificationUsersWithStoppedTextPhoneNumberQuery",
|
|
578
|
+
"module": "@dereekb/firebase",
|
|
579
|
+
"subpath": "model/notification/notification.query",
|
|
580
|
+
"signature": "notificationUsersWithStoppedTextPhoneNumberQuery(phoneNumber: E164PhoneNumber): FirestoreQueryConstraint[]",
|
|
581
|
+
"description": "Query constraints for finding {@link NotificationUser} documents that have the given phone number in their stopped numbers (`tso`).\n\nUsed by the text opt-out sync to find the users a START reply turns texts back on for.",
|
|
582
|
+
"model": "NotificationUser",
|
|
583
|
+
"collection": "nu",
|
|
584
|
+
"isNested": false,
|
|
585
|
+
"scope": "COLLECTION",
|
|
586
|
+
"manual": false,
|
|
587
|
+
"skip": false,
|
|
588
|
+
"category": "lookup",
|
|
589
|
+
"params": [
|
|
590
|
+
{
|
|
591
|
+
"name": "phoneNumber",
|
|
592
|
+
"type": "E164PhoneNumber",
|
|
593
|
+
"description": "- The stopped phone number to match.",
|
|
594
|
+
"optional": false
|
|
595
|
+
}
|
|
596
|
+
],
|
|
597
|
+
"returns": "Array of Firestore query constraints filtering for users that stopped that number.",
|
|
598
|
+
"tags": [
|
|
599
|
+
"lookup",
|
|
600
|
+
"notificationuser",
|
|
601
|
+
"notification",
|
|
602
|
+
"users",
|
|
603
|
+
"with",
|
|
604
|
+
"stopped",
|
|
605
|
+
"text",
|
|
606
|
+
"phone",
|
|
607
|
+
"number",
|
|
608
|
+
"query",
|
|
609
|
+
"notificationuserswithstoppedtextphonenumberquery",
|
|
610
|
+
"user",
|
|
611
|
+
"constraints",
|
|
612
|
+
"finding",
|
|
613
|
+
"link",
|
|
614
|
+
"documents",
|
|
615
|
+
"have",
|
|
616
|
+
"given",
|
|
617
|
+
"their",
|
|
618
|
+
"numbers"
|
|
619
|
+
],
|
|
620
|
+
"constraintSequences": [
|
|
621
|
+
{
|
|
622
|
+
"pathLabel": "all",
|
|
623
|
+
"entries": [
|
|
624
|
+
{
|
|
625
|
+
"kind": "where",
|
|
626
|
+
"fieldPath": "tso",
|
|
627
|
+
"operator": "array-contains"
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
],
|
|
632
|
+
"derivedComposites": [],
|
|
633
|
+
"derivedFieldOverrides": []
|
|
634
|
+
},
|
|
516
635
|
{
|
|
517
636
|
"slug": "notification-summaries-flagged-for-needs-initialization-query",
|
|
518
637
|
"name": "notificationSummariesFlaggedForNeedsInitializationQuery",
|
|
@@ -298,6 +298,20 @@
|
|
|
298
298
|
],
|
|
299
299
|
"notes": "Names one upload \"slot\" within a FormSpace — the resume, the cover letter, the photo of the ID.\n\nA slot is stored on the uploaded {@link StorageFile} as its `pg` (purposeSubgroup), which is what makes\n\"replace the file in this slot\" the existing `flagPreviousForDelete` behaviour rather than new machinery."
|
|
300
300
|
},
|
|
301
|
+
{
|
|
302
|
+
"name": "NotificationTemplateTypeInfoGroupKey",
|
|
303
|
+
"package": "@dereekb/firebase",
|
|
304
|
+
"module": "src/lib/model/notification/notification.details",
|
|
305
|
+
"kind": "semantic-type",
|
|
306
|
+
"definition": "string",
|
|
307
|
+
"baseType": "string",
|
|
308
|
+
"topics": [
|
|
309
|
+
"identifier",
|
|
310
|
+
"string",
|
|
311
|
+
"dereekb-firebase:notification"
|
|
312
|
+
],
|
|
313
|
+
"notes": "Key of a {@link NotificationTemplateTypeInfoGroup}. Template types whose groups share a key are shown together."
|
|
314
|
+
},
|
|
301
315
|
{
|
|
302
316
|
"name": "NotificationTemplateType",
|
|
303
317
|
"package": "@dereekb/firebase",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/dbx-components-mcp",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.15.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"ts-morph": "^21.0.0"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@dereekb/dbx-cli": "14.
|
|
16
|
-
"@dereekb/util": "14.
|
|
15
|
+
"@dereekb/dbx-cli": "14.15.0",
|
|
16
|
+
"@dereekb/util": "14.15.0"
|
|
17
17
|
}
|
|
18
18
|
}
|