@dereekb/firebase-server 13.14.0 → 13.16.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/mcp/index.esm.js CHANGED
@@ -3,8 +3,8 @@ import { existsSync, readFileSync } from 'node:fs';
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { getOidcScopesFromRequest } from '@dereekb/firebase-server/oidc';
6
- import { makeValuesGroupMap, authRolesSetHasRoles } from '@dereekb/util';
7
- import { ModelApiCallModelDispatchService, ModelApiGetService, FirebaseServerEnvService, FirebaseServerAnalyticsService } from '@dereekb/firebase-server';
6
+ import { makeValuesGroupMap, performAsyncTasks, authRolesSetHasRoles } from '@dereekb/util';
7
+ import { ModelApiCallModelDispatchService, ModelApiGetService, FirebaseServerStorageService, FirebaseServerEnvService, FirebaseServerAnalyticsService } from '@dereekb/firebase-server';
8
8
  import { inspect } from 'node:util';
9
9
  import { arktypeToJsonSchemaForExport } from '@dereekb/model';
10
10
  import { callModelOidcScopeForCallType } from '@dereekb/firebase';
@@ -115,13 +115,13 @@ function _define_property$7(obj, key, value) {
115
115
  * NestJS injection token for the optional {@link McpAuthRoleReader} provider.
116
116
  */ var MCP_AUTH_ROLE_READER = 'MCP_AUTH_ROLE_READER';
117
117
 
118
- function _type_of$2(obj) {
118
+ function _type_of$3(obj) {
119
119
  "@swc/helpers - typeof";
120
120
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
121
121
  }
122
122
  function __decorate(decorators, target, key, desc) {
123
123
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
124
- if ((typeof Reflect === "undefined" ? "undefined" : _type_of$2(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
124
+ if ((typeof Reflect === "undefined" ? "undefined" : _type_of$3(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
125
125
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
126
126
  return c > 3 && r && Object.defineProperty(target, key, r), r;
127
127
  }
@@ -190,7 +190,7 @@ function _class_call_check$4(instance, Constructor) {
190
190
  return isDefault ? "".concat(modelType, ".").concat(call, "._") : "".concat(modelType, ".").concat(call, ".").concat(specifier);
191
191
  }
192
192
 
193
- function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
193
+ function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
194
194
  try {
195
195
  var info = gen[key](arg);
196
196
  var value = info.value;
@@ -204,22 +204,22 @@ function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
204
204
  Promise.resolve(value).then(_next, _throw);
205
205
  }
206
206
  }
207
- function _async_to_generator$4(fn) {
207
+ function _async_to_generator$5(fn) {
208
208
  return function() {
209
209
  var self = this, args = arguments;
210
210
  return new Promise(function(resolve, reject) {
211
211
  var gen = fn.apply(self, args);
212
212
  function _next(value) {
213
- asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "next", value);
213
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "next", value);
214
214
  }
215
215
  function _throw(err) {
216
- asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "throw", err);
216
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "throw", err);
217
217
  }
218
218
  _next(undefined);
219
219
  });
220
220
  };
221
221
  }
222
- function _instanceof(left, right) {
222
+ function _instanceof$1(left, right) {
223
223
  "@swc/helpers - instanceof";
224
224
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
225
225
  return !!right[Symbol.hasInstance](left);
@@ -227,7 +227,7 @@ function _instanceof(left, right) {
227
227
  return left instanceof right;
228
228
  }
229
229
  }
230
- function _ts_generator$4(thisArg, body) {
230
+ function _ts_generator$5(thisArg, body) {
231
231
  var f, y, t, _ = {
232
232
  label: 0,
233
233
  sent: function() {
@@ -355,9 +355,9 @@ function _ts_generator$4(thisArg, body) {
355
355
  * @param details - The handler-level API details (carries the mapper + Tier 2/3 formatters).
356
356
  * @returns The MCP tool response content.
357
357
  */ function formatMcpToolResponse(result, params, details) {
358
- return _async_to_generator$4(function() {
358
+ return _async_to_generator$5(function() {
359
359
  var mcp, value, _tmp, context, response, summary;
360
- return _ts_generator$4(this, function(_state) {
360
+ return _ts_generator$5(this, function(_state) {
361
361
  switch(_state.label){
362
362
  case 0:
363
363
  mcp = details === null || details === void 0 ? void 0 : details.mcp;
@@ -423,7 +423,7 @@ function _ts_generator$4(thisArg, body) {
423
423
  * @param error - The thrown error.
424
424
  * @returns An MCP tool response with `isError: true` and the error message as a text block.
425
425
  */ function formatMcpToolErrorResponse(error) {
426
- var message = _instanceof(error, Error) ? error.message : String(error);
426
+ var message = _instanceof$1(error, Error) ? error.message : String(error);
427
427
  return {
428
428
  isError: true,
429
429
  content: [
@@ -521,15 +521,15 @@ function stringifyResult(result) {
521
521
  return callModelOidcScopeForCallType(callType);
522
522
  }
523
523
 
524
- function _array_like_to_array$6(arr, len) {
524
+ function _array_like_to_array$7(arr, len) {
525
525
  if (len == null || len > arr.length) len = arr.length;
526
526
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
527
527
  return arr2;
528
528
  }
529
- function _array_with_holes$2(arr) {
529
+ function _array_with_holes$3(arr) {
530
530
  if (Array.isArray(arr)) return arr;
531
531
  }
532
- function _iterable_to_array_limit$2(arr, i) {
532
+ function _iterable_to_array_limit$3(arr, i) {
533
533
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
534
534
  if (_i == null) return;
535
535
  var _arr = [];
@@ -553,23 +553,23 @@ function _iterable_to_array_limit$2(arr, i) {
553
553
  }
554
554
  return _arr;
555
555
  }
556
- function _non_iterable_rest$2() {
556
+ function _non_iterable_rest$3() {
557
557
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
558
558
  }
559
- function _sliced_to_array$2(arr, i) {
560
- return _array_with_holes$2(arr) || _iterable_to_array_limit$2(arr, i) || _unsupported_iterable_to_array$6(arr, i) || _non_iterable_rest$2();
559
+ function _sliced_to_array$3(arr, i) {
560
+ return _array_with_holes$3(arr) || _iterable_to_array_limit$3(arr, i) || _unsupported_iterable_to_array$7(arr, i) || _non_iterable_rest$3();
561
561
  }
562
- function _type_of$1(obj) {
562
+ function _type_of$2(obj) {
563
563
  "@swc/helpers - typeof";
564
564
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
565
565
  }
566
- function _unsupported_iterable_to_array$6(o, minLen) {
566
+ function _unsupported_iterable_to_array$7(o, minLen) {
567
567
  if (!o) return;
568
- if (typeof o === "string") return _array_like_to_array$6(o, minLen);
568
+ if (typeof o === "string") return _array_like_to_array$7(o, minLen);
569
569
  var n = Object.prototype.toString.call(o).slice(8, -1);
570
570
  if (n === "Object" && o.constructor) n = o.constructor.name;
571
571
  if (n === "Map" || n === "Set") return Array.from(n);
572
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
572
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$7(o, minLen);
573
573
  }
574
574
  /**
575
575
  * Default `toJsonSchema()` options.
@@ -835,18 +835,18 @@ function _unsupported_iterable_to_array$6(o, minLen) {
835
835
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
836
836
  try {
837
837
  for(var _iterator = Object.entries(apiDetails.models)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
838
- var _step_value = _sliced_to_array$2(_step.value, 2), modelType = _step_value[0], modelEntry = _step_value[1];
838
+ var _step_value = _sliced_to_array$3(_step.value, 2), modelType = _step_value[0], modelEntry = _step_value[1];
839
839
  var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
840
840
  try {
841
841
  for(var _iterator1 = Object.entries(modelEntry.calls)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
842
- var _step_value1 = _sliced_to_array$2(_step1.value, 2), callType = _step_value1[0], callDetails = _step_value1[1];
842
+ var _step_value1 = _sliced_to_array$3(_step1.value, 2), callType = _step_value1[0], callDetails = _step_value1[1];
843
843
  if (callDetails == null) {
844
844
  continue;
845
845
  }
846
846
  var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
847
847
  try {
848
848
  for(var _iterator2 = Object.entries(callDetails.specifiers)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
849
- var _step_value2 = _sliced_to_array$2(_step2.value, 2), specifierKey = _step_value2[0], handlerDetails = _step_value2[1];
849
+ var _step_value2 = _sliced_to_array$3(_step2.value, 2), specifierKey = _step_value2[0], handlerDetails = _step_value2[1];
850
850
  var _ref;
851
851
  var _naming_modelSegments, _handlerDetails_mcp, _handlerDetails_mcp1;
852
852
  if (handlerDetails == null) {
@@ -1094,7 +1094,7 @@ function resolveInputSchema(context) {
1094
1094
  var result;
1095
1095
  try {
1096
1096
  var exported = arktypeToJsonSchemaForExport(handlerDetails.inputType);
1097
- if (exported && (typeof exported === "undefined" ? "undefined" : _type_of$1(exported)) === 'object') {
1097
+ if (exported && (typeof exported === "undefined" ? "undefined" : _type_of$2(exported)) === 'object') {
1098
1098
  result = exported;
1099
1099
  } else {
1100
1100
  // arktypeToJsonSchemaForExport returned a non-object (shouldn't happen for object schemas).
@@ -1113,15 +1113,15 @@ function resolveInputSchema(context) {
1113
1113
  return result;
1114
1114
  }
1115
1115
 
1116
- function _array_like_to_array$5(arr, len) {
1116
+ function _array_like_to_array$6(arr, len) {
1117
1117
  if (len == null || len > arr.length) len = arr.length;
1118
1118
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1119
1119
  return arr2;
1120
1120
  }
1121
1121
  function _array_without_holes$5(arr) {
1122
- if (Array.isArray(arr)) return _array_like_to_array$5(arr);
1122
+ if (Array.isArray(arr)) return _array_like_to_array$6(arr);
1123
1123
  }
1124
- function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
1124
+ function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
1125
1125
  try {
1126
1126
  var info = gen[key](arg);
1127
1127
  var value = info.value;
@@ -1135,16 +1135,16 @@ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
1135
1135
  Promise.resolve(value).then(_next, _throw);
1136
1136
  }
1137
1137
  }
1138
- function _async_to_generator$3(fn) {
1138
+ function _async_to_generator$4(fn) {
1139
1139
  return function() {
1140
1140
  var self = this, args = arguments;
1141
1141
  return new Promise(function(resolve, reject) {
1142
1142
  var gen = fn.apply(self, args);
1143
1143
  function _next(value) {
1144
- asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
1144
+ asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "next", value);
1145
1145
  }
1146
1146
  function _throw(err) {
1147
- asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
1147
+ asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "throw", err);
1148
1148
  }
1149
1149
  _next(undefined);
1150
1150
  });
@@ -1157,17 +1157,17 @@ function _non_iterable_spread$5() {
1157
1157
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1158
1158
  }
1159
1159
  function _to_consumable_array$5(arr) {
1160
- return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$5();
1160
+ return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$6(arr) || _non_iterable_spread$5();
1161
1161
  }
1162
- function _unsupported_iterable_to_array$5(o, minLen) {
1162
+ function _unsupported_iterable_to_array$6(o, minLen) {
1163
1163
  if (!o) return;
1164
- if (typeof o === "string") return _array_like_to_array$5(o, minLen);
1164
+ if (typeof o === "string") return _array_like_to_array$6(o, minLen);
1165
1165
  var n = Object.prototype.toString.call(o).slice(8, -1);
1166
1166
  if (n === "Object" && o.constructor) n = o.constructor.name;
1167
1167
  if (n === "Map" || n === "Set") return Array.from(n);
1168
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
1168
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
1169
1169
  }
1170
- function _ts_generator$3(thisArg, body) {
1170
+ function _ts_generator$4(thisArg, body) {
1171
1171
  var f, y, t, _ = {
1172
1172
  label: 0,
1173
1173
  sent: function() {
@@ -1337,9 +1337,9 @@ function _ts_generator$3(thisArg, body) {
1337
1337
  }
1338
1338
  // MARK: Handler
1339
1339
  function modelGetToolHandler(args, ctx, deps) {
1340
- return _async_to_generator$3(function() {
1340
+ return _async_to_generator$4(function() {
1341
1341
  var result, input, identity, resolvedKeys, merged, error;
1342
- return _ts_generator$3(this, function(_state) {
1342
+ return _ts_generator$4(this, function(_state) {
1343
1343
  switch(_state.label){
1344
1344
  case 0:
1345
1345
  _state.trys.push([
@@ -1446,9 +1446,9 @@ function resolveKeys(keys, identity) {
1446
1446
  return resolved;
1447
1447
  }
1448
1448
  function readInChunks(input) {
1449
- return _async_to_generator$3(function() {
1449
+ return _async_to_generator$4(function() {
1450
1450
  var modelType, keys, auth, readDocuments, merged, offset, _merged_results, _merged_errors, batch, partial;
1451
- return _ts_generator$3(this, function(_state) {
1451
+ return _ts_generator$4(this, function(_state) {
1452
1452
  switch(_state.label){
1453
1453
  case 0:
1454
1454
  modelType = input.modelType, keys = input.keys, auth = input.auth, readDocuments = input.readDocuments;
@@ -1562,13 +1562,13 @@ var MODEL_GET_OUTPUT_SCHEMA = {
1562
1562
  }
1563
1563
  };
1564
1564
 
1565
- function _array_like_to_array$4(arr, len) {
1565
+ function _array_like_to_array$5(arr, len) {
1566
1566
  if (len == null || len > arr.length) len = arr.length;
1567
1567
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1568
1568
  return arr2;
1569
1569
  }
1570
1570
  function _array_without_holes$4(arr) {
1571
- if (Array.isArray(arr)) return _array_like_to_array$4(arr);
1571
+ if (Array.isArray(arr)) return _array_like_to_array$5(arr);
1572
1572
  }
1573
1573
  function _define_property$6(obj, key, value) {
1574
1574
  if (key in obj) {
@@ -1624,15 +1624,15 @@ function _object_spread_props(target, source) {
1624
1624
  return target;
1625
1625
  }
1626
1626
  function _to_consumable_array$4(arr) {
1627
- return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
1627
+ return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$4();
1628
1628
  }
1629
- function _unsupported_iterable_to_array$4(o, minLen) {
1629
+ function _unsupported_iterable_to_array$5(o, minLen) {
1630
1630
  if (!o) return;
1631
- if (typeof o === "string") return _array_like_to_array$4(o, minLen);
1631
+ if (typeof o === "string") return _array_like_to_array$5(o, minLen);
1632
1632
  var n = Object.prototype.toString.call(o).slice(8, -1);
1633
1633
  if (n === "Object" && o.constructor) n = o.constructor.name;
1634
1634
  if (n === "Map" || n === "Set") return Array.from(n);
1635
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
1635
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
1636
1636
  }
1637
1637
  // MARK: Constants
1638
1638
  /**
@@ -1992,11 +1992,11 @@ function findGroupCount(query, manifest) {
1992
1992
  function buildModelNotFoundMessage(query, manifest) {
1993
1993
  var groupMatch = findGroupCount(query, manifest);
1994
1994
  var message;
1995
- if (groupMatch != null) {
1995
+ if (groupMatch == null) {
1996
+ message = 'model-info: no exact match for "'.concat(query, '". Call `model-info` with no arguments to list groups, or pass all:true for the full catalog.');
1997
+ } else {
1996
1998
  var plural = groupMatch.modelCount === 1 ? '' : 's';
1997
1999
  message = 'model-info: no exact match for "'.concat(query, '" — did you mean group:"').concat(groupMatch.modelGroup, '" (').concat(groupMatch.modelCount, " model").concat(plural, ')? Use modelGroup:"').concat(groupMatch.modelGroup, '", or all:true for everything.');
1998
- } else {
1999
- message = 'model-info: no exact match for "'.concat(query, '". Call `model-info` with no arguments to list groups, or pass all:true for the full catalog.');
2000
2000
  }
2001
2001
  return message;
2002
2002
  }
@@ -2537,16 +2537,16 @@ var MODEL_DECODE_OUTPUT_SCHEMA = {
2537
2537
  }
2538
2538
  };
2539
2539
 
2540
- function _array_like_to_array$3(arr, len) {
2540
+ function _array_like_to_array$4(arr, len) {
2541
2541
  if (len == null || len > arr.length) len = arr.length;
2542
2542
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
2543
2543
  return arr2;
2544
2544
  }
2545
- function _array_with_holes$1(arr) {
2545
+ function _array_with_holes$2(arr) {
2546
2546
  if (Array.isArray(arr)) return arr;
2547
2547
  }
2548
2548
  function _array_without_holes$3(arr) {
2549
- if (Array.isArray(arr)) return _array_like_to_array$3(arr);
2549
+ if (Array.isArray(arr)) return _array_like_to_array$4(arr);
2550
2550
  }
2551
2551
  function _define_property$4(obj, key, value) {
2552
2552
  if (key in obj) {
@@ -2564,7 +2564,7 @@ function _define_property$4(obj, key, value) {
2564
2564
  function _iterable_to_array$3(iter) {
2565
2565
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
2566
2566
  }
2567
- function _iterable_to_array_limit$1(arr, i) {
2567
+ function _iterable_to_array_limit$2(arr, i) {
2568
2568
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
2569
2569
  if (_i == null) return;
2570
2570
  var _arr = [];
@@ -2588,7 +2588,7 @@ function _iterable_to_array_limit$1(arr, i) {
2588
2588
  }
2589
2589
  return _arr;
2590
2590
  }
2591
- function _non_iterable_rest$1() {
2591
+ function _non_iterable_rest$2() {
2592
2592
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2593
2593
  }
2594
2594
  function _non_iterable_spread$3() {
@@ -2609,19 +2609,19 @@ function _object_spread(target) {
2609
2609
  }
2610
2610
  return target;
2611
2611
  }
2612
- function _sliced_to_array$1(arr, i) {
2613
- return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest$1();
2612
+ function _sliced_to_array$2(arr, i) {
2613
+ return _array_with_holes$2(arr) || _iterable_to_array_limit$2(arr, i) || _unsupported_iterable_to_array$4(arr, i) || _non_iterable_rest$2();
2614
2614
  }
2615
2615
  function _to_consumable_array$3(arr) {
2616
- return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
2616
+ return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$3();
2617
2617
  }
2618
- function _unsupported_iterable_to_array$3(o, minLen) {
2618
+ function _unsupported_iterable_to_array$4(o, minLen) {
2619
2619
  if (!o) return;
2620
- if (typeof o === "string") return _array_like_to_array$3(o, minLen);
2620
+ if (typeof o === "string") return _array_like_to_array$4(o, minLen);
2621
2621
  var n = Object.prototype.toString.call(o).slice(8, -1);
2622
2622
  if (n === "Object" && o.constructor) n = o.constructor.name;
2623
2623
  if (n === "Map" || n === "Set") return Array.from(n);
2624
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
2624
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
2625
2625
  }
2626
2626
  // MARK: Constants
2627
2627
  /**
@@ -2695,10 +2695,10 @@ function whoamiToolHandler(ctx, deps) {
2695
2695
  }
2696
2696
  var token = (_auth_token = auth.token) !== null && _auth_token !== void 0 ? _auth_token : {};
2697
2697
  var presentKeys = Object.entries(token).filter(function(param) {
2698
- var _param = _sliced_to_array$1(param, 2), value = _param[1];
2698
+ var _param = _sliced_to_array$2(param, 2), value = _param[1];
2699
2699
  return value !== undefined;
2700
2700
  }).map(function(param) {
2701
- var _param = _sliced_to_array$1(param, 1), key = _param[0];
2701
+ var _param = _sliced_to_array$2(param, 1), key = _param[0];
2702
2702
  return key;
2703
2703
  });
2704
2704
  var roleSet = deps.roleReader == null ? new Set() : deps.roleReader(token);
@@ -2971,18 +2971,15 @@ var WHOAMI_OUTPUT_SCHEMA = {
2971
2971
  }
2972
2972
  };
2973
2973
 
2974
- function _array_like_to_array$2(arr, len) {
2974
+ function _array_like_to_array$3(arr, len) {
2975
2975
  if (len == null || len > arr.length) len = arr.length;
2976
2976
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
2977
2977
  return arr2;
2978
2978
  }
2979
- function _array_with_holes(arr) {
2979
+ function _array_with_holes$1(arr) {
2980
2980
  if (Array.isArray(arr)) return arr;
2981
2981
  }
2982
- function _array_without_holes$2(arr) {
2983
- if (Array.isArray(arr)) return _array_like_to_array$2(arr);
2984
- }
2985
- function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
2982
+ function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
2986
2983
  try {
2987
2984
  var info = gen[key](arg);
2988
2985
  var value = info.value;
@@ -2996,56 +2993,30 @@ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
2996
2993
  Promise.resolve(value).then(_next, _throw);
2997
2994
  }
2998
2995
  }
2999
- function _async_to_generator$2(fn) {
2996
+ function _async_to_generator$3(fn) {
3000
2997
  return function() {
3001
2998
  var self = this, args = arguments;
3002
2999
  return new Promise(function(resolve, reject) {
3003
3000
  var gen = fn.apply(self, args);
3004
3001
  function _next(value) {
3005
- asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
3002
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value);
3006
3003
  }
3007
3004
  function _throw(err) {
3008
- asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
3005
+ asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err);
3009
3006
  }
3010
3007
  _next(undefined);
3011
3008
  });
3012
3009
  };
3013
3010
  }
3014
- function _class_call_check$3(instance, Constructor) {
3015
- if (!(instance instanceof Constructor)) {
3016
- throw new TypeError("Cannot call a class as a function");
3017
- }
3018
- }
3019
- function _defineProperties$3(target, props) {
3020
- for(var i = 0; i < props.length; i++){
3021
- var descriptor = props[i];
3022
- descriptor.enumerable = descriptor.enumerable || false;
3023
- descriptor.configurable = true;
3024
- if ("value" in descriptor) descriptor.writable = true;
3025
- Object.defineProperty(target, descriptor.key, descriptor);
3026
- }
3027
- }
3028
- function _create_class$3(Constructor, protoProps, staticProps) {
3029
- if (protoProps) _defineProperties$3(Constructor.prototype, protoProps);
3030
- return Constructor;
3031
- }
3032
- function _define_property$3(obj, key, value) {
3033
- if (key in obj) {
3034
- Object.defineProperty(obj, key, {
3035
- value: value,
3036
- enumerable: true,
3037
- configurable: true,
3038
- writable: true
3039
- });
3011
+ function _instanceof(left, right) {
3012
+ "@swc/helpers - instanceof";
3013
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
3014
+ return !!right[Symbol.hasInstance](left);
3040
3015
  } else {
3041
- obj[key] = value;
3016
+ return left instanceof right;
3042
3017
  }
3043
- return obj;
3044
- }
3045
- function _iterable_to_array$2(iter) {
3046
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
3047
3018
  }
3048
- function _iterable_to_array_limit(arr, i) {
3019
+ function _iterable_to_array_limit$1(arr, i) {
3049
3020
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
3050
3021
  if (_i == null) return;
3051
3022
  var _arr = [];
@@ -3069,27 +3040,25 @@ function _iterable_to_array_limit(arr, i) {
3069
3040
  }
3070
3041
  return _arr;
3071
3042
  }
3072
- function _non_iterable_rest() {
3043
+ function _non_iterable_rest$1() {
3073
3044
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3074
3045
  }
3075
- function _non_iterable_spread$2() {
3076
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3077
- }
3078
- function _sliced_to_array(arr, i) {
3079
- return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest();
3046
+ function _sliced_to_array$1(arr, i) {
3047
+ return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest$1();
3080
3048
  }
3081
- function _to_consumable_array$2(arr) {
3082
- return _array_without_holes$2(arr) || _iterable_to_array$2(arr) || _unsupported_iterable_to_array$2(arr) || _non_iterable_spread$2();
3049
+ function _type_of$1(obj) {
3050
+ "@swc/helpers - typeof";
3051
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
3083
3052
  }
3084
- function _unsupported_iterable_to_array$2(o, minLen) {
3053
+ function _unsupported_iterable_to_array$3(o, minLen) {
3085
3054
  if (!o) return;
3086
- if (typeof o === "string") return _array_like_to_array$2(o, minLen);
3055
+ if (typeof o === "string") return _array_like_to_array$3(o, minLen);
3087
3056
  var n = Object.prototype.toString.call(o).slice(8, -1);
3088
3057
  if (n === "Object" && o.constructor) n = o.constructor.name;
3089
3058
  if (n === "Map" || n === "Set") return Array.from(n);
3090
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$2(o, minLen);
3059
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
3091
3060
  }
3092
- function _ts_generator$2(thisArg, body) {
3061
+ function _ts_generator$3(thisArg, body) {
3093
3062
  var f, y, t, _ = {
3094
3063
  label: 0,
3095
3064
  sent: function() {
@@ -3188,106 +3157,1006 @@ function _ts_generator$2(thisArg, body) {
3188
3157
  };
3189
3158
  }
3190
3159
  }
3191
- var McpServerFactoryService_1;
3160
+ // MARK: Constants
3192
3161
  /**
3193
- * Injectable factory that builds {@link McpServer} instances pre-wired to the
3194
- * call model dispatch chain.
3162
+ * Reserved tool name for the built-in `batch-execute` static tool.
3163
+ */ var BATCH_EXECUTE_TOOL_NAME = 'batch-execute';
3164
+ /**
3165
+ * Synthetic call type used in the tool's dispatch identity (analytics only — the tool re-dispatches
3166
+ * to other callModel tools rather than resolving a `batch` call type of its own).
3167
+ */ var BATCH_EXECUTE_DISPATCH_CALL = 'batch';
3168
+ /**
3169
+ * Synthetic model type used in the tool's dispatch identity. The tool isn't bound to a model type
3170
+ * (each operation carries its own), so we use the literal "batch" as the identity. Apps avoiding
3171
+ * collision should not register a real model literally named "batch".
3172
+ */ var BATCH_EXECUTE_DISPATCH_MODEL_TYPE = 'batch';
3173
+ /**
3174
+ * Default per-operation concurrency when the caller does not specify `maxParallel`.
3175
+ */ var DEFAULT_BATCH_EXECUTE_MAX_PARALLEL = 5;
3176
+ /**
3177
+ * Hard upper bound on operations accepted in a single batch file, guarding against an
3178
+ * accidentally enormous upload exhausting the function's memory/time budget.
3179
+ */ var MAX_BATCH_EXECUTE_OPERATIONS = 1000;
3180
+ /**
3181
+ * Maximum bytes read from the operations file. NDJSON of typical CRUD payloads stays well under
3182
+ * this; an oversized file is rejected rather than streamed.
3183
+ */ var MAX_BATCH_EXECUTE_FILE_BYTES = 5 * 1024 * 1024;
3184
+ // MARK: Coordinate key
3185
+ /**
3186
+ * Builds the lookup key identifying a callModel dispatch coordinate. The factory indexes the
3187
+ * caller's visible callModel tools by this key; the batch handler looks each operation up by the
3188
+ * same key, so authorization reuses the exact tool set advertised on `tools/list`.
3195
3189
  *
3196
- * The factory is invoked per Streamable HTTP request — `@modelcontextprotocol/sdk`
3197
- * recommends a fresh `McpServer` + transport pair per stateless JSON-RPC request,
3198
- * which sidesteps session bookkeeping for the common Claude-connector case.
3199
- */ var McpServerFactoryService = McpServerFactoryService_1 = /*#__PURE__*/ function() {
3200
- function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader, analyticsService) {
3201
- _class_call_check$3(this, McpServerFactoryService);
3202
- _define_property$3(this, "mcpConfig", void 0);
3203
- _define_property$3(this, "dispatchService", void 0);
3204
- _define_property$3(this, "modelApiGetService", void 0);
3205
- _define_property$3(this, "roleReader", void 0);
3206
- _define_property$3(this, "_logger", new Logger(McpServerFactoryService_1.name));
3207
- _define_property$3(this, "_cachedTools", void 0);
3208
- _define_property$3(this, "_cachedStaticTools", void 0);
3209
- _define_property$3(this, "_cachedManifest", void 0);
3210
- _define_property$3(this, "_cachedManifestModels", void 0);
3211
- _define_property$3(this, "_cachedManifestAuth", void 0);
3212
- _define_property$3(this, "_manifestLoaded", false);
3213
- _define_property$3(this, "_loggedSkips", false);
3214
- _define_property$3(this, "_warnedMissingRoleReader", false);
3215
- _define_property$3(this, "_analyticsService", void 0);
3216
- this.mcpConfig = mcpConfig;
3217
- this.dispatchService = dispatchService;
3218
- this.modelApiGetService = modelApiGetService;
3219
- this.roleReader = roleReader;
3220
- this._analyticsService = analyticsService !== null && analyticsService !== void 0 ? analyticsService : noopMcpAnalyticsService();
3221
- }
3222
- _create_class$3(McpServerFactoryService, [
3223
- {
3224
- /**
3225
- * Builds a configured MCP server with tool listing + dispatch handlers wired up.
3226
- *
3227
- * @param ctx - The per-request context (auth, raw request) used when forwarding tool calls.
3228
- * @returns A configured MCP server ready to be `connect()`-ed to a transport.
3229
- */ key: "createServer",
3230
- value: function createServer(ctx) {
3231
- var _this = this;
3232
- var _this_mcpConfig_serverName, _this_mcpConfig_serverVersion, _this_mcpConfig_serverInstructions;
3233
- var baseServerName = (_this_mcpConfig_serverName = this.mcpConfig.serverName) !== null && _this_mcpConfig_serverName !== void 0 ? _this_mcpConfig_serverName : DEFAULT_MCP_SERVER_NAME;
3234
- var serverName = this.mcpConfig.readOnly === true ? "".concat(baseServerName, " (read-only)") : baseServerName;
3235
- var server = new McpServer({
3236
- name: serverName,
3237
- version: (_this_mcpConfig_serverVersion = this.mcpConfig.serverVersion) !== null && _this_mcpConfig_serverVersion !== void 0 ? _this_mcpConfig_serverVersion : '0.0.0'
3238
- }, {
3239
- instructions: (_this_mcpConfig_serverInstructions = this.mcpConfig.serverInstructions) !== null && _this_mcpConfig_serverInstructions !== void 0 ? _this_mcpConfig_serverInstructions : DEFAULT_MCP_SERVER_INSTRUCTIONS
3240
- });
3241
- server.server.registerCapabilities({
3242
- tools: {}
3243
- });
3244
- var toolGeneration = this._resolveToolDefinitions();
3245
- var staticTools = this._resolveStaticTools();
3246
- var scopes = this._resolveScopes(ctx);
3247
- var authRoles = this._resolveAuthRoles(ctx);
3248
- var combinedTools = _to_consumable_array$2(toolGeneration.tools).concat(_to_consumable_array$2(staticTools));
3249
- var visibleTools = this._filterToolsForRequest(combinedTools, {
3250
- ctx: ctx,
3251
- scopes: scopes,
3252
- authRoles: authRoles
3253
- });
3254
- var definitionsByName = new Map(visibleTools.map(function(tool) {
3255
- return [
3256
- tool.name,
3257
- tool
3258
- ];
3259
- }));
3260
- server.server.setRequestHandler(ListToolsRequestSchema, function() {
3261
- return _async_to_generator$2(function() {
3262
- var _this;
3263
- return _ts_generator$2(this, function(_state) {
3264
- _this = this;
3265
- return [
3266
- 2,
3267
- {
3268
- tools: visibleTools.map(function(tool) {
3269
- return _this._buildToolListEntry(tool, ctx, scopes);
3270
- })
3271
- }
3272
- ];
3273
- });
3274
- }).call(_this);
3275
- });
3276
- server.server.setRequestHandler(CallToolRequestSchema, function(request) {
3277
- return _async_to_generator$2(function() {
3278
- return _ts_generator$2(this, function(_state) {
3279
- return [
3280
- 2,
3281
- this._handleToolCall(request, definitionsByName, ctx)
3282
- ];
3283
- });
3284
- }).call(_this);
3285
- });
3286
- return server;
3287
- }
3288
- },
3289
- {
3290
- /**
3190
+ * @param dispatch - The `(call, modelType, specifier?)` coordinate to key.
3191
+ * @returns A stable string key. Uses a NUL separator so segment values can't collide.
3192
+ */ function batchOperationCoordKey(dispatch) {
3193
+ var _dispatch_specifier;
3194
+ return "".concat(dispatch.call, "\0").concat(dispatch.modelType, "\0").concat((_dispatch_specifier = dispatch.specifier) !== null && _dispatch_specifier !== void 0 ? _dispatch_specifier : '');
3195
+ }
3196
+ // MARK: Factory
3197
+ /**
3198
+ * Builds the built-in `batch-execute` MCP tool definition.
3199
+ *
3200
+ * The tool ingests an uploaded JSON / NDJSON file of `(call, modelType, specifier?, data)`
3201
+ * operations and runs them server-side, returning a single success/failure summary. It exists so an
3202
+ * agent can perform a bulk mutation (e.g. "update 200 workers") by *generating* the operations file
3203
+ * with a script and uploading it — rather than emitting each payload as tool-call output and paying
3204
+ * one model turn per record.
3205
+ *
3206
+ * Safety model:
3207
+ * - Every operation is validated and authorized against the caller's visible tool set *before any
3208
+ * dispatch*. A malformed or forbidden operation aborts the whole batch with a pre-flight error and
3209
+ * nothing runs — `dispatch` would otherwise bypass the `tools/list` visibility filter.
3210
+ * - Runtime failures are best-effort by default (collected into the summary); `stopOnError` halts at
3211
+ * the first failure (forcing sequential execution).
3212
+ *
3213
+ * @param deps - Storage reader, dispatch fn, and per-operation authorizer (typically wired in the
3214
+ * server factory to the request's visible tool set).
3215
+ * @returns A statically-registered {@link McpToolDefinition} ready to be appended to the MCP server
3216
+ * factory's tool registry.
3217
+ */ function createBatchExecuteTool(deps) {
3218
+ var handler = function handler(args, ctx) {
3219
+ return batchExecuteToolHandler(args, ctx, deps);
3220
+ };
3221
+ var name = BATCH_EXECUTE_TOOL_NAME;
3222
+ var description = 'Execute a batch of MCP operations server-side from an uploaded JSON/NDJSON file, returning a success/failure summary. Each line/element is an operation `{ call, modelType, specifier?, data }` matching any other write tool you could call individually. Generate the file with a script and upload it instead of invoking a per-record tool many times. Every operation is authorized against your visible tools before any run; a forbidden or malformed operation aborts the whole batch with nothing executed.';
3223
+ return {
3224
+ name: name,
3225
+ description: description,
3226
+ inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
3227
+ outputSchema: BATCH_EXECUTE_OUTPUT_SCHEMA,
3228
+ dispatch: {
3229
+ call: BATCH_EXECUTE_DISPATCH_CALL,
3230
+ modelType: BATCH_EXECUTE_DISPATCH_MODEL_TYPE
3231
+ },
3232
+ staticHandler: handler,
3233
+ filterMetadata: {
3234
+ visibilityKind: 'declarative',
3235
+ rule: {
3236
+ requireAuthenticated: true
3237
+ },
3238
+ effectiveReadOnly: false
3239
+ },
3240
+ staticWireEntry: buildStaticWireEntry({
3241
+ name: name,
3242
+ description: description,
3243
+ inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
3244
+ outputSchema: BATCH_EXECUTE_OUTPUT_SCHEMA
3245
+ })
3246
+ };
3247
+ }
3248
+ // MARK: Handler
3249
+ function batchExecuteToolHandler(args, ctx, deps) {
3250
+ return _async_to_generator$3(function() {
3251
+ var result, _deps_maxOperations, input, maxOperations, fileText, operations, preflightErrors, execution, failureCount, successCount, skippedCount, uploadDeleted, summary, error;
3252
+ return _ts_generator$3(this, function(_state) {
3253
+ switch(_state.label){
3254
+ case 0:
3255
+ _state.trys.push([
3256
+ 0,
3257
+ 4,
3258
+ ,
3259
+ 5
3260
+ ]);
3261
+ input = parseBatchExecuteInput(args);
3262
+ maxOperations = (_deps_maxOperations = deps.maxOperations) !== null && _deps_maxOperations !== void 0 ? _deps_maxOperations : MAX_BATCH_EXECUTE_OPERATIONS;
3263
+ return [
3264
+ 4,
3265
+ readOperationsFile({
3266
+ storageService: deps.storageService,
3267
+ uploadPath: input.uploadPath,
3268
+ bucketId: input.bucketId
3269
+ })
3270
+ ];
3271
+ case 1:
3272
+ fileText = _state.sent();
3273
+ operations = parseOperations(fileText, input.format, maxOperations);
3274
+ // Pre-flight: validate + authorize every operation before any dispatch. dispatch() bypasses the
3275
+ // tools/list visibility filter, so an unauthorized operation must never reach it.
3276
+ preflightErrors = collectPreflightErrors(operations, deps.authorizeOperation);
3277
+ if (preflightErrors.length > 0) {
3278
+ throw new Error("batch-execute: ".concat(preflightErrors.length, " of ").concat(operations.length, " operation(s) failed pre-flight; nothing was executed. ").concat(describePreflightErrors(preflightErrors)));
3279
+ }
3280
+ return [
3281
+ 4,
3282
+ executeOperations({
3283
+ operations: operations,
3284
+ input: input,
3285
+ ctx: ctx,
3286
+ dispatch: deps.dispatch
3287
+ })
3288
+ ];
3289
+ case 2:
3290
+ execution = _state.sent();
3291
+ failureCount = execution.errors.length;
3292
+ successCount = execution.succeededCount;
3293
+ skippedCount = operations.length - successCount - failureCount;
3294
+ return [
3295
+ 4,
3296
+ maybeDeleteUpload({
3297
+ storageService: deps.storageService,
3298
+ input: input,
3299
+ failureCount: failureCount
3300
+ })
3301
+ ];
3302
+ case 3:
3303
+ uploadDeleted = _state.sent();
3304
+ summary = {
3305
+ total: operations.length,
3306
+ successCount: successCount,
3307
+ failureCount: failureCount,
3308
+ skippedCount: skippedCount,
3309
+ errors: execution.errors,
3310
+ uploadDeleted: uploadDeleted
3311
+ };
3312
+ result = {
3313
+ content: [
3314
+ {
3315
+ type: 'text',
3316
+ text: JSON.stringify(summary)
3317
+ }
3318
+ ],
3319
+ structuredContent: summary
3320
+ };
3321
+ return [
3322
+ 3,
3323
+ 5
3324
+ ];
3325
+ case 4:
3326
+ error = _state.sent();
3327
+ result = formatMcpToolErrorResponse(error);
3328
+ return [
3329
+ 3,
3330
+ 5
3331
+ ];
3332
+ case 5:
3333
+ return [
3334
+ 2,
3335
+ result
3336
+ ];
3337
+ }
3338
+ });
3339
+ })();
3340
+ }
3341
+ // MARK: Input parsing
3342
+ function parseBatchExecuteInput(args) {
3343
+ var _args_format, _args_maxParallel;
3344
+ var uploadPath = args.uploadPath;
3345
+ if (typeof uploadPath !== 'string' || uploadPath.length === 0) {
3346
+ throw new Error('batch-execute: "uploadPath" is required and must be a non-empty string.');
3347
+ }
3348
+ var bucketId = args.bucketId;
3349
+ if (bucketId != null && (typeof bucketId !== 'string' || bucketId.length === 0)) {
3350
+ throw new Error('batch-execute: "bucketId" must be a non-empty string when provided.');
3351
+ }
3352
+ var format = (_args_format = args.format) !== null && _args_format !== void 0 ? _args_format : 'ndjson';
3353
+ if (format !== 'json' && format !== 'ndjson') {
3354
+ throw new Error('batch-execute: "format" must be "json" or "ndjson".');
3355
+ }
3356
+ var maxParallel = (_args_maxParallel = args.maxParallel) !== null && _args_maxParallel !== void 0 ? _args_maxParallel : DEFAULT_BATCH_EXECUTE_MAX_PARALLEL;
3357
+ if (typeof maxParallel !== 'number' || !Number.isInteger(maxParallel) || maxParallel < 1) {
3358
+ throw new Error('batch-execute: "maxParallel" must be a positive integer.');
3359
+ }
3360
+ return {
3361
+ uploadPath: uploadPath,
3362
+ bucketId: bucketId !== null && bucketId !== void 0 ? bucketId : undefined,
3363
+ format: format,
3364
+ maxParallel: maxParallel,
3365
+ stopOnError: args.stopOnError === true,
3366
+ deleteUploadOnSuccess: args.deleteUploadOnSuccess !== false
3367
+ };
3368
+ }
3369
+ function readOperationsFile(input) {
3370
+ return _async_to_generator$3(function() {
3371
+ var file, exists, bytes;
3372
+ return _ts_generator$3(this, function(_state) {
3373
+ switch(_state.label){
3374
+ case 0:
3375
+ file = input.storageService.file(toStoragePathInput(input.uploadPath, input.bucketId));
3376
+ return [
3377
+ 4,
3378
+ file.exists()
3379
+ ];
3380
+ case 1:
3381
+ exists = _state.sent();
3382
+ if (!exists) {
3383
+ throw new Error('batch-execute: operations file not found at "'.concat(input.uploadPath, '".'));
3384
+ }
3385
+ return [
3386
+ 4,
3387
+ file.getBytes(MAX_BATCH_EXECUTE_FILE_BYTES)
3388
+ ];
3389
+ case 2:
3390
+ bytes = _state.sent();
3391
+ return [
3392
+ 2,
3393
+ Buffer.from(bytes).toString('utf8')
3394
+ ];
3395
+ }
3396
+ });
3397
+ })();
3398
+ }
3399
+ // MARK: Operation parsing
3400
+ function parseOperations(fileText, format, maxOperations) {
3401
+ var rawOperations = format === 'ndjson' ? parseNdjsonOperations(fileText) : parseJsonArrayOperations(fileText);
3402
+ if (rawOperations.length === 0) {
3403
+ throw new Error('batch-execute: the operations file contained no operations.');
3404
+ }
3405
+ if (rawOperations.length > maxOperations) {
3406
+ throw new Error("batch-execute: ".concat(rawOperations.length, " operations exceed the limit of ").concat(maxOperations, "."));
3407
+ }
3408
+ return rawOperations.map(function(value, index) {
3409
+ return validateOperation(value, index);
3410
+ });
3411
+ }
3412
+ function parseNdjsonOperations(fileText) {
3413
+ var operations = [];
3414
+ fileText.split('\n').forEach(function(line, lineIndex) {
3415
+ var trimmed = line.trim();
3416
+ if (trimmed.length > 0) {
3417
+ try {
3418
+ operations.push(JSON.parse(trimmed));
3419
+ } catch (error) {
3420
+ throw new Error("batch-execute: invalid JSON on line ".concat(lineIndex + 1, ": ").concat(error.message), {
3421
+ cause: error
3422
+ });
3423
+ }
3424
+ }
3425
+ });
3426
+ return operations;
3427
+ }
3428
+ function parseJsonArrayOperations(fileText) {
3429
+ var parsed;
3430
+ try {
3431
+ parsed = JSON.parse(fileText);
3432
+ } catch (error) {
3433
+ throw new Error("batch-execute: file is not valid JSON: ".concat(error.message), {
3434
+ cause: error
3435
+ });
3436
+ }
3437
+ if (!Array.isArray(parsed)) {
3438
+ throw new TypeError('batch-execute: with format "json" the file must contain a top-level array of operations.');
3439
+ }
3440
+ return parsed;
3441
+ }
3442
+ function validateOperation(value, index) {
3443
+ if (value == null || (typeof value === "undefined" ? "undefined" : _type_of$1(value)) !== 'object') {
3444
+ throw new Error("batch-execute: operation[".concat(index, "] must be an object."));
3445
+ }
3446
+ var candidate = value;
3447
+ var modelType = candidate.modelType;
3448
+ var call = candidate.call;
3449
+ var specifier = candidate.specifier;
3450
+ if (typeof modelType !== 'string' || modelType.length === 0) {
3451
+ throw new Error("batch-execute: operation[".concat(index, '] is missing a non-empty "modelType".'));
3452
+ }
3453
+ if (typeof call !== 'string' || call.length === 0) {
3454
+ throw new Error("batch-execute: operation[".concat(index, '] is missing a non-empty "call".'));
3455
+ }
3456
+ if (specifier != null && typeof specifier !== 'string') {
3457
+ throw new Error("batch-execute: operation[".concat(index, '] "specifier" must be a string when provided.'));
3458
+ }
3459
+ return {
3460
+ call: call,
3461
+ modelType: modelType,
3462
+ specifier: specifier !== null && specifier !== void 0 ? specifier : undefined,
3463
+ data: candidate.data
3464
+ };
3465
+ }
3466
+ function collectPreflightErrors(operations, authorizeOperation) {
3467
+ var errors = [];
3468
+ operations.forEach(function(operation, index) {
3469
+ var authorization = authorizeOperation(operation);
3470
+ if (!authorization.allowed) {
3471
+ var _operation_call;
3472
+ errors.push({
3473
+ index: index,
3474
+ modelType: operation.modelType,
3475
+ call: (_operation_call = operation.call) !== null && _operation_call !== void 0 ? _operation_call : undefined,
3476
+ specifier: operation.specifier,
3477
+ reason: authorization.reason
3478
+ });
3479
+ }
3480
+ });
3481
+ return errors;
3482
+ }
3483
+ function describePreflightErrors(errors) {
3484
+ var sample = errors.slice(0, 5).map(function(error) {
3485
+ var _error_call;
3486
+ var specifierSuffix = error.specifier ? "/".concat(error.specifier) : '';
3487
+ return "[".concat(error.index, "] ").concat((_error_call = error.call) !== null && _error_call !== void 0 ? _error_call : '?', "/").concat(error.modelType).concat(specifierSuffix, ": ").concat(error.reason);
3488
+ }).join('; ');
3489
+ var suffix = errors.length > 5 ? " (+".concat(errors.length - 5, " more)") : '';
3490
+ return "".concat(sample).concat(suffix);
3491
+ }
3492
+ function executeOperations(input) {
3493
+ return _async_to_generator$3(function() {
3494
+ return _ts_generator$3(this, function(_state) {
3495
+ return [
3496
+ 2,
3497
+ input.input.stopOnError ? executeSequentialStopOnError(input) : executeBestEffort(input)
3498
+ ];
3499
+ });
3500
+ })();
3501
+ }
3502
+ function executeBestEffort(input) {
3503
+ return _async_to_generator$3(function() {
3504
+ var operations, ctx, dispatch, indices, taskResult, errors;
3505
+ return _ts_generator$3(this, function(_state) {
3506
+ switch(_state.label){
3507
+ case 0:
3508
+ operations = input.operations, ctx = input.ctx, dispatch = input.dispatch;
3509
+ indices = operations.map(function(_, index) {
3510
+ return index;
3511
+ });
3512
+ return [
3513
+ 4,
3514
+ performAsyncTasks(indices, function(index) {
3515
+ return _async_to_generator$3(function() {
3516
+ var entry, error;
3517
+ return _ts_generator$3(this, function(_state) {
3518
+ switch(_state.label){
3519
+ case 0:
3520
+ _state.trys.push([
3521
+ 0,
3522
+ 2,
3523
+ ,
3524
+ 3
3525
+ ]);
3526
+ return [
3527
+ 4,
3528
+ dispatch(operations[index], ctx.auth, ctx.rawRequest)
3529
+ ];
3530
+ case 1:
3531
+ _state.sent();
3532
+ return [
3533
+ 3,
3534
+ 3
3535
+ ];
3536
+ case 2:
3537
+ error = _state.sent();
3538
+ entry = toErrorEntry(operations[index], index, error);
3539
+ return [
3540
+ 3,
3541
+ 3
3542
+ ];
3543
+ case 3:
3544
+ return [
3545
+ 2,
3546
+ entry
3547
+ ];
3548
+ }
3549
+ });
3550
+ })();
3551
+ }, {
3552
+ throwError: false,
3553
+ maxParallelTasks: input.input.maxParallel
3554
+ })
3555
+ ];
3556
+ case 1:
3557
+ taskResult = _state.sent();
3558
+ errors = taskResult.results.map(function(param) {
3559
+ var _param = _sliced_to_array$1(param, 2), entry = _param[1];
3560
+ return entry;
3561
+ }).filter(function(entry) {
3562
+ return entry != null;
3563
+ }).sort(function(a, b) {
3564
+ return a.index - b.index;
3565
+ });
3566
+ return [
3567
+ 2,
3568
+ {
3569
+ succeededCount: operations.length - errors.length,
3570
+ errors: errors
3571
+ }
3572
+ ];
3573
+ }
3574
+ });
3575
+ })();
3576
+ }
3577
+ function executeSequentialStopOnError(input) {
3578
+ return _async_to_generator$3(function() {
3579
+ var operations, ctx, dispatch, errors, succeededCount, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, index, operation, error, err;
3580
+ return _ts_generator$3(this, function(_state) {
3581
+ switch(_state.label){
3582
+ case 0:
3583
+ operations = input.operations, ctx = input.ctx, dispatch = input.dispatch;
3584
+ errors = [];
3585
+ succeededCount = 0;
3586
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3587
+ _state.label = 1;
3588
+ case 1:
3589
+ _state.trys.push([
3590
+ 1,
3591
+ 8,
3592
+ 9,
3593
+ 10
3594
+ ]);
3595
+ _iterator = operations.entries()[Symbol.iterator]();
3596
+ _state.label = 2;
3597
+ case 2:
3598
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
3599
+ 3,
3600
+ 7
3601
+ ];
3602
+ _step_value = _sliced_to_array$1(_step.value, 2), index = _step_value[0], operation = _step_value[1];
3603
+ _state.label = 3;
3604
+ case 3:
3605
+ _state.trys.push([
3606
+ 3,
3607
+ 5,
3608
+ ,
3609
+ 6
3610
+ ]);
3611
+ return [
3612
+ 4,
3613
+ dispatch(operation, ctx.auth, ctx.rawRequest)
3614
+ ];
3615
+ case 4:
3616
+ _state.sent();
3617
+ succeededCount += 1;
3618
+ return [
3619
+ 3,
3620
+ 6
3621
+ ];
3622
+ case 5:
3623
+ error = _state.sent();
3624
+ errors.push(toErrorEntry(operation, index, error));
3625
+ return [
3626
+ 3,
3627
+ 7
3628
+ ];
3629
+ case 6:
3630
+ _iteratorNormalCompletion = true;
3631
+ return [
3632
+ 3,
3633
+ 2
3634
+ ];
3635
+ case 7:
3636
+ return [
3637
+ 3,
3638
+ 10
3639
+ ];
3640
+ case 8:
3641
+ err = _state.sent();
3642
+ _didIteratorError = true;
3643
+ _iteratorError = err;
3644
+ return [
3645
+ 3,
3646
+ 10
3647
+ ];
3648
+ case 9:
3649
+ try {
3650
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3651
+ _iterator.return();
3652
+ }
3653
+ } finally{
3654
+ if (_didIteratorError) {
3655
+ throw _iteratorError;
3656
+ }
3657
+ }
3658
+ return [
3659
+ 7
3660
+ ];
3661
+ case 10:
3662
+ return [
3663
+ 2,
3664
+ {
3665
+ succeededCount: succeededCount,
3666
+ errors: errors
3667
+ }
3668
+ ];
3669
+ }
3670
+ });
3671
+ })();
3672
+ }
3673
+ function toErrorEntry(operation, index, error) {
3674
+ var _operation_call;
3675
+ return {
3676
+ index: index,
3677
+ modelType: operation.modelType,
3678
+ call: (_operation_call = operation.call) !== null && _operation_call !== void 0 ? _operation_call : undefined,
3679
+ specifier: operation.specifier,
3680
+ message: _instanceof(error, Error) ? error.message : String(error)
3681
+ };
3682
+ }
3683
+ function maybeDeleteUpload(input) {
3684
+ return _async_to_generator$3(function() {
3685
+ var deleted, file;
3686
+ return _ts_generator$3(this, function(_state) {
3687
+ switch(_state.label){
3688
+ case 0:
3689
+ deleted = false;
3690
+ if (!(input.input.deleteUploadOnSuccess && input.failureCount === 0)) return [
3691
+ 3,
3692
+ 2
3693
+ ];
3694
+ file = input.storageService.file(toStoragePathInput(input.input.uploadPath, input.input.bucketId));
3695
+ return [
3696
+ 4,
3697
+ file.delete()
3698
+ ];
3699
+ case 1:
3700
+ _state.sent();
3701
+ deleted = true;
3702
+ _state.label = 2;
3703
+ case 2:
3704
+ return [
3705
+ 2,
3706
+ deleted
3707
+ ];
3708
+ }
3709
+ });
3710
+ })();
3711
+ }
3712
+ /**
3713
+ * Builds a {@link StoragePathInput} from a path + optional bucket. Omits `bucketId` entirely when
3714
+ * absent (rather than passing `undefined`) so the accessor falls back to the app default bucket.
3715
+ *
3716
+ * @param pathString - The slash path of the file within the bucket.
3717
+ * @param bucketId - The bucket id, or `undefined` for the default bucket.
3718
+ * @returns The resolved storage path input.
3719
+ */ function toStoragePathInput(pathString, bucketId) {
3720
+ return bucketId == null ? {
3721
+ pathString: pathString
3722
+ } : {
3723
+ bucketId: bucketId,
3724
+ pathString: pathString
3725
+ };
3726
+ }
3727
+ // MARK: Schemas
3728
+ var BATCH_EXECUTE_INPUT_SCHEMA = {
3729
+ type: 'object',
3730
+ required: [
3731
+ 'uploadPath'
3732
+ ],
3733
+ properties: {
3734
+ uploadPath: {
3735
+ type: 'string',
3736
+ minLength: 1,
3737
+ description: 'Storage path of the uploaded operations file (JSON array or NDJSON).'
3738
+ },
3739
+ bucketId: {
3740
+ type: 'string',
3741
+ minLength: 1,
3742
+ description: 'Storage bucket id. Defaults to the app default bucket when omitted.'
3743
+ },
3744
+ format: {
3745
+ type: 'string',
3746
+ enum: [
3747
+ 'json',
3748
+ 'ndjson'
3749
+ ],
3750
+ description: 'File format. "ndjson" (default) = one operation per line; "json" = a top-level array.'
3751
+ },
3752
+ maxParallel: {
3753
+ type: 'integer',
3754
+ minimum: 1,
3755
+ description: "Operations dispatched concurrently. Defaults to ".concat(DEFAULT_BATCH_EXECUTE_MAX_PARALLEL, ". Ignored (forced to sequential) when stopOnError is true.")
3756
+ },
3757
+ stopOnError: {
3758
+ type: 'boolean',
3759
+ description: 'Halt at the first runtime failure (runs sequentially). Defaults to false (best-effort; all operations attempted).'
3760
+ },
3761
+ deleteUploadOnSuccess: {
3762
+ type: 'boolean',
3763
+ description: 'Delete the uploaded file when every operation succeeds. Defaults to true. The file is always kept when any operation fails.'
3764
+ }
3765
+ },
3766
+ additionalProperties: false
3767
+ };
3768
+ var BATCH_EXECUTE_OUTPUT_SCHEMA = {
3769
+ type: 'object',
3770
+ required: [
3771
+ 'total',
3772
+ 'successCount',
3773
+ 'failureCount',
3774
+ 'skippedCount',
3775
+ 'errors',
3776
+ 'uploadDeleted'
3777
+ ],
3778
+ properties: {
3779
+ total: {
3780
+ type: 'integer',
3781
+ description: 'Total operations in the file.'
3782
+ },
3783
+ successCount: {
3784
+ type: 'integer',
3785
+ description: 'Operations that succeeded.'
3786
+ },
3787
+ failureCount: {
3788
+ type: 'integer',
3789
+ description: 'Operations that failed at runtime.'
3790
+ },
3791
+ skippedCount: {
3792
+ type: 'integer',
3793
+ description: 'Operations not attempted (only non-zero when stopOnError halted the run early).'
3794
+ },
3795
+ errors: {
3796
+ type: 'array',
3797
+ description: 'Per-operation runtime failures, keyed by original file index.',
3798
+ items: {
3799
+ type: 'object',
3800
+ required: [
3801
+ 'index',
3802
+ 'modelType',
3803
+ 'message'
3804
+ ],
3805
+ properties: {
3806
+ index: {
3807
+ type: 'integer'
3808
+ },
3809
+ modelType: {
3810
+ type: 'string'
3811
+ },
3812
+ call: {
3813
+ type: 'string'
3814
+ },
3815
+ specifier: {
3816
+ type: 'string'
3817
+ },
3818
+ message: {
3819
+ type: 'string'
3820
+ }
3821
+ }
3822
+ }
3823
+ },
3824
+ uploadDeleted: {
3825
+ type: 'boolean',
3826
+ description: 'Whether the uploaded operations file was deleted after the run.'
3827
+ }
3828
+ }
3829
+ };
3830
+
3831
+ function _array_like_to_array$2(arr, len) {
3832
+ if (len == null || len > arr.length) len = arr.length;
3833
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
3834
+ return arr2;
3835
+ }
3836
+ function _array_with_holes(arr) {
3837
+ if (Array.isArray(arr)) return arr;
3838
+ }
3839
+ function _array_without_holes$2(arr) {
3840
+ if (Array.isArray(arr)) return _array_like_to_array$2(arr);
3841
+ }
3842
+ function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
3843
+ try {
3844
+ var info = gen[key](arg);
3845
+ var value = info.value;
3846
+ } catch (error) {
3847
+ reject(error);
3848
+ return;
3849
+ }
3850
+ if (info.done) {
3851
+ resolve(value);
3852
+ } else {
3853
+ Promise.resolve(value).then(_next, _throw);
3854
+ }
3855
+ }
3856
+ function _async_to_generator$2(fn) {
3857
+ return function() {
3858
+ var self = this, args = arguments;
3859
+ return new Promise(function(resolve, reject) {
3860
+ var gen = fn.apply(self, args);
3861
+ function _next(value) {
3862
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value);
3863
+ }
3864
+ function _throw(err) {
3865
+ asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err);
3866
+ }
3867
+ _next(undefined);
3868
+ });
3869
+ };
3870
+ }
3871
+ function _class_call_check$3(instance, Constructor) {
3872
+ if (!(instance instanceof Constructor)) {
3873
+ throw new TypeError("Cannot call a class as a function");
3874
+ }
3875
+ }
3876
+ function _defineProperties$3(target, props) {
3877
+ for(var i = 0; i < props.length; i++){
3878
+ var descriptor = props[i];
3879
+ descriptor.enumerable = descriptor.enumerable || false;
3880
+ descriptor.configurable = true;
3881
+ if ("value" in descriptor) descriptor.writable = true;
3882
+ Object.defineProperty(target, descriptor.key, descriptor);
3883
+ }
3884
+ }
3885
+ function _create_class$3(Constructor, protoProps, staticProps) {
3886
+ if (protoProps) _defineProperties$3(Constructor.prototype, protoProps);
3887
+ return Constructor;
3888
+ }
3889
+ function _define_property$3(obj, key, value) {
3890
+ if (key in obj) {
3891
+ Object.defineProperty(obj, key, {
3892
+ value: value,
3893
+ enumerable: true,
3894
+ configurable: true,
3895
+ writable: true
3896
+ });
3897
+ } else {
3898
+ obj[key] = value;
3899
+ }
3900
+ return obj;
3901
+ }
3902
+ function _iterable_to_array$2(iter) {
3903
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
3904
+ }
3905
+ function _iterable_to_array_limit(arr, i) {
3906
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
3907
+ if (_i == null) return;
3908
+ var _arr = [];
3909
+ var _n = true;
3910
+ var _d = false;
3911
+ var _s, _e;
3912
+ try {
3913
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
3914
+ _arr.push(_s.value);
3915
+ if (i && _arr.length === i) break;
3916
+ }
3917
+ } catch (err) {
3918
+ _d = true;
3919
+ _e = err;
3920
+ } finally{
3921
+ try {
3922
+ if (!_n && _i["return"] != null) _i["return"]();
3923
+ } finally{
3924
+ if (_d) throw _e;
3925
+ }
3926
+ }
3927
+ return _arr;
3928
+ }
3929
+ function _non_iterable_rest() {
3930
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3931
+ }
3932
+ function _non_iterable_spread$2() {
3933
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3934
+ }
3935
+ function _sliced_to_array(arr, i) {
3936
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest();
3937
+ }
3938
+ function _to_consumable_array$2(arr) {
3939
+ return _array_without_holes$2(arr) || _iterable_to_array$2(arr) || _unsupported_iterable_to_array$2(arr) || _non_iterable_spread$2();
3940
+ }
3941
+ function _unsupported_iterable_to_array$2(o, minLen) {
3942
+ if (!o) return;
3943
+ if (typeof o === "string") return _array_like_to_array$2(o, minLen);
3944
+ var n = Object.prototype.toString.call(o).slice(8, -1);
3945
+ if (n === "Object" && o.constructor) n = o.constructor.name;
3946
+ if (n === "Map" || n === "Set") return Array.from(n);
3947
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$2(o, minLen);
3948
+ }
3949
+ function _ts_generator$2(thisArg, body) {
3950
+ var f, y, t, _ = {
3951
+ label: 0,
3952
+ sent: function() {
3953
+ if (t[0] & 1) throw t[1];
3954
+ return t[1];
3955
+ },
3956
+ trys: [],
3957
+ ops: []
3958
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
3959
+ return d(g, "next", {
3960
+ value: verb(0)
3961
+ }), d(g, "throw", {
3962
+ value: verb(1)
3963
+ }), d(g, "return", {
3964
+ value: verb(2)
3965
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
3966
+ value: function() {
3967
+ return this;
3968
+ }
3969
+ }), g;
3970
+ function verb(n) {
3971
+ return function(v) {
3972
+ return step([
3973
+ n,
3974
+ v
3975
+ ]);
3976
+ };
3977
+ }
3978
+ function step(op) {
3979
+ if (f) throw new TypeError("Generator is already executing.");
3980
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
3981
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
3982
+ if (y = 0, t) op = [
3983
+ op[0] & 2,
3984
+ t.value
3985
+ ];
3986
+ switch(op[0]){
3987
+ case 0:
3988
+ case 1:
3989
+ t = op;
3990
+ break;
3991
+ case 4:
3992
+ _.label++;
3993
+ return {
3994
+ value: op[1],
3995
+ done: false
3996
+ };
3997
+ case 5:
3998
+ _.label++;
3999
+ y = op[1];
4000
+ op = [
4001
+ 0
4002
+ ];
4003
+ continue;
4004
+ case 7:
4005
+ op = _.ops.pop();
4006
+ _.trys.pop();
4007
+ continue;
4008
+ default:
4009
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
4010
+ _ = 0;
4011
+ continue;
4012
+ }
4013
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
4014
+ _.label = op[1];
4015
+ break;
4016
+ }
4017
+ if (op[0] === 6 && _.label < t[1]) {
4018
+ _.label = t[1];
4019
+ t = op;
4020
+ break;
4021
+ }
4022
+ if (t && _.label < t[2]) {
4023
+ _.label = t[2];
4024
+ _.ops.push(op);
4025
+ break;
4026
+ }
4027
+ if (t[2]) _.ops.pop();
4028
+ _.trys.pop();
4029
+ continue;
4030
+ }
4031
+ op = body.call(thisArg, _);
4032
+ } catch (e) {
4033
+ op = [
4034
+ 6,
4035
+ e
4036
+ ];
4037
+ y = 0;
4038
+ } finally{
4039
+ f = t = 0;
4040
+ }
4041
+ if (op[0] & 5) throw op[1];
4042
+ return {
4043
+ value: op[0] ? op[1] : void 0,
4044
+ done: true
4045
+ };
4046
+ }
4047
+ }
4048
+ var McpServerFactoryService_1;
4049
+ /**
4050
+ * Injectable factory that builds {@link McpServer} instances pre-wired to the
4051
+ * call model dispatch chain.
4052
+ *
4053
+ * The factory is invoked per Streamable HTTP request — `@modelcontextprotocol/sdk`
4054
+ * recommends a fresh `McpServer` + transport pair per stateless JSON-RPC request,
4055
+ * which sidesteps session bookkeeping for the common Claude-connector case.
4056
+ */ var McpServerFactoryService = McpServerFactoryService_1 = /*#__PURE__*/ function() {
4057
+ function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader, analyticsService, storageService) {
4058
+ _class_call_check$3(this, McpServerFactoryService);
4059
+ _define_property$3(this, "mcpConfig", void 0);
4060
+ _define_property$3(this, "dispatchService", void 0);
4061
+ _define_property$3(this, "modelApiGetService", void 0);
4062
+ _define_property$3(this, "roleReader", void 0);
4063
+ _define_property$3(this, "storageService", void 0);
4064
+ _define_property$3(this, "_logger", new Logger(McpServerFactoryService_1.name));
4065
+ _define_property$3(this, "_cachedTools", void 0);
4066
+ _define_property$3(this, "_cachedStaticTools", void 0);
4067
+ _define_property$3(this, "_cachedManifest", void 0);
4068
+ _define_property$3(this, "_cachedManifestModels", void 0);
4069
+ _define_property$3(this, "_cachedManifestAuth", void 0);
4070
+ _define_property$3(this, "_manifestLoaded", false);
4071
+ _define_property$3(this, "_loggedSkips", false);
4072
+ _define_property$3(this, "_warnedMissingRoleReader", false);
4073
+ _define_property$3(this, "_analyticsService", void 0);
4074
+ this.mcpConfig = mcpConfig;
4075
+ this.dispatchService = dispatchService;
4076
+ this.modelApiGetService = modelApiGetService;
4077
+ this.roleReader = roleReader;
4078
+ this.storageService = storageService;
4079
+ this._analyticsService = analyticsService !== null && analyticsService !== void 0 ? analyticsService : noopMcpAnalyticsService();
4080
+ }
4081
+ _create_class$3(McpServerFactoryService, [
4082
+ {
4083
+ /**
4084
+ * Builds a configured MCP server with tool listing + dispatch handlers wired up.
4085
+ *
4086
+ * @param ctx - The per-request context (auth, raw request) used when forwarding tool calls.
4087
+ * @returns A configured MCP server ready to be `connect()`-ed to a transport.
4088
+ */ key: "createServer",
4089
+ value: function createServer(ctx) {
4090
+ var _this = this;
4091
+ var _this_mcpConfig_serverName, _this_mcpConfig_serverVersion, _this_mcpConfig_serverInstructions;
4092
+ var baseServerName = (_this_mcpConfig_serverName = this.mcpConfig.serverName) !== null && _this_mcpConfig_serverName !== void 0 ? _this_mcpConfig_serverName : DEFAULT_MCP_SERVER_NAME;
4093
+ var serverName = this.mcpConfig.readOnly === true ? "".concat(baseServerName, " (read-only)") : baseServerName;
4094
+ var server = new McpServer({
4095
+ name: serverName,
4096
+ version: (_this_mcpConfig_serverVersion = this.mcpConfig.serverVersion) !== null && _this_mcpConfig_serverVersion !== void 0 ? _this_mcpConfig_serverVersion : '0.0.0'
4097
+ }, {
4098
+ instructions: (_this_mcpConfig_serverInstructions = this.mcpConfig.serverInstructions) !== null && _this_mcpConfig_serverInstructions !== void 0 ? _this_mcpConfig_serverInstructions : DEFAULT_MCP_SERVER_INSTRUCTIONS
4099
+ });
4100
+ server.server.registerCapabilities({
4101
+ tools: {}
4102
+ });
4103
+ var toolGeneration = this._resolveToolDefinitions();
4104
+ var staticTools = this._resolveStaticTools();
4105
+ var scopes = this._resolveScopes(ctx);
4106
+ var authRoles = this._resolveAuthRoles(ctx);
4107
+ var combinedTools = _to_consumable_array$2(toolGeneration.tools).concat(_to_consumable_array$2(staticTools));
4108
+ var visibleTools = this._filterToolsForRequest(combinedTools, {
4109
+ ctx: ctx,
4110
+ scopes: scopes,
4111
+ authRoles: authRoles
4112
+ });
4113
+ var definitionsByName = new Map(visibleTools.map(function(tool) {
4114
+ return [
4115
+ tool.name,
4116
+ tool
4117
+ ];
4118
+ }));
4119
+ // The batch tool is request-scoped: it authorizes each batched operation against this caller's
4120
+ // resolved visible tool set, so it can't be cached like the other static tools.
4121
+ var batchTool = this._resolveBatchTool(ctx, definitionsByName);
4122
+ var listedTools = visibleTools;
4123
+ if (batchTool != null) {
4124
+ definitionsByName.set(batchTool.name, batchTool);
4125
+ listedTools = _to_consumable_array$2(visibleTools).concat([
4126
+ batchTool
4127
+ ]);
4128
+ }
4129
+ server.server.setRequestHandler(ListToolsRequestSchema, function() {
4130
+ return _async_to_generator$2(function() {
4131
+ var _this;
4132
+ return _ts_generator$2(this, function(_state) {
4133
+ _this = this;
4134
+ return [
4135
+ 2,
4136
+ {
4137
+ tools: listedTools.map(function(tool) {
4138
+ return _this._buildToolListEntry(tool, ctx, scopes);
4139
+ })
4140
+ }
4141
+ ];
4142
+ });
4143
+ }).call(_this);
4144
+ });
4145
+ server.server.setRequestHandler(CallToolRequestSchema, function(request) {
4146
+ return _async_to_generator$2(function() {
4147
+ return _ts_generator$2(this, function(_state) {
4148
+ return [
4149
+ 2,
4150
+ this._handleToolCall(request, definitionsByName, ctx)
4151
+ ];
4152
+ });
4153
+ }).call(_this);
4154
+ });
4155
+ return server;
4156
+ }
4157
+ },
4158
+ {
4159
+ /**
3291
4160
  * Reads cached tool definitions, regenerating + logging skips on first call.
3292
4161
  *
3293
4162
  * The underlying call model `_apiDetails` is built at boot and doesn't change at runtime,
@@ -3526,6 +4395,92 @@ var McpServerFactoryService_1;
3526
4395
  },
3527
4396
  {
3528
4397
  /**
4398
+ * Builds the per-request `batch-execute` tool, or `undefined` when it should not be offered.
4399
+ *
4400
+ * Unlike the cached static tools this is rebuilt per request, because it closes over the caller's
4401
+ * resolved visible tool set: each batched operation is authorized against exactly the callModel
4402
+ * tools this caller may invoke directly. Offered only when a storage service is wired (it reads
4403
+ * the uploaded operations file), the caller is authenticated, and the server is not in read-only
4404
+ * mode (the tool performs writes).
4405
+ *
4406
+ * @param ctx - The per-request context (auth, raw request) forwarded to dispatched operations.
4407
+ * @param definitionsByName - The caller's visible tool definitions, keyed by name.
4408
+ * @returns The batch tool definition, or `undefined` when unavailable for this request.
4409
+ */ key: "_resolveBatchTool",
4410
+ value: function _resolveBatchTool(ctx, definitionsByName) {
4411
+ var _this = this;
4412
+ var result;
4413
+ var storageService = this.storageService;
4414
+ if (storageService != null && ctx.auth != null && this.mcpConfig.readOnly !== true) {
4415
+ var authorizedCoords = new Set();
4416
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
4417
+ try {
4418
+ for(var _iterator = definitionsByName.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
4419
+ var definition = _step.value;
4420
+ // Only callModel tools are re-dispatchable; static tools (model-get, whoami) have synthetic
4421
+ // dispatch identities the callModel chain can't resolve.
4422
+ if (definition.staticHandler == null) {
4423
+ authorizedCoords.add(batchOperationCoordKey(definition.dispatch));
4424
+ }
4425
+ }
4426
+ } catch (err) {
4427
+ _didIteratorError = true;
4428
+ _iteratorError = err;
4429
+ } finally{
4430
+ try {
4431
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
4432
+ _iterator.return();
4433
+ }
4434
+ } finally{
4435
+ if (_didIteratorError) {
4436
+ throw _iteratorError;
4437
+ }
4438
+ }
4439
+ }
4440
+ result = createBatchExecuteTool({
4441
+ storageService: storageService,
4442
+ dispatch: function dispatch(operation, auth, rawRequest) {
4443
+ return _this.dispatchService.dispatch(operation, auth, rawRequest);
4444
+ },
4445
+ authorizeOperation: function authorizeOperation(operation) {
4446
+ return _this._authorizeBatchOperation(operation, authorizedCoords);
4447
+ }
4448
+ });
4449
+ }
4450
+ return result;
4451
+ }
4452
+ },
4453
+ {
4454
+ /**
4455
+ * Authorizes a single batched operation against the caller's visible callModel tool coordinates.
4456
+ *
4457
+ * Re-applies the same gate the `tools/list` filter already enforced: an operation is allowed only
4458
+ * when its `(call, modelType, specifier)` coordinate matches a tool this caller can see. This is
4459
+ * the critical guard — `dispatchService.dispatch` bypasses the MCP visibility filter, so without
4460
+ * this check a batch could reach scope-, role-, or read-only-gated handlers.
4461
+ *
4462
+ * @param operation - The operation to authorize.
4463
+ * @param authorizedCoords - The set of dispatchable coordinate keys visible to this caller.
4464
+ * @returns Whether the operation may be dispatched, with a reason when it may not.
4465
+ */ key: "_authorizeBatchOperation",
4466
+ value: function _authorizeBatchOperation(operation, authorizedCoords) {
4467
+ var _operation_call, _operation_specifier, _operation_call1;
4468
+ var coordKey = batchOperationCoordKey({
4469
+ call: (_operation_call = operation.call) !== null && _operation_call !== void 0 ? _operation_call : '',
4470
+ modelType: operation.modelType,
4471
+ specifier: (_operation_specifier = operation.specifier) !== null && _operation_specifier !== void 0 ? _operation_specifier : undefined
4472
+ });
4473
+ var specifierSuffix = operation.specifier ? ' specifier="'.concat(operation.specifier, '"') : '';
4474
+ return authorizedCoords.has(coordKey) ? {
4475
+ allowed: true
4476
+ } : {
4477
+ allowed: false,
4478
+ reason: 'no visible tool matches call="'.concat((_operation_call1 = operation.call) !== null && _operation_call1 !== void 0 ? _operation_call1 : '', '" modelType="').concat(operation.modelType, '"').concat(specifierSuffix, " (unknown, or hidden by scope/role/read-only).")
4479
+ };
4480
+ }
4481
+ },
4482
+ {
4483
+ /**
3529
4484
  * Reads the pre-rendered MCP manifest JSON once, validates its version, and caches the
3530
4485
  * resulting `key → entry` map plus the optional `models` catalog for the process lifetime.
3531
4486
  *
@@ -4017,7 +4972,9 @@ McpServerFactoryService = McpServerFactoryService_1 = __decorate([
4017
4972
  __param(3, Optional()),
4018
4973
  __param(3, Inject(MCP_AUTH_ROLE_READER)),
4019
4974
  __param(4, Optional()),
4020
- __param(4, Inject(MCP_ANALYTICS_SERVICE))
4975
+ __param(4, Inject(MCP_ANALYTICS_SERVICE)),
4976
+ __param(5, Optional()),
4977
+ __param(5, Inject(FirebaseServerStorageService))
4021
4978
  ], McpServerFactoryService);
4022
4979
 
4023
4980
  function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
@@ -4710,7 +5667,7 @@ var FirebaseServerMcpAnalyticsService_1;
4710
5667
  value: function handleMcpAnalyticsEvent(event) {
4711
5668
  if (this._logEvents) {
4712
5669
  var uidSuffix = event.uid ? " uid=".concat(event.uid) : '';
4713
- var durationSuffix = event.durationMs != null ? " (".concat(event.durationMs, "ms)") : '';
5670
+ var durationSuffix = event.durationMs == null ? '' : " (".concat(event.durationMs, "ms)");
4714
5671
  var outcome = event.isSuccessful ? 'Succeeded' : 'Failed';
4715
5672
  this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix));
4716
5673
  }
@@ -4809,4 +5766,4 @@ function _unsupported_iterable_to_array(o, minLen) {
4809
5766
  };
4810
5767
  }
4811
5768
 
4812
- export { DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS, DEFAULT_MCP_ANALYTICS_EVENT_NAME, DEFAULT_MCP_PATH, DEFAULT_MCP_SERVER_INSTRUCTIONS, DEFAULT_MCP_SERVER_NAME, DEFAULT_SPECIFIER_KEY, DEFAULT_VOID_MCP_SUCCESS_VALUE, FIREBASE_SERVER_MCP_ANALYTICS_CONFIG, FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerMcpAnalyticsService, MCP_ANALYTICS_SERVICE, MCP_AUTH_ROLE_READER, MCP_CALL_TYPE_ABBREVIATIONS, MCP_MANIFEST_VERSION, MCP_MODEL_GET_BATCH_SIZE, MCP_TOOL_NAME_MAX_LENGTH, MCP_TOOL_NAME_WARN_LENGTH, MODEL_DECODE_DISPATCH_CALL, MODEL_DECODE_DISPATCH_MODEL_TYPE, MODEL_DECODE_TOOL_NAME, MODEL_GET_DISPATCH_CALL, MODEL_GET_DISPATCH_MODEL_TYPE, MODEL_GET_TOOL_NAME, MODEL_INFO_DISPATCH_CALL, MODEL_INFO_DISPATCH_MODEL_TYPE, MODEL_INFO_GROUPS_HINT, MODEL_INFO_TOOL_NAME, MODEL_INFO_UNGROUPED_LABEL, McpAnalyticsService, McpController, McpModuleConfig, McpServerFactoryService, McpWellKnownController, abbreviateMcpCallType, appMcpAnalyticsModuleMetadata, buildDefaultMcpToolDescription, buildDisambiguatedMcpToolName, buildMcpToolName, buildStaticWireEntry, classifyVisibility, createModelDecodeTool, createModelGetTool, createModelInfoTool, decodeFirestoreModelKey, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, mcpManifestKey, mcpModuleMetadata, noopMcpAnalyticsService, resolveEffectiveReadOnly, resolveRequiredScope, validateMcpToolName };
5769
+ export { BATCH_EXECUTE_DISPATCH_CALL, BATCH_EXECUTE_DISPATCH_MODEL_TYPE, BATCH_EXECUTE_TOOL_NAME, DEFAULT_BATCH_EXECUTE_MAX_PARALLEL, DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS, DEFAULT_MCP_ANALYTICS_EVENT_NAME, DEFAULT_MCP_PATH, DEFAULT_MCP_SERVER_INSTRUCTIONS, DEFAULT_MCP_SERVER_NAME, DEFAULT_SPECIFIER_KEY, DEFAULT_VOID_MCP_SUCCESS_VALUE, FIREBASE_SERVER_MCP_ANALYTICS_CONFIG, FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerMcpAnalyticsService, MAX_BATCH_EXECUTE_FILE_BYTES, MAX_BATCH_EXECUTE_OPERATIONS, MCP_ANALYTICS_SERVICE, MCP_AUTH_ROLE_READER, MCP_CALL_TYPE_ABBREVIATIONS, MCP_MANIFEST_VERSION, MCP_MODEL_GET_BATCH_SIZE, MCP_TOOL_NAME_MAX_LENGTH, MCP_TOOL_NAME_WARN_LENGTH, MODEL_DECODE_DISPATCH_CALL, MODEL_DECODE_DISPATCH_MODEL_TYPE, MODEL_DECODE_TOOL_NAME, MODEL_GET_DISPATCH_CALL, MODEL_GET_DISPATCH_MODEL_TYPE, MODEL_GET_TOOL_NAME, MODEL_INFO_DISPATCH_CALL, MODEL_INFO_DISPATCH_MODEL_TYPE, MODEL_INFO_GROUPS_HINT, MODEL_INFO_TOOL_NAME, MODEL_INFO_UNGROUPED_LABEL, McpAnalyticsService, McpController, McpModuleConfig, McpServerFactoryService, McpWellKnownController, abbreviateMcpCallType, appMcpAnalyticsModuleMetadata, batchOperationCoordKey, buildDefaultMcpToolDescription, buildDisambiguatedMcpToolName, buildMcpToolName, buildStaticWireEntry, classifyVisibility, createBatchExecuteTool, createModelDecodeTool, createModelGetTool, createModelInfoTool, decodeFirestoreModelKey, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, mcpManifestKey, mcpModuleMetadata, noopMcpAnalyticsService, resolveEffectiveReadOnly, resolveRequiredScope, validateMcpToolName };