@dereekb/firebase 13.12.7 → 13.12.9
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/eslint/index.cjs.js +343 -63
- package/eslint/index.esm.js +340 -64
- package/eslint/package.json +3 -3
- package/eslint/src/lib/index.d.ts +1 -0
- package/eslint/src/lib/plugin.d.ts +2 -0
- package/eslint/src/lib/require-dbx-model-api-params-tag.rule.d.ts +91 -0
- package/index.cjs.js +1 -0
- package/index.esm.js +1 -0
- package/package.json +5 -5
- package/src/lib/client/function/model.function.factory.d.ts +9 -1
- package/test/package.json +6 -6
package/eslint/index.cjs.js
CHANGED
|
@@ -1863,10 +1863,10 @@ function _unsupported_iterable_to_array$e(o, minLen) {
|
|
|
1863
1863
|
return result;
|
|
1864
1864
|
}
|
|
1865
1865
|
function pushFrame(node) {
|
|
1866
|
-
var _ref;
|
|
1866
|
+
var _stack_at, _ref;
|
|
1867
1867
|
var anchor = getFunctionJsdocAnchor(node);
|
|
1868
1868
|
var tagged = anchor ? jsdocHasMarker(anchor) : false;
|
|
1869
|
-
var parent = stack.
|
|
1869
|
+
var parent = (_stack_at = stack.at(-1)) !== null && _stack_at !== void 0 ? _stack_at : null;
|
|
1870
1870
|
var taggedDeep = tagged || ((_ref = parent === null || parent === void 0 ? void 0 : parent.taggedDeep) !== null && _ref !== void 0 ? _ref : false);
|
|
1871
1871
|
stack.push({
|
|
1872
1872
|
node: node,
|
|
@@ -1875,7 +1875,8 @@ function _unsupported_iterable_to_array$e(o, minLen) {
|
|
|
1875
1875
|
});
|
|
1876
1876
|
}
|
|
1877
1877
|
function popFrame(node) {
|
|
1878
|
-
|
|
1878
|
+
var _stack_at;
|
|
1879
|
+
if (((_stack_at = stack.at(-1)) === null || _stack_at === void 0 ? void 0 : _stack_at.node) === node) {
|
|
1879
1880
|
stack.pop();
|
|
1880
1881
|
}
|
|
1881
1882
|
}
|
|
@@ -2137,6 +2138,19 @@ var DEFAULT_KNOWN_COMPANIONS = [
|
|
|
2137
2138
|
'Path',
|
|
2138
2139
|
'Helper'
|
|
2139
2140
|
];
|
|
2141
|
+
function extractGenericIdentifier(callNode) {
|
|
2142
|
+
var _callNode_typeArguments;
|
|
2143
|
+
var params = (_callNode_typeArguments = callNode.typeArguments) !== null && _callNode_typeArguments !== void 0 ? _callNode_typeArguments : callNode.typeParameters;
|
|
2144
|
+
var result = null;
|
|
2145
|
+
if (params && Array.isArray(params.params) && params.params.length > 0) {
|
|
2146
|
+
var _first_typeName;
|
|
2147
|
+
var first = params.params[0];
|
|
2148
|
+
if ((first === null || first === void 0 ? void 0 : first.type) === 'TSTypeReference' && ((_first_typeName = first.typeName) === null || _first_typeName === void 0 ? void 0 : _first_typeName.type) === 'Identifier') {
|
|
2149
|
+
result = first.typeName.name;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return result;
|
|
2153
|
+
}
|
|
2140
2154
|
/**
|
|
2141
2155
|
* ESLint rule enforcing `@dbxModelFirebaseIndex` companion tags and body coherence.
|
|
2142
2156
|
* Mirrors the scanner schema at
|
|
@@ -2552,19 +2566,6 @@ var DEFAULT_KNOWN_COMPANIONS = [
|
|
|
2552
2566
|
}
|
|
2553
2567
|
}
|
|
2554
2568
|
}
|
|
2555
|
-
function extractGenericIdentifier(callNode) {
|
|
2556
|
-
var _callNode_typeArguments;
|
|
2557
|
-
var params = (_callNode_typeArguments = callNode.typeArguments) !== null && _callNode_typeArguments !== void 0 ? _callNode_typeArguments : callNode.typeParameters;
|
|
2558
|
-
var result = null;
|
|
2559
|
-
if (params && Array.isArray(params.params) && params.params.length > 0) {
|
|
2560
|
-
var _first_typeName;
|
|
2561
|
-
var first = params.params[0];
|
|
2562
|
-
if ((first === null || first === void 0 ? void 0 : first.type) === 'TSTypeReference' && ((_first_typeName = first.typeName) === null || _first_typeName === void 0 ? void 0 : _first_typeName.type) === 'Identifier') {
|
|
2563
|
-
result = first.typeName.name;
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
return result;
|
|
2567
|
-
}
|
|
2568
2569
|
function checkBody(node, parsed) {
|
|
2569
2570
|
if (!checkBodyCoherence) return;
|
|
2570
2571
|
var skip = getSkipTagValue(parsed);
|
|
@@ -2653,6 +2654,15 @@ function _type_of$8(obj) {
|
|
|
2653
2654
|
/**
|
|
2654
2655
|
* Default suffix used to recognise a presumed-tagged query factory by name (single-file scope).
|
|
2655
2656
|
*/ var DEFAULT_PRESUMED_TAGGED_SUFFIX = 'Query';
|
|
2657
|
+
function recordVariableDeclarator(node, emptyArrayDeclarators) {
|
|
2658
|
+
var _node_id, _node_init;
|
|
2659
|
+
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) === 'Identifier' && ((_node_init = node.init) === null || _node_init === void 0 ? void 0 : _node_init.type) === 'ArrayExpression' && Array.isArray(node.init.elements) && node.init.elements.length === 0) {
|
|
2660
|
+
emptyArrayDeclarators.push({
|
|
2661
|
+
node: node,
|
|
2662
|
+
name: node.id.name
|
|
2663
|
+
});
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2656
2666
|
/**
|
|
2657
2667
|
* ESLint rule enforcing that `@dbxModelFirebaseIndexDispatcher`-tagged factories delegate to
|
|
2658
2668
|
* other `@dbxModelFirebaseIndex`-tagged query factories instead of building constraints directly.
|
|
@@ -2776,15 +2786,6 @@ function _type_of$8(obj) {
|
|
|
2776
2786
|
pushReceivers.add(node.callee.object.name);
|
|
2777
2787
|
}
|
|
2778
2788
|
}
|
|
2779
|
-
function recordVariableDeclarator(node, emptyArrayDeclarators) {
|
|
2780
|
-
var _node_id, _node_init;
|
|
2781
|
-
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) === 'Identifier' && ((_node_init = node.init) === null || _node_init === void 0 ? void 0 : _node_init.type) === 'ArrayExpression' && Array.isArray(node.init.elements) && node.init.elements.length === 0) {
|
|
2782
|
-
emptyArrayDeclarators.push({
|
|
2783
|
-
node: node,
|
|
2784
|
-
name: node.id.name
|
|
2785
|
-
});
|
|
2786
|
-
}
|
|
2787
|
-
}
|
|
2788
2789
|
function scanBody(body) {
|
|
2789
2790
|
var constraintCalls = [];
|
|
2790
2791
|
var emptyArrayDeclarators = [];
|
|
@@ -2952,6 +2953,11 @@ function _unsupported_iterable_to_array$d(o, minLen) {
|
|
|
2952
2953
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
2953
2954
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$d(o, minLen);
|
|
2954
2955
|
}
|
|
2956
|
+
function hasTypeArgument(node) {
|
|
2957
|
+
var _node_typeArguments;
|
|
2958
|
+
var args = (_node_typeArguments = node.typeArguments) !== null && _node_typeArguments !== void 0 ? _node_typeArguments : node.typeParameters;
|
|
2959
|
+
return Boolean(args && Array.isArray(args.params) && args.params.length > 0);
|
|
2960
|
+
}
|
|
2955
2961
|
/**
|
|
2956
2962
|
* ESLint rule that warns when an `@dereekb/firebase` field-path-narrowing constraint factory
|
|
2957
2963
|
* (`where`, `orderBy`) is called without a generic type argument. Without `<Model>`, the
|
|
@@ -3026,11 +3032,6 @@ function _unsupported_iterable_to_array$d(o, minLen) {
|
|
|
3026
3032
|
}
|
|
3027
3033
|
return result;
|
|
3028
3034
|
}
|
|
3029
|
-
function hasTypeArgument(node) {
|
|
3030
|
-
var _node_typeArguments;
|
|
3031
|
-
var args = (_node_typeArguments = node.typeArguments) !== null && _node_typeArguments !== void 0 ? _node_typeArguments : node.typeParameters;
|
|
3032
|
-
return Boolean(args && Array.isArray(args.params) && args.params.length > 0);
|
|
3033
|
-
}
|
|
3034
3035
|
return {
|
|
3035
3036
|
ImportDeclaration: function ImportDeclaration(node) {
|
|
3036
3037
|
return trackImportDeclaration(registry, node);
|
|
@@ -12649,29 +12650,29 @@ var PATH_SEPARATOR = '/';
|
|
|
12649
12650
|
var env = new Map();
|
|
12650
12651
|
bindParamsAsWildcards((_fn_params = fn.params) !== null && _fn_params !== void 0 ? _fn_params : [], env);
|
|
12651
12652
|
var body = functionBodyExpression(fn);
|
|
12652
|
-
if (
|
|
12653
|
-
result = {
|
|
12654
|
-
ok: false,
|
|
12655
|
-
reason: 'buildUploadPath body is not a single return expression'
|
|
12656
|
-
};
|
|
12657
|
-
} else {
|
|
12653
|
+
if (body) {
|
|
12658
12654
|
var frags = foldFrags(body, {
|
|
12659
12655
|
scope: scope,
|
|
12660
12656
|
env: env
|
|
12661
12657
|
}, 0);
|
|
12662
|
-
if (
|
|
12663
|
-
result = {
|
|
12664
|
-
ok: false,
|
|
12665
|
-
reason: 'buildUploadPath does not fold to a constant path (unknown const, unmodeled call, or runtime value)'
|
|
12666
|
-
};
|
|
12667
|
-
} else {
|
|
12658
|
+
if (frags) {
|
|
12668
12659
|
result = {
|
|
12669
12660
|
ok: true,
|
|
12670
12661
|
path: {
|
|
12671
12662
|
segments: fragsToSegments(frags)
|
|
12672
12663
|
}
|
|
12673
12664
|
};
|
|
12665
|
+
} else {
|
|
12666
|
+
result = {
|
|
12667
|
+
ok: false,
|
|
12668
|
+
reason: 'buildUploadPath does not fold to a constant path (unknown const, unmodeled call, or runtime value)'
|
|
12669
|
+
};
|
|
12674
12670
|
}
|
|
12671
|
+
} else {
|
|
12672
|
+
result = {
|
|
12673
|
+
ok: false,
|
|
12674
|
+
reason: 'buildUploadPath body is not a single return expression'
|
|
12675
|
+
};
|
|
12675
12676
|
}
|
|
12676
12677
|
}
|
|
12677
12678
|
return result;
|
|
@@ -13611,9 +13612,7 @@ function applyNumericOperator(operator, left, right) {
|
|
|
13611
13612
|
for(var i = 0; result && i < folded.segments.length; i++){
|
|
13612
13613
|
var a = folded.segments[i];
|
|
13613
13614
|
var b = ruleSegments[i];
|
|
13614
|
-
if (a.kind !== b.kind) {
|
|
13615
|
-
result = false;
|
|
13616
|
-
} else if (a.kind === 'literal' && a.value !== b.value) {
|
|
13615
|
+
if (a.kind !== b.kind || a.kind === 'literal' && a.value !== b.value) {
|
|
13617
13616
|
result = false;
|
|
13618
13617
|
}
|
|
13619
13618
|
}
|
|
@@ -17243,20 +17242,19 @@ var SPEC_SUFFIX = '.spec.ts';
|
|
|
17243
17242
|
*/ function classifySpecFile(config) {
|
|
17244
17243
|
var filename = config.filename, parentFolderName = config.parentFolderName;
|
|
17245
17244
|
var result;
|
|
17246
|
-
if (
|
|
17247
|
-
result = {
|
|
17248
|
-
filename: filename,
|
|
17249
|
-
group: '',
|
|
17250
|
-
kind: 'non-spec',
|
|
17251
|
-
subgroups: [],
|
|
17252
|
-
isCanonical: false
|
|
17253
|
-
};
|
|
17254
|
-
} else {
|
|
17245
|
+
if (filename.endsWith(SPEC_SUFFIX)) {
|
|
17255
17246
|
var _parts_;
|
|
17256
17247
|
var stem = filename.slice(0, -SPEC_SUFFIX.length);
|
|
17257
17248
|
var parts = stem.split('.');
|
|
17258
17249
|
var group = (_parts_ = parts[0]) !== null && _parts_ !== void 0 ? _parts_ : '';
|
|
17259
|
-
if (group
|
|
17250
|
+
if (group === parentFolderName) {
|
|
17251
|
+
var rest = parts.slice(1);
|
|
17252
|
+
result = classifyRemainingSegments({
|
|
17253
|
+
filename: filename,
|
|
17254
|
+
group: group,
|
|
17255
|
+
rest: rest
|
|
17256
|
+
});
|
|
17257
|
+
} else {
|
|
17260
17258
|
result = {
|
|
17261
17259
|
filename: filename,
|
|
17262
17260
|
group: group,
|
|
@@ -17264,14 +17262,15 @@ var SPEC_SUFFIX = '.spec.ts';
|
|
|
17264
17262
|
subgroups: [],
|
|
17265
17263
|
isCanonical: false
|
|
17266
17264
|
};
|
|
17267
|
-
} else {
|
|
17268
|
-
var rest = parts.slice(1);
|
|
17269
|
-
result = classifyRemainingSegments({
|
|
17270
|
-
filename: filename,
|
|
17271
|
-
group: group,
|
|
17272
|
-
rest: rest
|
|
17273
|
-
});
|
|
17274
17265
|
}
|
|
17266
|
+
} else {
|
|
17267
|
+
result = {
|
|
17268
|
+
filename: filename,
|
|
17269
|
+
group: '',
|
|
17270
|
+
kind: 'non-spec',
|
|
17271
|
+
subgroups: [],
|
|
17272
|
+
isCanonical: false
|
|
17273
|
+
};
|
|
17275
17274
|
}
|
|
17276
17275
|
return result;
|
|
17277
17276
|
}
|
|
@@ -17638,6 +17637,282 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17638
17637
|
}
|
|
17639
17638
|
};
|
|
17640
17639
|
|
|
17640
|
+
/**
|
|
17641
|
+
* JSDoc marker tag that every CRUD params interface should carry so the dbx-components manifest
|
|
17642
|
+
* extractor (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) records it as an
|
|
17643
|
+
* intentionally-exposed API params type rather than an untagged one.
|
|
17644
|
+
*/ var DBX_MODEL_API_PARAMS_MARKER = 'dbxModelApiParams';
|
|
17645
|
+
/**
|
|
17646
|
+
* Suffix on the type alias that declares a model-group CRUD function config (e.g.
|
|
17647
|
+
* `GuestbookModelCrudFunctionsConfig`). Its referenced params interfaces are the ones the marker
|
|
17648
|
+
* tag is required on.
|
|
17649
|
+
*/ var DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX = 'ModelCrudFunctionsConfig';
|
|
17650
|
+
/**
|
|
17651
|
+
* Suffix on the type alias that declares a group's standalone function type map (e.g.
|
|
17652
|
+
* `GuestbookFunctionTypeMap`). Each entry's params type is also subject to the marker tag.
|
|
17653
|
+
*/ var DEFAULT_FUNCTION_TYPE_MAP_SUFFIX = 'FunctionTypeMap';
|
|
17654
|
+
/**
|
|
17655
|
+
* Returns the first element type node of a `TSTupleType`, normalizing across `@typescript-eslint`
|
|
17656
|
+
* versions (`elementTypes` historically, `elements` in newer releases). CRUD config tuples take the
|
|
17657
|
+
* form `[Params, Result]`, so element 0 is always the params type.
|
|
17658
|
+
*
|
|
17659
|
+
* @param node - A `TSTupleType` node.
|
|
17660
|
+
* @returns The first element type node, or null when the tuple is empty.
|
|
17661
|
+
*/ function tupleFirstElement(node) {
|
|
17662
|
+
var _ref, _ref1;
|
|
17663
|
+
var elements = (_ref = node === null || node === void 0 ? void 0 : node.elementTypes) !== null && _ref !== void 0 ? _ref : node === null || node === void 0 ? void 0 : node.elements;
|
|
17664
|
+
return (_ref1 = elements === null || elements === void 0 ? void 0 : elements[0]) !== null && _ref1 !== void 0 ? _ref1 : null;
|
|
17665
|
+
}
|
|
17666
|
+
/**
|
|
17667
|
+
* Recursively collects the params type-reference names declared by a CRUD config / function-type-map
|
|
17668
|
+
* type node into `out`, mirroring the resolution in `extract-crud.ts`. A bare `TSTypeReference`
|
|
17669
|
+
* (`create: CreateGuestbookParams`) contributes its referenced name; a `TSTupleType`
|
|
17670
|
+
* (`query: [QueryGuestbooksParams, OnCallQueryModelResult<...>]`) contributes element 0 only, since
|
|
17671
|
+
* element 1 is the result type; and a `TSTypeLiteral` (model literal, verb literal, or
|
|
17672
|
+
* `{ specifier: ... }` object) is recursed into per property-signature value. Generic type arguments
|
|
17673
|
+
* on a reference are intentionally not descended into — only the params type itself is collected.
|
|
17674
|
+
*
|
|
17675
|
+
* @param node - The type node to inspect.
|
|
17676
|
+
* @param out - The accumulating set of params type-reference names.
|
|
17677
|
+
*/ function collectParamsTypeNames(node, out) {
|
|
17678
|
+
if (!node) {
|
|
17679
|
+
return;
|
|
17680
|
+
}
|
|
17681
|
+
if (node.type === 'TSTypeReference') {
|
|
17682
|
+
var name = typeReferenceTypeName$1(node);
|
|
17683
|
+
if (name) {
|
|
17684
|
+
out.add(name);
|
|
17685
|
+
}
|
|
17686
|
+
} else if (node.type === 'TSTupleType') {
|
|
17687
|
+
collectParamsTypeNames(tupleFirstElement(node), out);
|
|
17688
|
+
} else if (node.type === 'TSTypeLiteral' && Array.isArray(node.members)) {
|
|
17689
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
17690
|
+
try {
|
|
17691
|
+
for(var _iterator = node.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
17692
|
+
var member = _step.value;
|
|
17693
|
+
if ((member === null || member === void 0 ? void 0 : member.type) === 'TSPropertySignature') {
|
|
17694
|
+
var _member_typeAnnotation;
|
|
17695
|
+
collectParamsTypeNames((_member_typeAnnotation = member.typeAnnotation) === null || _member_typeAnnotation === void 0 ? void 0 : _member_typeAnnotation.typeAnnotation, out);
|
|
17696
|
+
}
|
|
17697
|
+
}
|
|
17698
|
+
} catch (err) {
|
|
17699
|
+
_didIteratorError = true;
|
|
17700
|
+
_iteratorError = err;
|
|
17701
|
+
} finally{
|
|
17702
|
+
try {
|
|
17703
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
17704
|
+
_iterator.return();
|
|
17705
|
+
}
|
|
17706
|
+
} finally{
|
|
17707
|
+
if (_didIteratorError) {
|
|
17708
|
+
throw _iteratorError;
|
|
17709
|
+
}
|
|
17710
|
+
}
|
|
17711
|
+
}
|
|
17712
|
+
}
|
|
17713
|
+
}
|
|
17714
|
+
/**
|
|
17715
|
+
* Returns the inner declaration node when `statement` is (or wraps) a `TSInterfaceDeclaration`, along
|
|
17716
|
+
* with the statement-level anchor ESLint attaches leading comments to.
|
|
17717
|
+
*
|
|
17718
|
+
* @param statement - A top-level `Program.body` statement.
|
|
17719
|
+
* @returns The interface declaration + its JSDoc anchor, or null when the statement is not an interface.
|
|
17720
|
+
*/ function interfaceFromStatement(statement) {
|
|
17721
|
+
var _statement_declaration;
|
|
17722
|
+
var result = null;
|
|
17723
|
+
if ((statement === null || statement === void 0 ? void 0 : statement.type) === 'TSInterfaceDeclaration') {
|
|
17724
|
+
result = {
|
|
17725
|
+
decl: statement,
|
|
17726
|
+
anchor: statement
|
|
17727
|
+
};
|
|
17728
|
+
} else if (((statement === null || statement === void 0 ? void 0 : statement.type) === 'ExportNamedDeclaration' || (statement === null || statement === void 0 ? void 0 : statement.type) === 'ExportDefaultDeclaration') && ((_statement_declaration = statement.declaration) === null || _statement_declaration === void 0 ? void 0 : _statement_declaration.type) === 'TSInterfaceDeclaration') {
|
|
17729
|
+
result = {
|
|
17730
|
+
decl: statement.declaration,
|
|
17731
|
+
anchor: statement
|
|
17732
|
+
};
|
|
17733
|
+
}
|
|
17734
|
+
return result;
|
|
17735
|
+
}
|
|
17736
|
+
/**
|
|
17737
|
+
* Returns true when the interface's leading JSDoc carries the given marker tag.
|
|
17738
|
+
*
|
|
17739
|
+
* @param sourceCode - The ESLint `SourceCode` object.
|
|
17740
|
+
* @param anchor - The interface's JSDoc anchor node.
|
|
17741
|
+
* @param tagName - The marker tag name (without the leading `@`).
|
|
17742
|
+
* @returns True when the marker tag is present on the interface's JSDoc.
|
|
17743
|
+
*/ function interfaceHasMarker(sourceCode, anchor, tagName) {
|
|
17744
|
+
var jsdoc = leadingJsdocFor(sourceCode, anchor);
|
|
17745
|
+
var result = false;
|
|
17746
|
+
if (jsdoc) {
|
|
17747
|
+
var parsed = parseJsdocComment(jsdoc.value);
|
|
17748
|
+
result = parsed.tags.some(function(tag) {
|
|
17749
|
+
return tag.tag === tagName;
|
|
17750
|
+
});
|
|
17751
|
+
}
|
|
17752
|
+
return result;
|
|
17753
|
+
}
|
|
17754
|
+
/**
|
|
17755
|
+
* ESLint rule that requires every params interface referenced by a `*ModelCrudFunctionsConfig` (and,
|
|
17756
|
+
* by default, `*FunctionTypeMap`) type alias and declared in the same file to carry the
|
|
17757
|
+
* `@dbxModelApiParams` JSDoc marker tag.
|
|
17758
|
+
*
|
|
17759
|
+
* The marker is the signal the dbx-components manifest extractor
|
|
17760
|
+
* (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) reads to distinguish an
|
|
17761
|
+
* intentionally-exposed API params type from an untagged one — missing it produces the
|
|
17762
|
+
* `[no-api-params-tag]` build warning and the "Missing `@dbxModelApiParams` marker" hint in the
|
|
17763
|
+
* `dbx_model_api_lookup` MCP tool. This rule surfaces the same gap in-editor at lint time.
|
|
17764
|
+
*
|
|
17765
|
+
* Same-file resolution only — matching the extractor, which itself resolves params interfaces from a
|
|
17766
|
+
* single in-memory source file. Params types declared in another file (e.g. shared base params like
|
|
17767
|
+
* `TargetModelParams`) are skipped, exactly as the extractor reports them as unresolved.
|
|
17768
|
+
*
|
|
17769
|
+
* @example
|
|
17770
|
+
* ```ts
|
|
17771
|
+
* export type GuestbookModelCrudFunctionsConfig = {
|
|
17772
|
+
* guestbook: { create: CreateGuestbookParams };
|
|
17773
|
+
* };
|
|
17774
|
+
*
|
|
17775
|
+
* // OK
|
|
17776
|
+
* /**
|
|
17777
|
+
* * @dbxModelApiParams
|
|
17778
|
+
* *\/
|
|
17779
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
17780
|
+
*
|
|
17781
|
+
* // WARN — missingApiParamsTag
|
|
17782
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
17783
|
+
* ```
|
|
17784
|
+
*/ var FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE = {
|
|
17785
|
+
meta: {
|
|
17786
|
+
type: 'suggestion',
|
|
17787
|
+
fixable: undefined,
|
|
17788
|
+
docs: {
|
|
17789
|
+
description: 'Require the `@dbxModelApiParams` marker tag on params interfaces referenced by a `*ModelCrudFunctionsConfig` / `*FunctionTypeMap` alias and declared in the same file, mirroring the manifest extractor that reads the tag.',
|
|
17790
|
+
recommended: true
|
|
17791
|
+
},
|
|
17792
|
+
messages: {
|
|
17793
|
+
missingApiParamsTag: 'Params interface "{{name}}" is referenced by the CRUD config "{{configName}}" but is missing the `@{{tag}}` marker. Add `@{{tag}}` to its JSDoc so the manifest extractor records it as an intentionally-exposed API params type.'
|
|
17794
|
+
},
|
|
17795
|
+
schema: [
|
|
17796
|
+
{
|
|
17797
|
+
type: 'object',
|
|
17798
|
+
additionalProperties: false,
|
|
17799
|
+
properties: {
|
|
17800
|
+
configTypeSuffix: {
|
|
17801
|
+
type: 'string'
|
|
17802
|
+
},
|
|
17803
|
+
alsoFunctionTypeMap: {
|
|
17804
|
+
type: 'boolean'
|
|
17805
|
+
},
|
|
17806
|
+
tagName: {
|
|
17807
|
+
type: 'string'
|
|
17808
|
+
}
|
|
17809
|
+
}
|
|
17810
|
+
}
|
|
17811
|
+
]
|
|
17812
|
+
},
|
|
17813
|
+
create: function create(context) {
|
|
17814
|
+
var _context_options_, _options_configTypeSuffix, _options_tagName;
|
|
17815
|
+
var options = (_context_options_ = context.options[0]) !== null && _context_options_ !== void 0 ? _context_options_ : {};
|
|
17816
|
+
var configTypeSuffix = (_options_configTypeSuffix = options.configTypeSuffix) !== null && _options_configTypeSuffix !== void 0 ? _options_configTypeSuffix : DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX;
|
|
17817
|
+
var alsoFunctionTypeMap = options.alsoFunctionTypeMap !== false;
|
|
17818
|
+
var tagName = (_options_tagName = options.tagName) !== null && _options_tagName !== void 0 ? _options_tagName : DBX_MODEL_API_PARAMS_MARKER;
|
|
17819
|
+
var sourceCode = context.sourceCode;
|
|
17820
|
+
function isConfigAliasName(name) {
|
|
17821
|
+
return name.endsWith(configTypeSuffix) || alsoFunctionTypeMap && name.endsWith(DEFAULT_FUNCTION_TYPE_MAP_SUFFIX);
|
|
17822
|
+
}
|
|
17823
|
+
return {
|
|
17824
|
+
Program: function Program(programNode) {
|
|
17825
|
+
var _ref;
|
|
17826
|
+
var body = (_ref = programNode === null || programNode === void 0 ? void 0 : programNode.body) !== null && _ref !== void 0 ? _ref : [];
|
|
17827
|
+
// Index the interfaces declared in this file by name (same-file resolution, like the extractor).
|
|
17828
|
+
var interfaces = new Map();
|
|
17829
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
17830
|
+
try {
|
|
17831
|
+
for(var _iterator = body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
17832
|
+
var statement = _step.value;
|
|
17833
|
+
var _found_decl_id, _found_decl;
|
|
17834
|
+
var found = interfaceFromStatement(statement);
|
|
17835
|
+
if ((found === null || found === void 0 ? void 0 : (_found_decl = found.decl) === null || _found_decl === void 0 ? void 0 : (_found_decl_id = _found_decl.id) === null || _found_decl_id === void 0 ? void 0 : _found_decl_id.type) === 'Identifier') {
|
|
17836
|
+
interfaces.set(found.decl.id.name, found);
|
|
17837
|
+
}
|
|
17838
|
+
}
|
|
17839
|
+
} catch (err) {
|
|
17840
|
+
_didIteratorError = true;
|
|
17841
|
+
_iteratorError = err;
|
|
17842
|
+
} finally{
|
|
17843
|
+
try {
|
|
17844
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
17845
|
+
_iterator.return();
|
|
17846
|
+
}
|
|
17847
|
+
} finally{
|
|
17848
|
+
if (_didIteratorError) {
|
|
17849
|
+
throw _iteratorError;
|
|
17850
|
+
}
|
|
17851
|
+
}
|
|
17852
|
+
}
|
|
17853
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
17854
|
+
try {
|
|
17855
|
+
for(var _iterator1 = body[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
17856
|
+
var statement1 = _step1.value;
|
|
17857
|
+
var _statement_declaration, _alias_id;
|
|
17858
|
+
var alias = (statement1 === null || statement1 === void 0 ? void 0 : statement1.type) === 'TSTypeAliasDeclaration' ? statement1 : (statement1 === null || statement1 === void 0 ? void 0 : statement1.type) === 'ExportNamedDeclaration' && ((_statement_declaration = statement1.declaration) === null || _statement_declaration === void 0 ? void 0 : _statement_declaration.type) === 'TSTypeAliasDeclaration' ? statement1.declaration : null;
|
|
17859
|
+
if (!alias || ((_alias_id = alias.id) === null || _alias_id === void 0 ? void 0 : _alias_id.type) !== 'Identifier' || !isConfigAliasName(alias.id.name)) {
|
|
17860
|
+
continue;
|
|
17861
|
+
}
|
|
17862
|
+
var paramsNames = new Set();
|
|
17863
|
+
collectParamsTypeNames(alias.typeAnnotation, paramsNames);
|
|
17864
|
+
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
|
|
17865
|
+
try {
|
|
17866
|
+
for(var _iterator2 = paramsNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
|
|
17867
|
+
var paramsName = _step2.value;
|
|
17868
|
+
var target = interfaces.get(paramsName);
|
|
17869
|
+
// Skip params types not declared in this file — the extractor cannot resolve them either.
|
|
17870
|
+
if (target && !interfaceHasMarker(sourceCode, target.anchor, tagName)) {
|
|
17871
|
+
context.report({
|
|
17872
|
+
node: target.decl.id,
|
|
17873
|
+
messageId: 'missingApiParamsTag',
|
|
17874
|
+
data: {
|
|
17875
|
+
name: paramsName,
|
|
17876
|
+
configName: alias.id.name,
|
|
17877
|
+
tag: tagName
|
|
17878
|
+
}
|
|
17879
|
+
});
|
|
17880
|
+
}
|
|
17881
|
+
}
|
|
17882
|
+
} catch (err) {
|
|
17883
|
+
_didIteratorError2 = true;
|
|
17884
|
+
_iteratorError2 = err;
|
|
17885
|
+
} finally{
|
|
17886
|
+
try {
|
|
17887
|
+
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
17888
|
+
_iterator2.return();
|
|
17889
|
+
}
|
|
17890
|
+
} finally{
|
|
17891
|
+
if (_didIteratorError2) {
|
|
17892
|
+
throw _iteratorError2;
|
|
17893
|
+
}
|
|
17894
|
+
}
|
|
17895
|
+
}
|
|
17896
|
+
}
|
|
17897
|
+
} catch (err) {
|
|
17898
|
+
_didIteratorError1 = true;
|
|
17899
|
+
_iteratorError1 = err;
|
|
17900
|
+
} finally{
|
|
17901
|
+
try {
|
|
17902
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
17903
|
+
_iterator1.return();
|
|
17904
|
+
}
|
|
17905
|
+
} finally{
|
|
17906
|
+
if (_didIteratorError1) {
|
|
17907
|
+
throw _iteratorError1;
|
|
17908
|
+
}
|
|
17909
|
+
}
|
|
17910
|
+
}
|
|
17911
|
+
}
|
|
17912
|
+
};
|
|
17913
|
+
}
|
|
17914
|
+
};
|
|
17915
|
+
|
|
17641
17916
|
/**
|
|
17642
17917
|
* ESLint plugin for `@dereekb/firebase` rules.
|
|
17643
17918
|
*
|
|
@@ -17659,7 +17934,8 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17659
17934
|
'require-service-factory-for-dbx-model': FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE,
|
|
17660
17935
|
'require-dbx-model-companion-tags': FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE,
|
|
17661
17936
|
'require-canonical-api-spec-filename': FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE,
|
|
17662
|
-
'require-api-crud-spec-for-group': FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE
|
|
17937
|
+
'require-api-crud-spec-for-group': FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE,
|
|
17938
|
+
'require-dbx-model-api-params-tag': FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE
|
|
17663
17939
|
}
|
|
17664
17940
|
};
|
|
17665
17941
|
/**
|
|
@@ -17669,10 +17945,12 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17669
17945
|
*/ var firebaseESLintPlugin = FIREBASE_ESLINT_PLUGIN;
|
|
17670
17946
|
|
|
17671
17947
|
exports.API_DETAILS_IMPORT_MODULE = API_DETAILS_IMPORT_MODULE;
|
|
17948
|
+
exports.DBX_MODEL_API_PARAMS_MARKER = DBX_MODEL_API_PARAMS_MARKER;
|
|
17672
17949
|
exports.DBX_MODEL_FIREBASE_INDEX_MARKER = DBX_MODEL_FIREBASE_INDEX_MARKER;
|
|
17673
17950
|
exports.DBX_MODEL_SERVICE_FACTORY_TAG = DBX_MODEL_SERVICE_FACTORY_TAG;
|
|
17674
17951
|
exports.DEFAULT_API_DETAILS_FACTORY_NAME = DEFAULT_API_DETAILS_FACTORY_NAME;
|
|
17675
17952
|
exports.DEFAULT_CONSTRAINT_FACTORY_NAMES = DEFAULT_CONSTRAINT_FACTORY_NAMES;
|
|
17953
|
+
exports.DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX = DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX;
|
|
17676
17954
|
exports.DEFAULT_CRUD_FUNCTION_TYPE_VERBS = DEFAULT_CRUD_FUNCTION_TYPE_VERBS;
|
|
17677
17955
|
exports.DEFAULT_CRUD_VERB_NAMES = DEFAULT_CRUD_VERB_NAMES;
|
|
17678
17956
|
exports.DEFAULT_DISCOVERY_EXCLUDED_DIRS = DEFAULT_DISCOVERY_EXCLUDED_DIRS;
|
|
@@ -17680,6 +17958,7 @@ exports.DEFAULT_FACTORY_SEARCH_ROOTS = DEFAULT_FACTORY_SEARCH_ROOTS;
|
|
|
17680
17958
|
exports.DEFAULT_FACTORY_TAG = DEFAULT_FACTORY_TAG;
|
|
17681
17959
|
exports.DEFAULT_FIRESTORE_RULES_FILENAME = DEFAULT_FIRESTORE_RULES_FILENAME;
|
|
17682
17960
|
exports.DEFAULT_FUNCTION_DIR_SEGMENT = DEFAULT_FUNCTION_DIR_SEGMENT;
|
|
17961
|
+
exports.DEFAULT_FUNCTION_TYPE_MAP_SUFFIX = DEFAULT_FUNCTION_TYPE_MAP_SUFFIX;
|
|
17683
17962
|
exports.DEFAULT_IDENTITY_FACTORY_NAME = DEFAULT_IDENTITY_FACTORY_NAME;
|
|
17684
17963
|
exports.DEFAULT_INDEX_AFFECTING_CONSTRAINT_NAMES = DEFAULT_INDEX_AFFECTING_CONSTRAINT_NAMES;
|
|
17685
17964
|
exports.DEFAULT_MODEL_MARKER_TAG = DEFAULT_MODEL_MARKER_TAG;
|
|
@@ -17696,6 +17975,7 @@ exports.FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE = FIREBASE_REQUIRE_API_CRU
|
|
|
17696
17975
|
exports.FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE = FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE;
|
|
17697
17976
|
exports.FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE = FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE;
|
|
17698
17977
|
exports.FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE = FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE;
|
|
17978
|
+
exports.FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE = FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE;
|
|
17699
17979
|
exports.FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE = FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE;
|
|
17700
17980
|
exports.FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE = FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE;
|
|
17701
17981
|
exports.FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE = FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE;
|
package/eslint/index.esm.js
CHANGED
|
@@ -1861,10 +1861,10 @@ function _unsupported_iterable_to_array$e(o, minLen) {
|
|
|
1861
1861
|
return result;
|
|
1862
1862
|
}
|
|
1863
1863
|
function pushFrame(node) {
|
|
1864
|
-
var _ref;
|
|
1864
|
+
var _stack_at, _ref;
|
|
1865
1865
|
var anchor = getFunctionJsdocAnchor(node);
|
|
1866
1866
|
var tagged = anchor ? jsdocHasMarker(anchor) : false;
|
|
1867
|
-
var parent = stack.
|
|
1867
|
+
var parent = (_stack_at = stack.at(-1)) !== null && _stack_at !== void 0 ? _stack_at : null;
|
|
1868
1868
|
var taggedDeep = tagged || ((_ref = parent === null || parent === void 0 ? void 0 : parent.taggedDeep) !== null && _ref !== void 0 ? _ref : false);
|
|
1869
1869
|
stack.push({
|
|
1870
1870
|
node: node,
|
|
@@ -1873,7 +1873,8 @@ function _unsupported_iterable_to_array$e(o, minLen) {
|
|
|
1873
1873
|
});
|
|
1874
1874
|
}
|
|
1875
1875
|
function popFrame(node) {
|
|
1876
|
-
|
|
1876
|
+
var _stack_at;
|
|
1877
|
+
if (((_stack_at = stack.at(-1)) === null || _stack_at === void 0 ? void 0 : _stack_at.node) === node) {
|
|
1877
1878
|
stack.pop();
|
|
1878
1879
|
}
|
|
1879
1880
|
}
|
|
@@ -2135,6 +2136,19 @@ var DEFAULT_KNOWN_COMPANIONS = [
|
|
|
2135
2136
|
'Path',
|
|
2136
2137
|
'Helper'
|
|
2137
2138
|
];
|
|
2139
|
+
function extractGenericIdentifier(callNode) {
|
|
2140
|
+
var _callNode_typeArguments;
|
|
2141
|
+
var params = (_callNode_typeArguments = callNode.typeArguments) !== null && _callNode_typeArguments !== void 0 ? _callNode_typeArguments : callNode.typeParameters;
|
|
2142
|
+
var result = null;
|
|
2143
|
+
if (params && Array.isArray(params.params) && params.params.length > 0) {
|
|
2144
|
+
var _first_typeName;
|
|
2145
|
+
var first = params.params[0];
|
|
2146
|
+
if ((first === null || first === void 0 ? void 0 : first.type) === 'TSTypeReference' && ((_first_typeName = first.typeName) === null || _first_typeName === void 0 ? void 0 : _first_typeName.type) === 'Identifier') {
|
|
2147
|
+
result = first.typeName.name;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
return result;
|
|
2151
|
+
}
|
|
2138
2152
|
/**
|
|
2139
2153
|
* ESLint rule enforcing `@dbxModelFirebaseIndex` companion tags and body coherence.
|
|
2140
2154
|
* Mirrors the scanner schema at
|
|
@@ -2550,19 +2564,6 @@ var DEFAULT_KNOWN_COMPANIONS = [
|
|
|
2550
2564
|
}
|
|
2551
2565
|
}
|
|
2552
2566
|
}
|
|
2553
|
-
function extractGenericIdentifier(callNode) {
|
|
2554
|
-
var _callNode_typeArguments;
|
|
2555
|
-
var params = (_callNode_typeArguments = callNode.typeArguments) !== null && _callNode_typeArguments !== void 0 ? _callNode_typeArguments : callNode.typeParameters;
|
|
2556
|
-
var result = null;
|
|
2557
|
-
if (params && Array.isArray(params.params) && params.params.length > 0) {
|
|
2558
|
-
var _first_typeName;
|
|
2559
|
-
var first = params.params[0];
|
|
2560
|
-
if ((first === null || first === void 0 ? void 0 : first.type) === 'TSTypeReference' && ((_first_typeName = first.typeName) === null || _first_typeName === void 0 ? void 0 : _first_typeName.type) === 'Identifier') {
|
|
2561
|
-
result = first.typeName.name;
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
return result;
|
|
2565
|
-
}
|
|
2566
2567
|
function checkBody(node, parsed) {
|
|
2567
2568
|
if (!checkBodyCoherence) return;
|
|
2568
2569
|
var skip = getSkipTagValue(parsed);
|
|
@@ -2651,6 +2652,15 @@ function _type_of$8(obj) {
|
|
|
2651
2652
|
/**
|
|
2652
2653
|
* Default suffix used to recognise a presumed-tagged query factory by name (single-file scope).
|
|
2653
2654
|
*/ var DEFAULT_PRESUMED_TAGGED_SUFFIX = 'Query';
|
|
2655
|
+
function recordVariableDeclarator(node, emptyArrayDeclarators) {
|
|
2656
|
+
var _node_id, _node_init;
|
|
2657
|
+
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) === 'Identifier' && ((_node_init = node.init) === null || _node_init === void 0 ? void 0 : _node_init.type) === 'ArrayExpression' && Array.isArray(node.init.elements) && node.init.elements.length === 0) {
|
|
2658
|
+
emptyArrayDeclarators.push({
|
|
2659
|
+
node: node,
|
|
2660
|
+
name: node.id.name
|
|
2661
|
+
});
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2654
2664
|
/**
|
|
2655
2665
|
* ESLint rule enforcing that `@dbxModelFirebaseIndexDispatcher`-tagged factories delegate to
|
|
2656
2666
|
* other `@dbxModelFirebaseIndex`-tagged query factories instead of building constraints directly.
|
|
@@ -2774,15 +2784,6 @@ function _type_of$8(obj) {
|
|
|
2774
2784
|
pushReceivers.add(node.callee.object.name);
|
|
2775
2785
|
}
|
|
2776
2786
|
}
|
|
2777
|
-
function recordVariableDeclarator(node, emptyArrayDeclarators) {
|
|
2778
|
-
var _node_id, _node_init;
|
|
2779
|
-
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) === 'Identifier' && ((_node_init = node.init) === null || _node_init === void 0 ? void 0 : _node_init.type) === 'ArrayExpression' && Array.isArray(node.init.elements) && node.init.elements.length === 0) {
|
|
2780
|
-
emptyArrayDeclarators.push({
|
|
2781
|
-
node: node,
|
|
2782
|
-
name: node.id.name
|
|
2783
|
-
});
|
|
2784
|
-
}
|
|
2785
|
-
}
|
|
2786
2787
|
function scanBody(body) {
|
|
2787
2788
|
var constraintCalls = [];
|
|
2788
2789
|
var emptyArrayDeclarators = [];
|
|
@@ -2950,6 +2951,11 @@ function _unsupported_iterable_to_array$d(o, minLen) {
|
|
|
2950
2951
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
2951
2952
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$d(o, minLen);
|
|
2952
2953
|
}
|
|
2954
|
+
function hasTypeArgument(node) {
|
|
2955
|
+
var _node_typeArguments;
|
|
2956
|
+
var args = (_node_typeArguments = node.typeArguments) !== null && _node_typeArguments !== void 0 ? _node_typeArguments : node.typeParameters;
|
|
2957
|
+
return Boolean(args && Array.isArray(args.params) && args.params.length > 0);
|
|
2958
|
+
}
|
|
2953
2959
|
/**
|
|
2954
2960
|
* ESLint rule that warns when an `@dereekb/firebase` field-path-narrowing constraint factory
|
|
2955
2961
|
* (`where`, `orderBy`) is called without a generic type argument. Without `<Model>`, the
|
|
@@ -3024,11 +3030,6 @@ function _unsupported_iterable_to_array$d(o, minLen) {
|
|
|
3024
3030
|
}
|
|
3025
3031
|
return result;
|
|
3026
3032
|
}
|
|
3027
|
-
function hasTypeArgument(node) {
|
|
3028
|
-
var _node_typeArguments;
|
|
3029
|
-
var args = (_node_typeArguments = node.typeArguments) !== null && _node_typeArguments !== void 0 ? _node_typeArguments : node.typeParameters;
|
|
3030
|
-
return Boolean(args && Array.isArray(args.params) && args.params.length > 0);
|
|
3031
|
-
}
|
|
3032
3033
|
return {
|
|
3033
3034
|
ImportDeclaration: function ImportDeclaration(node) {
|
|
3034
3035
|
return trackImportDeclaration(registry, node);
|
|
@@ -12647,29 +12648,29 @@ var PATH_SEPARATOR = '/';
|
|
|
12647
12648
|
var env = new Map();
|
|
12648
12649
|
bindParamsAsWildcards((_fn_params = fn.params) !== null && _fn_params !== void 0 ? _fn_params : [], env);
|
|
12649
12650
|
var body = functionBodyExpression(fn);
|
|
12650
|
-
if (
|
|
12651
|
-
result = {
|
|
12652
|
-
ok: false,
|
|
12653
|
-
reason: 'buildUploadPath body is not a single return expression'
|
|
12654
|
-
};
|
|
12655
|
-
} else {
|
|
12651
|
+
if (body) {
|
|
12656
12652
|
var frags = foldFrags(body, {
|
|
12657
12653
|
scope: scope,
|
|
12658
12654
|
env: env
|
|
12659
12655
|
}, 0);
|
|
12660
|
-
if (
|
|
12661
|
-
result = {
|
|
12662
|
-
ok: false,
|
|
12663
|
-
reason: 'buildUploadPath does not fold to a constant path (unknown const, unmodeled call, or runtime value)'
|
|
12664
|
-
};
|
|
12665
|
-
} else {
|
|
12656
|
+
if (frags) {
|
|
12666
12657
|
result = {
|
|
12667
12658
|
ok: true,
|
|
12668
12659
|
path: {
|
|
12669
12660
|
segments: fragsToSegments(frags)
|
|
12670
12661
|
}
|
|
12671
12662
|
};
|
|
12663
|
+
} else {
|
|
12664
|
+
result = {
|
|
12665
|
+
ok: false,
|
|
12666
|
+
reason: 'buildUploadPath does not fold to a constant path (unknown const, unmodeled call, or runtime value)'
|
|
12667
|
+
};
|
|
12672
12668
|
}
|
|
12669
|
+
} else {
|
|
12670
|
+
result = {
|
|
12671
|
+
ok: false,
|
|
12672
|
+
reason: 'buildUploadPath body is not a single return expression'
|
|
12673
|
+
};
|
|
12673
12674
|
}
|
|
12674
12675
|
}
|
|
12675
12676
|
return result;
|
|
@@ -13609,9 +13610,7 @@ function applyNumericOperator(operator, left, right) {
|
|
|
13609
13610
|
for(var i = 0; result && i < folded.segments.length; i++){
|
|
13610
13611
|
var a = folded.segments[i];
|
|
13611
13612
|
var b = ruleSegments[i];
|
|
13612
|
-
if (a.kind !== b.kind) {
|
|
13613
|
-
result = false;
|
|
13614
|
-
} else if (a.kind === 'literal' && a.value !== b.value) {
|
|
13613
|
+
if (a.kind !== b.kind || a.kind === 'literal' && a.value !== b.value) {
|
|
13615
13614
|
result = false;
|
|
13616
13615
|
}
|
|
13617
13616
|
}
|
|
@@ -17241,20 +17240,19 @@ var SPEC_SUFFIX = '.spec.ts';
|
|
|
17241
17240
|
*/ function classifySpecFile(config) {
|
|
17242
17241
|
var filename = config.filename, parentFolderName = config.parentFolderName;
|
|
17243
17242
|
var result;
|
|
17244
|
-
if (
|
|
17245
|
-
result = {
|
|
17246
|
-
filename: filename,
|
|
17247
|
-
group: '',
|
|
17248
|
-
kind: 'non-spec',
|
|
17249
|
-
subgroups: [],
|
|
17250
|
-
isCanonical: false
|
|
17251
|
-
};
|
|
17252
|
-
} else {
|
|
17243
|
+
if (filename.endsWith(SPEC_SUFFIX)) {
|
|
17253
17244
|
var _parts_;
|
|
17254
17245
|
var stem = filename.slice(0, -SPEC_SUFFIX.length);
|
|
17255
17246
|
var parts = stem.split('.');
|
|
17256
17247
|
var group = (_parts_ = parts[0]) !== null && _parts_ !== void 0 ? _parts_ : '';
|
|
17257
|
-
if (group
|
|
17248
|
+
if (group === parentFolderName) {
|
|
17249
|
+
var rest = parts.slice(1);
|
|
17250
|
+
result = classifyRemainingSegments({
|
|
17251
|
+
filename: filename,
|
|
17252
|
+
group: group,
|
|
17253
|
+
rest: rest
|
|
17254
|
+
});
|
|
17255
|
+
} else {
|
|
17258
17256
|
result = {
|
|
17259
17257
|
filename: filename,
|
|
17260
17258
|
group: group,
|
|
@@ -17262,14 +17260,15 @@ var SPEC_SUFFIX = '.spec.ts';
|
|
|
17262
17260
|
subgroups: [],
|
|
17263
17261
|
isCanonical: false
|
|
17264
17262
|
};
|
|
17265
|
-
} else {
|
|
17266
|
-
var rest = parts.slice(1);
|
|
17267
|
-
result = classifyRemainingSegments({
|
|
17268
|
-
filename: filename,
|
|
17269
|
-
group: group,
|
|
17270
|
-
rest: rest
|
|
17271
|
-
});
|
|
17272
17263
|
}
|
|
17264
|
+
} else {
|
|
17265
|
+
result = {
|
|
17266
|
+
filename: filename,
|
|
17267
|
+
group: '',
|
|
17268
|
+
kind: 'non-spec',
|
|
17269
|
+
subgroups: [],
|
|
17270
|
+
isCanonical: false
|
|
17271
|
+
};
|
|
17273
17272
|
}
|
|
17274
17273
|
return result;
|
|
17275
17274
|
}
|
|
@@ -17636,6 +17635,282 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17636
17635
|
}
|
|
17637
17636
|
};
|
|
17638
17637
|
|
|
17638
|
+
/**
|
|
17639
|
+
* JSDoc marker tag that every CRUD params interface should carry so the dbx-components manifest
|
|
17640
|
+
* extractor (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) records it as an
|
|
17641
|
+
* intentionally-exposed API params type rather than an untagged one.
|
|
17642
|
+
*/ var DBX_MODEL_API_PARAMS_MARKER = 'dbxModelApiParams';
|
|
17643
|
+
/**
|
|
17644
|
+
* Suffix on the type alias that declares a model-group CRUD function config (e.g.
|
|
17645
|
+
* `GuestbookModelCrudFunctionsConfig`). Its referenced params interfaces are the ones the marker
|
|
17646
|
+
* tag is required on.
|
|
17647
|
+
*/ var DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX = 'ModelCrudFunctionsConfig';
|
|
17648
|
+
/**
|
|
17649
|
+
* Suffix on the type alias that declares a group's standalone function type map (e.g.
|
|
17650
|
+
* `GuestbookFunctionTypeMap`). Each entry's params type is also subject to the marker tag.
|
|
17651
|
+
*/ var DEFAULT_FUNCTION_TYPE_MAP_SUFFIX = 'FunctionTypeMap';
|
|
17652
|
+
/**
|
|
17653
|
+
* Returns the first element type node of a `TSTupleType`, normalizing across `@typescript-eslint`
|
|
17654
|
+
* versions (`elementTypes` historically, `elements` in newer releases). CRUD config tuples take the
|
|
17655
|
+
* form `[Params, Result]`, so element 0 is always the params type.
|
|
17656
|
+
*
|
|
17657
|
+
* @param node - A `TSTupleType` node.
|
|
17658
|
+
* @returns The first element type node, or null when the tuple is empty.
|
|
17659
|
+
*/ function tupleFirstElement(node) {
|
|
17660
|
+
var _ref, _ref1;
|
|
17661
|
+
var elements = (_ref = node === null || node === void 0 ? void 0 : node.elementTypes) !== null && _ref !== void 0 ? _ref : node === null || node === void 0 ? void 0 : node.elements;
|
|
17662
|
+
return (_ref1 = elements === null || elements === void 0 ? void 0 : elements[0]) !== null && _ref1 !== void 0 ? _ref1 : null;
|
|
17663
|
+
}
|
|
17664
|
+
/**
|
|
17665
|
+
* Recursively collects the params type-reference names declared by a CRUD config / function-type-map
|
|
17666
|
+
* type node into `out`, mirroring the resolution in `extract-crud.ts`. A bare `TSTypeReference`
|
|
17667
|
+
* (`create: CreateGuestbookParams`) contributes its referenced name; a `TSTupleType`
|
|
17668
|
+
* (`query: [QueryGuestbooksParams, OnCallQueryModelResult<...>]`) contributes element 0 only, since
|
|
17669
|
+
* element 1 is the result type; and a `TSTypeLiteral` (model literal, verb literal, or
|
|
17670
|
+
* `{ specifier: ... }` object) is recursed into per property-signature value. Generic type arguments
|
|
17671
|
+
* on a reference are intentionally not descended into — only the params type itself is collected.
|
|
17672
|
+
*
|
|
17673
|
+
* @param node - The type node to inspect.
|
|
17674
|
+
* @param out - The accumulating set of params type-reference names.
|
|
17675
|
+
*/ function collectParamsTypeNames(node, out) {
|
|
17676
|
+
if (!node) {
|
|
17677
|
+
return;
|
|
17678
|
+
}
|
|
17679
|
+
if (node.type === 'TSTypeReference') {
|
|
17680
|
+
var name = typeReferenceTypeName$1(node);
|
|
17681
|
+
if (name) {
|
|
17682
|
+
out.add(name);
|
|
17683
|
+
}
|
|
17684
|
+
} else if (node.type === 'TSTupleType') {
|
|
17685
|
+
collectParamsTypeNames(tupleFirstElement(node), out);
|
|
17686
|
+
} else if (node.type === 'TSTypeLiteral' && Array.isArray(node.members)) {
|
|
17687
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
17688
|
+
try {
|
|
17689
|
+
for(var _iterator = node.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
17690
|
+
var member = _step.value;
|
|
17691
|
+
if ((member === null || member === void 0 ? void 0 : member.type) === 'TSPropertySignature') {
|
|
17692
|
+
var _member_typeAnnotation;
|
|
17693
|
+
collectParamsTypeNames((_member_typeAnnotation = member.typeAnnotation) === null || _member_typeAnnotation === void 0 ? void 0 : _member_typeAnnotation.typeAnnotation, out);
|
|
17694
|
+
}
|
|
17695
|
+
}
|
|
17696
|
+
} catch (err) {
|
|
17697
|
+
_didIteratorError = true;
|
|
17698
|
+
_iteratorError = err;
|
|
17699
|
+
} finally{
|
|
17700
|
+
try {
|
|
17701
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
17702
|
+
_iterator.return();
|
|
17703
|
+
}
|
|
17704
|
+
} finally{
|
|
17705
|
+
if (_didIteratorError) {
|
|
17706
|
+
throw _iteratorError;
|
|
17707
|
+
}
|
|
17708
|
+
}
|
|
17709
|
+
}
|
|
17710
|
+
}
|
|
17711
|
+
}
|
|
17712
|
+
/**
|
|
17713
|
+
* Returns the inner declaration node when `statement` is (or wraps) a `TSInterfaceDeclaration`, along
|
|
17714
|
+
* with the statement-level anchor ESLint attaches leading comments to.
|
|
17715
|
+
*
|
|
17716
|
+
* @param statement - A top-level `Program.body` statement.
|
|
17717
|
+
* @returns The interface declaration + its JSDoc anchor, or null when the statement is not an interface.
|
|
17718
|
+
*/ function interfaceFromStatement(statement) {
|
|
17719
|
+
var _statement_declaration;
|
|
17720
|
+
var result = null;
|
|
17721
|
+
if ((statement === null || statement === void 0 ? void 0 : statement.type) === 'TSInterfaceDeclaration') {
|
|
17722
|
+
result = {
|
|
17723
|
+
decl: statement,
|
|
17724
|
+
anchor: statement
|
|
17725
|
+
};
|
|
17726
|
+
} else if (((statement === null || statement === void 0 ? void 0 : statement.type) === 'ExportNamedDeclaration' || (statement === null || statement === void 0 ? void 0 : statement.type) === 'ExportDefaultDeclaration') && ((_statement_declaration = statement.declaration) === null || _statement_declaration === void 0 ? void 0 : _statement_declaration.type) === 'TSInterfaceDeclaration') {
|
|
17727
|
+
result = {
|
|
17728
|
+
decl: statement.declaration,
|
|
17729
|
+
anchor: statement
|
|
17730
|
+
};
|
|
17731
|
+
}
|
|
17732
|
+
return result;
|
|
17733
|
+
}
|
|
17734
|
+
/**
|
|
17735
|
+
* Returns true when the interface's leading JSDoc carries the given marker tag.
|
|
17736
|
+
*
|
|
17737
|
+
* @param sourceCode - The ESLint `SourceCode` object.
|
|
17738
|
+
* @param anchor - The interface's JSDoc anchor node.
|
|
17739
|
+
* @param tagName - The marker tag name (without the leading `@`).
|
|
17740
|
+
* @returns True when the marker tag is present on the interface's JSDoc.
|
|
17741
|
+
*/ function interfaceHasMarker(sourceCode, anchor, tagName) {
|
|
17742
|
+
var jsdoc = leadingJsdocFor(sourceCode, anchor);
|
|
17743
|
+
var result = false;
|
|
17744
|
+
if (jsdoc) {
|
|
17745
|
+
var parsed = parseJsdocComment(jsdoc.value);
|
|
17746
|
+
result = parsed.tags.some(function(tag) {
|
|
17747
|
+
return tag.tag === tagName;
|
|
17748
|
+
});
|
|
17749
|
+
}
|
|
17750
|
+
return result;
|
|
17751
|
+
}
|
|
17752
|
+
/**
|
|
17753
|
+
* ESLint rule that requires every params interface referenced by a `*ModelCrudFunctionsConfig` (and,
|
|
17754
|
+
* by default, `*FunctionTypeMap`) type alias and declared in the same file to carry the
|
|
17755
|
+
* `@dbxModelApiParams` JSDoc marker tag.
|
|
17756
|
+
*
|
|
17757
|
+
* The marker is the signal the dbx-components manifest extractor
|
|
17758
|
+
* (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) reads to distinguish an
|
|
17759
|
+
* intentionally-exposed API params type from an untagged one — missing it produces the
|
|
17760
|
+
* `[no-api-params-tag]` build warning and the "Missing `@dbxModelApiParams` marker" hint in the
|
|
17761
|
+
* `dbx_model_api_lookup` MCP tool. This rule surfaces the same gap in-editor at lint time.
|
|
17762
|
+
*
|
|
17763
|
+
* Same-file resolution only — matching the extractor, which itself resolves params interfaces from a
|
|
17764
|
+
* single in-memory source file. Params types declared in another file (e.g. shared base params like
|
|
17765
|
+
* `TargetModelParams`) are skipped, exactly as the extractor reports them as unresolved.
|
|
17766
|
+
*
|
|
17767
|
+
* @example
|
|
17768
|
+
* ```ts
|
|
17769
|
+
* export type GuestbookModelCrudFunctionsConfig = {
|
|
17770
|
+
* guestbook: { create: CreateGuestbookParams };
|
|
17771
|
+
* };
|
|
17772
|
+
*
|
|
17773
|
+
* // OK
|
|
17774
|
+
* /**
|
|
17775
|
+
* * @dbxModelApiParams
|
|
17776
|
+
* *\/
|
|
17777
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
17778
|
+
*
|
|
17779
|
+
* // WARN — missingApiParamsTag
|
|
17780
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
17781
|
+
* ```
|
|
17782
|
+
*/ var FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE = {
|
|
17783
|
+
meta: {
|
|
17784
|
+
type: 'suggestion',
|
|
17785
|
+
fixable: undefined,
|
|
17786
|
+
docs: {
|
|
17787
|
+
description: 'Require the `@dbxModelApiParams` marker tag on params interfaces referenced by a `*ModelCrudFunctionsConfig` / `*FunctionTypeMap` alias and declared in the same file, mirroring the manifest extractor that reads the tag.',
|
|
17788
|
+
recommended: true
|
|
17789
|
+
},
|
|
17790
|
+
messages: {
|
|
17791
|
+
missingApiParamsTag: 'Params interface "{{name}}" is referenced by the CRUD config "{{configName}}" but is missing the `@{{tag}}` marker. Add `@{{tag}}` to its JSDoc so the manifest extractor records it as an intentionally-exposed API params type.'
|
|
17792
|
+
},
|
|
17793
|
+
schema: [
|
|
17794
|
+
{
|
|
17795
|
+
type: 'object',
|
|
17796
|
+
additionalProperties: false,
|
|
17797
|
+
properties: {
|
|
17798
|
+
configTypeSuffix: {
|
|
17799
|
+
type: 'string'
|
|
17800
|
+
},
|
|
17801
|
+
alsoFunctionTypeMap: {
|
|
17802
|
+
type: 'boolean'
|
|
17803
|
+
},
|
|
17804
|
+
tagName: {
|
|
17805
|
+
type: 'string'
|
|
17806
|
+
}
|
|
17807
|
+
}
|
|
17808
|
+
}
|
|
17809
|
+
]
|
|
17810
|
+
},
|
|
17811
|
+
create: function create(context) {
|
|
17812
|
+
var _context_options_, _options_configTypeSuffix, _options_tagName;
|
|
17813
|
+
var options = (_context_options_ = context.options[0]) !== null && _context_options_ !== void 0 ? _context_options_ : {};
|
|
17814
|
+
var configTypeSuffix = (_options_configTypeSuffix = options.configTypeSuffix) !== null && _options_configTypeSuffix !== void 0 ? _options_configTypeSuffix : DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX;
|
|
17815
|
+
var alsoFunctionTypeMap = options.alsoFunctionTypeMap !== false;
|
|
17816
|
+
var tagName = (_options_tagName = options.tagName) !== null && _options_tagName !== void 0 ? _options_tagName : DBX_MODEL_API_PARAMS_MARKER;
|
|
17817
|
+
var sourceCode = context.sourceCode;
|
|
17818
|
+
function isConfigAliasName(name) {
|
|
17819
|
+
return name.endsWith(configTypeSuffix) || alsoFunctionTypeMap && name.endsWith(DEFAULT_FUNCTION_TYPE_MAP_SUFFIX);
|
|
17820
|
+
}
|
|
17821
|
+
return {
|
|
17822
|
+
Program: function Program(programNode) {
|
|
17823
|
+
var _ref;
|
|
17824
|
+
var body = (_ref = programNode === null || programNode === void 0 ? void 0 : programNode.body) !== null && _ref !== void 0 ? _ref : [];
|
|
17825
|
+
// Index the interfaces declared in this file by name (same-file resolution, like the extractor).
|
|
17826
|
+
var interfaces = new Map();
|
|
17827
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
17828
|
+
try {
|
|
17829
|
+
for(var _iterator = body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
17830
|
+
var statement = _step.value;
|
|
17831
|
+
var _found_decl_id, _found_decl;
|
|
17832
|
+
var found = interfaceFromStatement(statement);
|
|
17833
|
+
if ((found === null || found === void 0 ? void 0 : (_found_decl = found.decl) === null || _found_decl === void 0 ? void 0 : (_found_decl_id = _found_decl.id) === null || _found_decl_id === void 0 ? void 0 : _found_decl_id.type) === 'Identifier') {
|
|
17834
|
+
interfaces.set(found.decl.id.name, found);
|
|
17835
|
+
}
|
|
17836
|
+
}
|
|
17837
|
+
} catch (err) {
|
|
17838
|
+
_didIteratorError = true;
|
|
17839
|
+
_iteratorError = err;
|
|
17840
|
+
} finally{
|
|
17841
|
+
try {
|
|
17842
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
17843
|
+
_iterator.return();
|
|
17844
|
+
}
|
|
17845
|
+
} finally{
|
|
17846
|
+
if (_didIteratorError) {
|
|
17847
|
+
throw _iteratorError;
|
|
17848
|
+
}
|
|
17849
|
+
}
|
|
17850
|
+
}
|
|
17851
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
17852
|
+
try {
|
|
17853
|
+
for(var _iterator1 = body[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
17854
|
+
var statement1 = _step1.value;
|
|
17855
|
+
var _statement_declaration, _alias_id;
|
|
17856
|
+
var alias = (statement1 === null || statement1 === void 0 ? void 0 : statement1.type) === 'TSTypeAliasDeclaration' ? statement1 : (statement1 === null || statement1 === void 0 ? void 0 : statement1.type) === 'ExportNamedDeclaration' && ((_statement_declaration = statement1.declaration) === null || _statement_declaration === void 0 ? void 0 : _statement_declaration.type) === 'TSTypeAliasDeclaration' ? statement1.declaration : null;
|
|
17857
|
+
if (!alias || ((_alias_id = alias.id) === null || _alias_id === void 0 ? void 0 : _alias_id.type) !== 'Identifier' || !isConfigAliasName(alias.id.name)) {
|
|
17858
|
+
continue;
|
|
17859
|
+
}
|
|
17860
|
+
var paramsNames = new Set();
|
|
17861
|
+
collectParamsTypeNames(alias.typeAnnotation, paramsNames);
|
|
17862
|
+
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
|
|
17863
|
+
try {
|
|
17864
|
+
for(var _iterator2 = paramsNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
|
|
17865
|
+
var paramsName = _step2.value;
|
|
17866
|
+
var target = interfaces.get(paramsName);
|
|
17867
|
+
// Skip params types not declared in this file — the extractor cannot resolve them either.
|
|
17868
|
+
if (target && !interfaceHasMarker(sourceCode, target.anchor, tagName)) {
|
|
17869
|
+
context.report({
|
|
17870
|
+
node: target.decl.id,
|
|
17871
|
+
messageId: 'missingApiParamsTag',
|
|
17872
|
+
data: {
|
|
17873
|
+
name: paramsName,
|
|
17874
|
+
configName: alias.id.name,
|
|
17875
|
+
tag: tagName
|
|
17876
|
+
}
|
|
17877
|
+
});
|
|
17878
|
+
}
|
|
17879
|
+
}
|
|
17880
|
+
} catch (err) {
|
|
17881
|
+
_didIteratorError2 = true;
|
|
17882
|
+
_iteratorError2 = err;
|
|
17883
|
+
} finally{
|
|
17884
|
+
try {
|
|
17885
|
+
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
17886
|
+
_iterator2.return();
|
|
17887
|
+
}
|
|
17888
|
+
} finally{
|
|
17889
|
+
if (_didIteratorError2) {
|
|
17890
|
+
throw _iteratorError2;
|
|
17891
|
+
}
|
|
17892
|
+
}
|
|
17893
|
+
}
|
|
17894
|
+
}
|
|
17895
|
+
} catch (err) {
|
|
17896
|
+
_didIteratorError1 = true;
|
|
17897
|
+
_iteratorError1 = err;
|
|
17898
|
+
} finally{
|
|
17899
|
+
try {
|
|
17900
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
17901
|
+
_iterator1.return();
|
|
17902
|
+
}
|
|
17903
|
+
} finally{
|
|
17904
|
+
if (_didIteratorError1) {
|
|
17905
|
+
throw _iteratorError1;
|
|
17906
|
+
}
|
|
17907
|
+
}
|
|
17908
|
+
}
|
|
17909
|
+
}
|
|
17910
|
+
};
|
|
17911
|
+
}
|
|
17912
|
+
};
|
|
17913
|
+
|
|
17639
17914
|
/**
|
|
17640
17915
|
* ESLint plugin for `@dereekb/firebase` rules.
|
|
17641
17916
|
*
|
|
@@ -17657,7 +17932,8 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17657
17932
|
'require-service-factory-for-dbx-model': FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE,
|
|
17658
17933
|
'require-dbx-model-companion-tags': FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE,
|
|
17659
17934
|
'require-canonical-api-spec-filename': FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE,
|
|
17660
|
-
'require-api-crud-spec-for-group': FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE
|
|
17935
|
+
'require-api-crud-spec-for-group': FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE,
|
|
17936
|
+
'require-dbx-model-api-params-tag': FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE
|
|
17661
17937
|
}
|
|
17662
17938
|
};
|
|
17663
17939
|
/**
|
|
@@ -17666,4 +17942,4 @@ function hasCrudSpec(groupDir, group) {
|
|
|
17666
17942
|
* @dbxAllowConstantName
|
|
17667
17943
|
*/ var firebaseESLintPlugin = FIREBASE_ESLINT_PLUGIN;
|
|
17668
17944
|
|
|
17669
|
-
export { API_DETAILS_IMPORT_MODULE, DBX_MODEL_FIREBASE_INDEX_MARKER, DBX_MODEL_SERVICE_FACTORY_TAG, DEFAULT_API_DETAILS_FACTORY_NAME, DEFAULT_CONSTRAINT_FACTORY_NAMES, DEFAULT_CRUD_FUNCTION_TYPE_VERBS, DEFAULT_CRUD_VERB_NAMES, DEFAULT_DISCOVERY_EXCLUDED_DIRS, DEFAULT_FACTORY_SEARCH_ROOTS, DEFAULT_FACTORY_TAG, DEFAULT_FIRESTORE_RULES_FILENAME, DEFAULT_FUNCTION_DIR_SEGMENT, DEFAULT_IDENTITY_FACTORY_NAME, DEFAULT_INDEX_AFFECTING_CONSTRAINT_NAMES, DEFAULT_MODEL_MARKER_TAG, DEFAULT_MODEL_SEARCH_ROOTS, DEFAULT_PAGINATION_CONSTRAINT_NAMES, DEFAULT_REGISTRY_FACTORY_CALL_NAME, DEFAULT_STORAGE_FILE_UPLOAD_POLICY_TYPE_NAME, DEFAULT_STORAGE_RULES_FILENAME, FIREBASE_ESLINT_PLUGIN, FIREBASE_MODEL_SERVICE_FACTORY_MODULE, FIREBASE_MODEL_SERVICE_FACTORY_NAME, FIREBASE_MODULE, FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE, FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE, FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE, FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE, FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_VALID_DISPATCHER_RULE, FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE, FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE, FIREBASE_REQUIRE_FIRESTORE_RULE_FOR_SERVICE_MODEL_RULE, FIREBASE_REQUIRE_INPUT_TYPE_FOR_API_DETAILS_RULE, FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE, FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE, FIREBASE_REQUIRE_TAGGED_FIRESTORE_CONSTRAINTS_RULE, INPUT_TYPE_PROPERTY_NAME, MIRRORS_POLICY_KEY_MARKER_REGEX, MODEL_FIREBASE_CRUD_FUNCTION_CONFIG_MAP_TYPE_NAME, QUERY_SUFFIX, discoveryGlobExcludeFilter, firebaseESLintPlugin, parseFirestoreRules, parseStorageRules };
|
|
17945
|
+
export { API_DETAILS_IMPORT_MODULE, DBX_MODEL_API_PARAMS_MARKER, DBX_MODEL_FIREBASE_INDEX_MARKER, DBX_MODEL_SERVICE_FACTORY_TAG, DEFAULT_API_DETAILS_FACTORY_NAME, DEFAULT_CONSTRAINT_FACTORY_NAMES, DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX, DEFAULT_CRUD_FUNCTION_TYPE_VERBS, DEFAULT_CRUD_VERB_NAMES, DEFAULT_DISCOVERY_EXCLUDED_DIRS, DEFAULT_FACTORY_SEARCH_ROOTS, DEFAULT_FACTORY_TAG, DEFAULT_FIRESTORE_RULES_FILENAME, DEFAULT_FUNCTION_DIR_SEGMENT, DEFAULT_FUNCTION_TYPE_MAP_SUFFIX, DEFAULT_IDENTITY_FACTORY_NAME, DEFAULT_INDEX_AFFECTING_CONSTRAINT_NAMES, DEFAULT_MODEL_MARKER_TAG, DEFAULT_MODEL_SEARCH_ROOTS, DEFAULT_PAGINATION_CONSTRAINT_NAMES, DEFAULT_REGISTRY_FACTORY_CALL_NAME, DEFAULT_STORAGE_FILE_UPLOAD_POLICY_TYPE_NAME, DEFAULT_STORAGE_RULES_FILENAME, FIREBASE_ESLINT_PLUGIN, FIREBASE_MODEL_SERVICE_FACTORY_MODULE, FIREBASE_MODEL_SERVICE_FACTORY_NAME, FIREBASE_MODULE, FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE, FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE, FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE, FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE, FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE, FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE, FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_VALID_DISPATCHER_RULE, FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE, FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE, FIREBASE_REQUIRE_FIRESTORE_RULE_FOR_SERVICE_MODEL_RULE, FIREBASE_REQUIRE_INPUT_TYPE_FOR_API_DETAILS_RULE, FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE, FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE, FIREBASE_REQUIRE_TAGGED_FIRESTORE_CONSTRAINTS_RULE, INPUT_TYPE_PROPERTY_NAME, MIRRORS_POLICY_KEY_MARKER_REGEX, MODEL_FIREBASE_CRUD_FUNCTION_CONFIG_MAP_TYPE_NAME, QUERY_SUFFIX, discoveryGlobExcludeFilter, firebaseESLintPlugin, parseFirestoreRules, parseStorageRules };
|
package/eslint/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase/eslint",
|
|
3
|
-
"version": "13.12.
|
|
3
|
+
"version": "13.12.9",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/util": "13.12.
|
|
5
|
+
"@dereekb/util": "13.12.9",
|
|
6
6
|
"@marcbachmann/cel-js": "^7.6.1",
|
|
7
7
|
"@typescript-eslint/parser": "8.59.3",
|
|
8
8
|
"@typescript-eslint/utils": "8.59.3"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
|
-
"@dereekb/firebase": "13.12.
|
|
11
|
+
"@dereekb/firebase": "13.12.9",
|
|
12
12
|
"eslint": "10.4.0",
|
|
13
13
|
"firebase": "^12.12.1"
|
|
14
14
|
},
|
|
@@ -13,6 +13,7 @@ export { FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE, DEFAULT_FACTORY_SE
|
|
|
13
13
|
export { FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE, type FirebaseRequireDbxModelCompanionTagsRuleOptions, type FirebaseRequireDbxModelCompanionTagsRuleDefinition } from './require-dbx-model-companion-tags.rule';
|
|
14
14
|
export { FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE, DEFAULT_FUNCTION_DIR_SEGMENT, type FirebaseRequireCanonicalApiSpecFilenameRuleOptions, type FirebaseRequireCanonicalApiSpecFilenameRuleDefinition } from './require-canonical-api-spec-filename.rule';
|
|
15
15
|
export { FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE, type FirebaseRequireApiCrudSpecForGroupRuleOptions, type FirebaseRequireApiCrudSpecForGroupRuleDefinition } from './require-api-crud-spec-for-group.rule';
|
|
16
|
+
export { FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE, DBX_MODEL_API_PARAMS_MARKER, DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX, DEFAULT_FUNCTION_TYPE_MAP_SUFFIX, type FirebaseRequireDbxModelApiParamsTagRuleOptions, type FirebaseRequireDbxModelApiParamsTagRuleDefinition } from './require-dbx-model-api-params-tag.rule';
|
|
16
17
|
export { parseStorageRules, MIRRORS_POLICY_KEY_MARKER_REGEX, type ParsedRuleBranch, type ParsedStorageRulesBlock } from './storage-rules-parser';
|
|
17
18
|
export { parseFirestoreRules, type ParsedFirestoreMatchBlock } from './firestore-rules-parser';
|
|
18
19
|
export { FIREBASE_ESLINT_PLUGIN, firebaseESLintPlugin, type FirebaseEslintPlugin } from './plugin';
|
|
@@ -13,6 +13,7 @@ import { FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE } from './require-s
|
|
|
13
13
|
import { FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE } from './require-dbx-model-companion-tags.rule';
|
|
14
14
|
import { FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE } from './require-canonical-api-spec-filename.rule';
|
|
15
15
|
import { FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE } from './require-api-crud-spec-for-group.rule';
|
|
16
|
+
import { FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE } from './require-dbx-model-api-params-tag.rule';
|
|
16
17
|
/**
|
|
17
18
|
* ESLint plugin interface for `@dereekb/firebase` rules.
|
|
18
19
|
*/
|
|
@@ -33,6 +34,7 @@ export interface FirebaseEslintPlugin {
|
|
|
33
34
|
readonly 'require-dbx-model-companion-tags': typeof FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE;
|
|
34
35
|
readonly 'require-canonical-api-spec-filename': typeof FIREBASE_REQUIRE_CANONICAL_API_SPEC_FILENAME_RULE;
|
|
35
36
|
readonly 'require-api-crud-spec-for-group': typeof FIREBASE_REQUIRE_API_CRUD_SPEC_FOR_GROUP_RULE;
|
|
37
|
+
readonly 'require-dbx-model-api-params-tag': typeof FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE;
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type AstNode } from './util';
|
|
2
|
+
/**
|
|
3
|
+
* JSDoc marker tag that every CRUD params interface should carry so the dbx-components manifest
|
|
4
|
+
* extractor (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) records it as an
|
|
5
|
+
* intentionally-exposed API params type rather than an untagged one.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DBX_MODEL_API_PARAMS_MARKER = "dbxModelApiParams";
|
|
8
|
+
/**
|
|
9
|
+
* Suffix on the type alias that declares a model-group CRUD function config (e.g.
|
|
10
|
+
* `GuestbookModelCrudFunctionsConfig`). Its referenced params interfaces are the ones the marker
|
|
11
|
+
* tag is required on.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX = "ModelCrudFunctionsConfig";
|
|
14
|
+
/**
|
|
15
|
+
* Suffix on the type alias that declares a group's standalone function type map (e.g.
|
|
16
|
+
* `GuestbookFunctionTypeMap`). Each entry's params type is also subject to the marker tag.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_FUNCTION_TYPE_MAP_SUFFIX = "FunctionTypeMap";
|
|
19
|
+
/**
|
|
20
|
+
* Options for the require-dbx-model-api-params-tag rule.
|
|
21
|
+
*/
|
|
22
|
+
export interface FirebaseRequireDbxModelApiParamsTagRuleOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Suffix identifying the CRUD functions config type alias. Defaults to {@link DEFAULT_CRUD_FUNCTIONS_CONFIG_SUFFIX}.
|
|
25
|
+
*/
|
|
26
|
+
readonly configTypeSuffix?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to also inspect `*FunctionTypeMap` aliases for params types. Defaults to `true`.
|
|
29
|
+
*/
|
|
30
|
+
readonly alsoFunctionTypeMap?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Marker tag name (without the leading `@`). Defaults to {@link DBX_MODEL_API_PARAMS_MARKER}.
|
|
33
|
+
*/
|
|
34
|
+
readonly tagName?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* ESLint rule definition for require-dbx-model-api-params-tag.
|
|
38
|
+
*/
|
|
39
|
+
export interface FirebaseRequireDbxModelApiParamsTagRuleDefinition {
|
|
40
|
+
readonly meta: {
|
|
41
|
+
readonly type: 'suggestion';
|
|
42
|
+
readonly fixable: undefined;
|
|
43
|
+
readonly docs: {
|
|
44
|
+
readonly description: string;
|
|
45
|
+
readonly recommended: boolean;
|
|
46
|
+
};
|
|
47
|
+
readonly messages: Readonly<Record<string, string>>;
|
|
48
|
+
readonly schema: readonly object[];
|
|
49
|
+
};
|
|
50
|
+
create(context: {
|
|
51
|
+
options: FirebaseRequireDbxModelApiParamsTagRuleOptions[];
|
|
52
|
+
report: (descriptor: {
|
|
53
|
+
node: AstNode;
|
|
54
|
+
messageId: string;
|
|
55
|
+
data?: Record<string, string>;
|
|
56
|
+
}) => void;
|
|
57
|
+
sourceCode: AstNode;
|
|
58
|
+
}): Record<string, (node: AstNode) => void>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* ESLint rule that requires every params interface referenced by a `*ModelCrudFunctionsConfig` (and,
|
|
62
|
+
* by default, `*FunctionTypeMap`) type alias and declared in the same file to carry the
|
|
63
|
+
* `@dbxModelApiParams` JSDoc marker tag.
|
|
64
|
+
*
|
|
65
|
+
* The marker is the signal the dbx-components manifest extractor
|
|
66
|
+
* (`packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts`) reads to distinguish an
|
|
67
|
+
* intentionally-exposed API params type from an untagged one — missing it produces the
|
|
68
|
+
* `[no-api-params-tag]` build warning and the "Missing `@dbxModelApiParams` marker" hint in the
|
|
69
|
+
* `dbx_model_api_lookup` MCP tool. This rule surfaces the same gap in-editor at lint time.
|
|
70
|
+
*
|
|
71
|
+
* Same-file resolution only — matching the extractor, which itself resolves params interfaces from a
|
|
72
|
+
* single in-memory source file. Params types declared in another file (e.g. shared base params like
|
|
73
|
+
* `TargetModelParams`) are skipped, exactly as the extractor reports them as unresolved.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* export type GuestbookModelCrudFunctionsConfig = {
|
|
78
|
+
* guestbook: { create: CreateGuestbookParams };
|
|
79
|
+
* };
|
|
80
|
+
*
|
|
81
|
+
* // OK
|
|
82
|
+
* /**
|
|
83
|
+
* * @dbxModelApiParams
|
|
84
|
+
* *\/
|
|
85
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
86
|
+
*
|
|
87
|
+
* // WARN — missingApiParamsTag
|
|
88
|
+
* export interface CreateGuestbookParams { readonly name: string; }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare const FIREBASE_REQUIRE_DBX_MODEL_API_PARAMS_TAG_RULE: FirebaseRequireDbxModelApiParamsTagRuleDefinition;
|
package/index.cjs.js
CHANGED
|
@@ -11717,6 +11717,7 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
11717
11717
|
addCallFunctions('update', _callFn, modelType);
|
|
11718
11718
|
addCallFunctions('delete', _callFn, modelType);
|
|
11719
11719
|
addCallFunctions('query', _callFn, modelType);
|
|
11720
|
+
addCallFunctions('invoke', _callFn, modelType);
|
|
11720
11721
|
// tslint:disable-next-line
|
|
11721
11722
|
x[modelType] = modelTypeCalls;
|
|
11722
11723
|
});
|
package/index.esm.js
CHANGED
|
@@ -11715,6 +11715,7 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
11715
11715
|
addCallFunctions('update', _callFn, modelType);
|
|
11716
11716
|
addCallFunctions('delete', _callFn, modelType);
|
|
11717
11717
|
addCallFunctions('query', _callFn, modelType);
|
|
11718
|
+
addCallFunctions('invoke', _callFn, modelType);
|
|
11718
11719
|
// tslint:disable-next-line
|
|
11719
11720
|
x[modelType] = modelTypeCalls;
|
|
11720
11721
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase",
|
|
3
|
-
"version": "13.12.
|
|
3
|
+
"version": "13.12.9",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"exports": {
|
|
6
6
|
"./test": {
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@dereekb/date": "13.12.
|
|
28
|
-
"@dereekb/model": "13.12.
|
|
29
|
-
"@dereekb/rxjs": "13.12.
|
|
30
|
-
"@dereekb/util": "13.12.
|
|
27
|
+
"@dereekb/date": "13.12.9",
|
|
28
|
+
"@dereekb/model": "13.12.9",
|
|
29
|
+
"@dereekb/rxjs": "13.12.9",
|
|
30
|
+
"@dereekb/util": "13.12.9",
|
|
31
31
|
"@firebase/rules-unit-testing": "5.0.0",
|
|
32
32
|
"@marcbachmann/cel-js": "^7.6.1",
|
|
33
33
|
"@typescript-eslint/parser": "8.59.3",
|
|
@@ -43,6 +43,11 @@ export type ModelFirebaseUpdateFunction<I, O = void> = ModelFirebaseCrudFunction
|
|
|
43
43
|
* Delete function for a model. Returns void by default.
|
|
44
44
|
*/
|
|
45
45
|
export type ModelFirebaseDeleteFunction<I, O = void> = ModelFirebaseCrudFunction<I, O>;
|
|
46
|
+
/**
|
|
47
|
+
* Invoke function for a model. Covers RPC-style operations that don't fit
|
|
48
|
+
* a CRUD verb (e.g. regenerate-thumbnails, resync-with-external). Returns void by default.
|
|
49
|
+
*/
|
|
50
|
+
export type ModelFirebaseInvokeFunction<I, O = void> = ModelFirebaseCrudFunction<I, O>;
|
|
46
51
|
/**
|
|
47
52
|
* Query function for a model. Returns {@link OnCallQueryModelResult} (a paged, cursorable
|
|
48
53
|
* collection) by default. The input type defaults to {@link OnCallQueryModelRequestParams}
|
|
@@ -64,7 +69,7 @@ export type ModelFirebaseCrudFunctionTypeMap<T extends FirestoreModelIdentity =
|
|
|
64
69
|
* Can be `null`/`undefined` (no CRUD functions for this model) or a partial record of
|
|
65
70
|
* create/read/update/delete/query configurations, each optionally with specifiers.
|
|
66
71
|
*/
|
|
67
|
-
export type ModelFirebaseCrudFunctionTypeMapEntry = MaybeNot | Partial<ModelFirebaseCrudFunctionCreateTypeConfig & ModelFirebaseCrudFunctionReadTypeConfig & ModelFirebaseCrudFunctionUpdateTypeConfig & ModelFirebaseCrudFunctionDeleteTypeConfig & ModelFirebaseCrudFunctionQueryTypeConfig>;
|
|
72
|
+
export type ModelFirebaseCrudFunctionTypeMapEntry = MaybeNot | Partial<ModelFirebaseCrudFunctionCreateTypeConfig & ModelFirebaseCrudFunctionReadTypeConfig & ModelFirebaseCrudFunctionUpdateTypeConfig & ModelFirebaseCrudFunctionDeleteTypeConfig & ModelFirebaseCrudFunctionQueryTypeConfig & ModelFirebaseCrudFunctionInvokeTypeConfig>;
|
|
68
73
|
export type ModelFirebaseCrudFunctionTypeMapEntryWithReturnType<I = unknown, O = unknown> = [I, O];
|
|
69
74
|
export type ModelFirebaseCrudFunctionTypeSpecifierConfig = Record<string | number, unknown | ModelFirebaseCrudFunctionTypeMapEntryWithReturnType>;
|
|
70
75
|
export type ModelFirebaseCrudFunctionCreateTypeConfig = {
|
|
@@ -82,6 +87,9 @@ export type ModelFirebaseCrudFunctionDeleteTypeConfig = {
|
|
|
82
87
|
export type ModelFirebaseCrudFunctionQueryTypeConfig = {
|
|
83
88
|
readonly query: unknown;
|
|
84
89
|
};
|
|
90
|
+
export type ModelFirebaseCrudFunctionInvokeTypeConfig = {
|
|
91
|
+
readonly invoke: unknown;
|
|
92
|
+
};
|
|
85
93
|
/**
|
|
86
94
|
* Default specifier string (`'_'`) used when a CRUD operation has specifiers but one
|
|
87
95
|
* should map to the base function name without a specifier suffix.
|
package/test/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase/test",
|
|
3
|
-
"version": "13.12.
|
|
3
|
+
"version": "13.12.9",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/date": "13.12.
|
|
6
|
-
"@dereekb/firebase": "13.12.
|
|
7
|
-
"@dereekb/model": "13.12.
|
|
8
|
-
"@dereekb/rxjs": "13.12.
|
|
9
|
-
"@dereekb/util": "13.12.
|
|
5
|
+
"@dereekb/date": "13.12.9",
|
|
6
|
+
"@dereekb/firebase": "13.12.9",
|
|
7
|
+
"@dereekb/model": "13.12.9",
|
|
8
|
+
"@dereekb/rxjs": "13.12.9",
|
|
9
|
+
"@dereekb/util": "13.12.9",
|
|
10
10
|
"@firebase/rules-unit-testing": "5.0.0",
|
|
11
11
|
"date-fns": "^4.1.0",
|
|
12
12
|
"firebase": "^12.12.1",
|