@dereekb/dbx-cli 13.11.6 → 13.11.8

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/index.cjs.js CHANGED
@@ -11,13 +11,13 @@ var node_readline = require('node:readline');
11
11
  var yargs = require('yargs');
12
12
  var helpers = require('yargs/helpers');
13
13
 
14
- function _array_like_to_array$7(arr, len) {
14
+ function _array_like_to_array$8(arr, len) {
15
15
  if (len == null || len > arr.length) len = arr.length;
16
16
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
17
17
  return arr2;
18
18
  }
19
- function _array_without_holes$4(arr) {
20
- if (Array.isArray(arr)) return _array_like_to_array$7(arr);
19
+ function _array_without_holes$5(arr) {
20
+ if (Array.isArray(arr)) return _array_like_to_array$8(arr);
21
21
  }
22
22
  function _assert_this_initialized(self) {
23
23
  if (self === void 0) {
@@ -94,10 +94,10 @@ function _instanceof$6(left, right) {
94
94
  function _is_native_function(fn) {
95
95
  return Function.toString.call(fn).indexOf("[native code]") !== -1;
96
96
  }
97
- function _iterable_to_array$4(iter) {
97
+ function _iterable_to_array$5(iter) {
98
98
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
99
99
  }
100
- function _non_iterable_spread$4() {
100
+ function _non_iterable_spread$5() {
101
101
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
102
102
  }
103
103
  function _object_spread$c(target) {
@@ -128,20 +128,20 @@ function _set_prototype_of(o, p) {
128
128
  };
129
129
  return _set_prototype_of(o, p);
130
130
  }
131
- function _to_consumable_array$4(arr) {
132
- return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$7(arr) || _non_iterable_spread$4();
131
+ function _to_consumable_array$5(arr) {
132
+ return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$8(arr) || _non_iterable_spread$5();
133
133
  }
134
134
  function _type_of$3(obj) {
135
135
  "@swc/helpers - typeof";
136
136
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
137
137
  }
138
- function _unsupported_iterable_to_array$7(o, minLen) {
138
+ function _unsupported_iterable_to_array$8(o, minLen) {
139
139
  if (!o) return;
140
- if (typeof o === "string") return _array_like_to_array$7(o, minLen);
140
+ if (typeof o === "string") return _array_like_to_array$8(o, minLen);
141
141
  var n = Object.prototype.toString.call(o).slice(8, -1);
142
142
  if (n === "Object" && o.constructor) n = o.constructor.name;
143
143
  if (n === "Map" || n === "Set") return Array.from(n);
144
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$7(o, minLen);
144
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$8(o, minLen);
145
145
  }
146
146
  function _wrap_native_super(Class) {
147
147
  var _cache = typeof Map === "function" ? new Map() : undefined;
@@ -190,7 +190,7 @@ function _is_native_reflect_construct() {
190
190
  /id_token[=:]\s*\S+/gi
191
191
  ];
192
192
  var _outputOptions = {};
193
- var _secretPatterns = _to_consumable_array$4(DEFAULT_CLI_SECRET_PATTERNS);
193
+ var _secretPatterns = _to_consumable_array$5(DEFAULT_CLI_SECRET_PATTERNS);
194
194
  var _errorMapper;
195
195
  /**
196
196
  * Configures output options from parsed CLI arguments.
@@ -443,7 +443,7 @@ function pickFromObject(obj, fields) {
443
443
  };
444
444
  }
445
445
 
446
- function asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, key, arg) {
446
+ function asyncGeneratorStep$h(gen, resolve, reject, _next, _throw, key, arg) {
447
447
  try {
448
448
  var info = gen[key](arg);
449
449
  var value = info.value;
@@ -457,16 +457,16 @@ function asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, key, arg) {
457
457
  Promise.resolve(value).then(_next, _throw);
458
458
  }
459
459
  }
460
- function _async_to_generator$f(fn) {
460
+ function _async_to_generator$h(fn) {
461
461
  return function() {
462
462
  var self = this, args = arguments;
463
463
  return new Promise(function(resolve, reject) {
464
464
  var gen = fn.apply(self, args);
465
465
  function _next(value) {
466
- asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, "next", value);
466
+ asyncGeneratorStep$h(gen, resolve, reject, _next, _throw, "next", value);
467
467
  }
468
468
  function _throw(err) {
469
- asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, "throw", err);
469
+ asyncGeneratorStep$h(gen, resolve, reject, _next, _throw, "throw", err);
470
470
  }
471
471
  _next(undefined);
472
472
  });
@@ -476,7 +476,7 @@ function _type_of$2(obj) {
476
476
  "@swc/helpers - typeof";
477
477
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
478
478
  }
479
- function _ts_generator$f(thisArg, body) {
479
+ function _ts_generator$h(thisArg, body) {
480
480
  var f, y, t, _ = {
481
481
  label: 0,
482
482
  sent: function() {
@@ -576,6 +576,7 @@ function _ts_generator$f(thisArg, body) {
576
576
  }
577
577
  }
578
578
  var CALL_MODEL_API_PATH = "/model/call";
579
+ var MAX_MODEL_ACCESS_MULTI_READ_KEYS = 50;
579
580
  /**
580
581
  * Posts a typed model call to `<apiBaseUrl>/model/call` with a Bearer access token and parses the JSON response.
581
582
  *
@@ -591,9 +592,9 @@ var CALL_MODEL_API_PATH = "/model/call";
591
592
  * @param input.fetcher - Optional fetch implementation override (used by tests).
592
593
  * @returns The parsed JSON response body cast to `R`.
593
594
  */ function callModelOverHttp(input) {
594
- return _async_to_generator$f(function() {
595
+ return _async_to_generator$h(function() {
595
596
  var _input_fetcher, fetcher, url, res, text, body, _input_params_call, bodyMessage, messageString, message;
596
- return _ts_generator$f(this, function(_state) {
597
+ return _ts_generator$h(this, function(_state) {
597
598
  switch(_state.label){
598
599
  case 0:
599
600
  fetcher = (_input_fetcher = input.fetcher) !== null && _input_fetcher !== void 0 ? _input_fetcher : fetch;
@@ -643,6 +644,163 @@ var CALL_MODEL_API_PATH = "/model/call";
643
644
  });
644
645
  })();
645
646
  }
647
+ /**
648
+ * GETs a single Firestore document by key via the typed model-access endpoint.
649
+ *
650
+ * Calls `<apiBaseUrl>/model/<modelType>/get?key=<encoded key>` with a Bearer access token and
651
+ * returns the parsed `{ key, data }` envelope. Non-2xx responses are mapped to a {@link CliError}
652
+ * with a stable code derived from the status — matching {@link callModelOverHttp}'s error shape.
653
+ *
654
+ * The backend route is implemented by `ModelApiController.getOne` (packages/firebase-server) and
655
+ * enforces `roles: 'read'` via `useModel(...)` so Firestore security rules still apply.
656
+ *
657
+ * @param input - The request envelope describing the API target, access token, model + key, and optional fetch override.
658
+ * @returns The parsed `{ key, data }` envelope.
659
+ */ function getModelOverHttp(input) {
660
+ return _async_to_generator$h(function() {
661
+ var _input_fetcher, fetcher, url, res, _ref, ok, body, fallbackMessage;
662
+ return _ts_generator$h(this, function(_state) {
663
+ switch(_state.label){
664
+ case 0:
665
+ fetcher = (_input_fetcher = input.fetcher) !== null && _input_fetcher !== void 0 ? _input_fetcher : fetch;
666
+ url = "".concat(trimSlash$1(input.apiBaseUrl), "/model/").concat(encodeURIComponent(input.modelType), "/get?key=").concat(encodeURIComponent(input.key));
667
+ return [
668
+ 4,
669
+ fetcher(url, {
670
+ method: 'GET',
671
+ headers: {
672
+ Accept: 'application/json',
673
+ Authorization: "Bearer ".concat(input.accessToken)
674
+ }
675
+ })
676
+ ];
677
+ case 1:
678
+ res = _state.sent();
679
+ return [
680
+ 4,
681
+ readJsonResponse(res)
682
+ ];
683
+ case 2:
684
+ _ref = _state.sent(), ok = _ref.ok, body = _ref.body, fallbackMessage = _ref.fallbackMessage;
685
+ if (!ok) {
686
+ throw new CliError({
687
+ message: "get ".concat(input.modelType, "/").concat(input.key, " failed: ").concat(extractMessage(body, fallbackMessage, res)),
688
+ code: codeForStatus(res.status),
689
+ suggestion: res.status === 401 || res.status === 403 ? 'Run `<cli> auth login` to refresh credentials.' : undefined
690
+ });
691
+ }
692
+ return [
693
+ 2,
694
+ body
695
+ ];
696
+ }
697
+ });
698
+ })();
699
+ }
700
+ /**
701
+ * Batch-reads up to {@link MAX_MODEL_ACCESS_MULTI_READ_KEYS} Firestore documents in a single request.
702
+ *
703
+ * Calls `POST <apiBaseUrl>/model/<modelType>/get` with body `{ keys }` and returns the
704
+ * `{ results, errors }` envelope. The 50-key cap is enforced client-side so the error surfaces
705
+ * with a clear `INVALID_ARGUMENT` code before the request is made.
706
+ *
707
+ * Backend route: `ModelApiController.getMany` (packages/firebase-server). Same `'read'` role enforcement.
708
+ *
709
+ * @param input - The request envelope describing the API target, access token, model, keys, and optional fetch override.
710
+ * @returns The parsed `{ results, errors }` envelope.
711
+ */ function getMultipleModelsOverHttp(input) {
712
+ return _async_to_generator$h(function() {
713
+ var _input_fetcher, fetcher, url, res, _ref, ok, body, fallbackMessage;
714
+ return _ts_generator$h(this, function(_state) {
715
+ switch(_state.label){
716
+ case 0:
717
+ if (input.keys.length === 0) {
718
+ throw new CliError({
719
+ message: 'get-many requires at least one key.',
720
+ code: 'INVALID_ARGUMENT'
721
+ });
722
+ }
723
+ if (input.keys.length > MAX_MODEL_ACCESS_MULTI_READ_KEYS) {
724
+ throw new CliError({
725
+ message: "get-many supports at most ".concat(MAX_MODEL_ACCESS_MULTI_READ_KEYS, " keys (got ").concat(input.keys.length, ")."),
726
+ code: 'INVALID_ARGUMENT'
727
+ });
728
+ }
729
+ fetcher = (_input_fetcher = input.fetcher) !== null && _input_fetcher !== void 0 ? _input_fetcher : fetch;
730
+ url = "".concat(trimSlash$1(input.apiBaseUrl), "/model/").concat(encodeURIComponent(input.modelType), "/get");
731
+ return [
732
+ 4,
733
+ fetcher(url, {
734
+ method: 'POST',
735
+ headers: {
736
+ 'Content-Type': 'application/json',
737
+ Accept: 'application/json',
738
+ Authorization: "Bearer ".concat(input.accessToken)
739
+ },
740
+ body: JSON.stringify({
741
+ keys: input.keys
742
+ })
743
+ })
744
+ ];
745
+ case 1:
746
+ res = _state.sent();
747
+ return [
748
+ 4,
749
+ readJsonResponse(res)
750
+ ];
751
+ case 2:
752
+ _ref = _state.sent(), ok = _ref.ok, body = _ref.body, fallbackMessage = _ref.fallbackMessage;
753
+ if (!ok) {
754
+ throw new CliError({
755
+ message: "get-many ".concat(input.modelType, " failed: ").concat(extractMessage(body, fallbackMessage, res)),
756
+ code: codeForStatus(res.status),
757
+ suggestion: res.status === 401 || res.status === 403 ? 'Run `<cli> auth login` to refresh credentials.' : undefined
758
+ });
759
+ }
760
+ return [
761
+ 2,
762
+ body
763
+ ];
764
+ }
765
+ });
766
+ })();
767
+ }
768
+ function readJsonResponse(res) {
769
+ return _async_to_generator$h(function() {
770
+ var text, body;
771
+ return _ts_generator$h(this, function(_state) {
772
+ switch(_state.label){
773
+ case 0:
774
+ return [
775
+ 4,
776
+ res.text()
777
+ ];
778
+ case 1:
779
+ text = _state.sent();
780
+ if (text.length > 0) {
781
+ try {
782
+ body = JSON.parse(text);
783
+ } catch (unused) {
784
+ body = text;
785
+ }
786
+ }
787
+ return [
788
+ 2,
789
+ {
790
+ ok: res.ok,
791
+ body: body,
792
+ fallbackMessage: text
793
+ }
794
+ ];
795
+ }
796
+ });
797
+ })();
798
+ }
799
+ function extractMessage(body, fallback, res) {
800
+ var bodyMessage = (typeof body === "undefined" ? "undefined" : _type_of$2(body)) === 'object' && body && 'message' in body ? body.message : undefined;
801
+ var messageString = typeof bodyMessage === 'string' ? bodyMessage : undefined;
802
+ return messageString !== null && messageString !== void 0 ? messageString : fallback || "".concat(res.status, " ").concat(res.statusText);
803
+ }
646
804
  function codeForStatus(status) {
647
805
  if (status === 401) return 'AUTH_UNAUTHORIZED';
648
806
  if (status === 403) return 'AUTH_FORBIDDEN';
@@ -710,33 +868,53 @@ var getCliContext = _cliContextSlot.get;
710
868
  /**
711
869
  * Builds a {@link CliContext} for the current invocation.
712
870
  *
713
- * Bundles the env config and access token alongside a `callModel` helper that POSTs to
714
- * `<env.apiBaseUrl>/model/call` with the cached Bearer token.
871
+ * Bundles the env config and access token alongside helpers that POST/GET against
872
+ * `<env.apiBaseUrl>/model/*` with the cached Bearer token.
715
873
  *
716
874
  * @param input - The context inputs.
717
875
  * @param input.cliName - The CLI's binary name.
718
876
  * @param input.envName - The active env name.
719
877
  * @param input.env - The resolved {@link CliEnvConfig} for the active env.
720
878
  * @param input.accessToken - The Bearer access token to include on outgoing API calls.
879
+ * @param input.modelManifest - Optional generated {@link CliModelManifest} for key→modelType resolution.
721
880
  * @returns The constructed {@link CliContext}.
722
881
  * @__NO_SIDE_EFFECTS__
723
882
  */ function createCliContext(input) {
883
+ var apiBaseUrl = input.env.apiBaseUrl;
884
+ var accessToken = input.accessToken;
724
885
  return {
725
886
  cliName: input.cliName,
726
887
  envName: input.envName,
727
888
  env: input.env,
728
- accessToken: input.accessToken,
889
+ accessToken: accessToken,
890
+ modelManifest: input.modelManifest,
729
891
  callModel: function callModel(params) {
730
892
  return callModelOverHttp({
731
- apiBaseUrl: input.env.apiBaseUrl,
732
- accessToken: input.accessToken,
893
+ apiBaseUrl: apiBaseUrl,
894
+ accessToken: accessToken,
733
895
  params: params
734
896
  });
897
+ },
898
+ getModel: function getModel(modelType, key) {
899
+ return getModelOverHttp({
900
+ apiBaseUrl: apiBaseUrl,
901
+ accessToken: accessToken,
902
+ modelType: modelType,
903
+ key: key
904
+ });
905
+ },
906
+ getMultipleModels: function getMultipleModels(modelType, keys) {
907
+ return getMultipleModelsOverHttp({
908
+ apiBaseUrl: apiBaseUrl,
909
+ accessToken: accessToken,
910
+ modelType: modelType,
911
+ keys: keys
912
+ });
735
913
  }
736
914
  };
737
915
  }
738
916
 
739
- function asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, key, arg) {
917
+ function asyncGeneratorStep$g(gen, resolve, reject, _next, _throw, key, arg) {
740
918
  try {
741
919
  var info = gen[key](arg);
742
920
  var value = info.value;
@@ -750,16 +928,16 @@ function asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, key, arg) {
750
928
  Promise.resolve(value).then(_next, _throw);
751
929
  }
752
930
  }
753
- function _async_to_generator$e(fn) {
931
+ function _async_to_generator$g(fn) {
754
932
  return function() {
755
933
  var self = this, args = arguments;
756
934
  return new Promise(function(resolve, reject) {
757
935
  var gen = fn.apply(self, args);
758
936
  function _next(value) {
759
- asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, "next", value);
937
+ asyncGeneratorStep$g(gen, resolve, reject, _next, _throw, "next", value);
760
938
  }
761
939
  function _throw(err) {
762
- asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, "throw", err);
940
+ asyncGeneratorStep$g(gen, resolve, reject, _next, _throw, "throw", err);
763
941
  }
764
942
  _next(undefined);
765
943
  });
@@ -812,7 +990,7 @@ function _object_spread_props$7(target, source) {
812
990
  }
813
991
  return target;
814
992
  }
815
- function _ts_generator$e(thisArg, body) {
993
+ function _ts_generator$g(thisArg, body) {
816
994
  var f, y, t, _ = {
817
995
  label: 0,
818
996
  sent: function() {
@@ -928,9 +1106,9 @@ function _ts_generator$e(thisArg, body) {
928
1106
  return spec.builder ? spec.builder(yargs) : yargs;
929
1107
  },
930
1108
  handler: function handler(argv) {
931
- return _async_to_generator$e(function() {
1109
+ return _async_to_generator$g(function() {
932
1110
  var context, data, params, result, e;
933
- return _ts_generator$e(this, function(_state) {
1111
+ return _ts_generator$g(this, function(_state) {
934
1112
  switch(_state.label){
935
1113
  case 0:
936
1114
  _state.trys.push([
@@ -1091,7 +1269,7 @@ function _ts_generator$e(thisArg, body) {
1091
1269
  });
1092
1270
  }
1093
1271
 
1094
- function asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, key, arg) {
1272
+ function asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, key, arg) {
1095
1273
  try {
1096
1274
  var info = gen[key](arg);
1097
1275
  var value = info.value;
@@ -1105,16 +1283,16 @@ function asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, key, arg) {
1105
1283
  Promise.resolve(value).then(_next, _throw);
1106
1284
  }
1107
1285
  }
1108
- function _async_to_generator$d(fn) {
1286
+ function _async_to_generator$f(fn) {
1109
1287
  return function() {
1110
1288
  var self = this, args = arguments;
1111
1289
  return new Promise(function(resolve, reject) {
1112
1290
  var gen = fn.apply(self, args);
1113
1291
  function _next(value) {
1114
- asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, "next", value);
1292
+ asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, "next", value);
1115
1293
  }
1116
1294
  function _throw(err) {
1117
- asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, "throw", err);
1295
+ asyncGeneratorStep$f(gen, resolve, reject, _next, _throw, "throw", err);
1118
1296
  }
1119
1297
  _next(undefined);
1120
1298
  });
@@ -1175,7 +1353,7 @@ function _object_spread_props$6(target, source) {
1175
1353
  }
1176
1354
  return target;
1177
1355
  }
1178
- function _ts_generator$d(thisArg, body) {
1356
+ function _ts_generator$f(thisArg, body) {
1179
1357
  var f, y, t, _ = {
1180
1358
  label: 0,
1181
1359
  sent: function() {
@@ -1286,9 +1464,9 @@ function _ts_generator$d(thisArg, body) {
1286
1464
  return withCallModelArgs(yargs);
1287
1465
  },
1288
1466
  handler: function handler(argv) {
1289
- return _async_to_generator$d(function() {
1467
+ return _async_to_generator$f(function() {
1290
1468
  var context, data, params, result, e;
1291
- return _ts_generator$d(this, function(_state) {
1469
+ return _ts_generator$f(this, function(_state) {
1292
1470
  switch(_state.label){
1293
1471
  case 0:
1294
1472
  _state.trys.push([
@@ -1346,12 +1524,12 @@ function _ts_generator$d(thisArg, body) {
1346
1524
  }
1347
1525
  };
1348
1526
 
1349
- function _array_like_to_array$6(arr, len) {
1527
+ function _array_like_to_array$7(arr, len) {
1350
1528
  if (len == null || len > arr.length) len = arr.length;
1351
1529
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1352
1530
  return arr2;
1353
1531
  }
1354
- function _array_with_holes$3(arr) {
1532
+ function _array_with_holes$4(arr) {
1355
1533
  if (Array.isArray(arr)) return arr;
1356
1534
  }
1357
1535
  function _instanceof$4(left, right) {
@@ -1362,7 +1540,7 @@ function _instanceof$4(left, right) {
1362
1540
  return left instanceof right;
1363
1541
  }
1364
1542
  }
1365
- function _iterable_to_array_limit$3(arr, i) {
1543
+ function _iterable_to_array_limit$4(arr, i) {
1366
1544
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
1367
1545
  if (_i == null) return;
1368
1546
  var _arr = [];
@@ -1386,23 +1564,23 @@ function _iterable_to_array_limit$3(arr, i) {
1386
1564
  }
1387
1565
  return _arr;
1388
1566
  }
1389
- function _non_iterable_rest$3() {
1567
+ function _non_iterable_rest$4() {
1390
1568
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1391
1569
  }
1392
- function _sliced_to_array$3(arr, i) {
1393
- return _array_with_holes$3(arr) || _iterable_to_array_limit$3(arr, i) || _unsupported_iterable_to_array$6(arr, i) || _non_iterable_rest$3();
1570
+ function _sliced_to_array$4(arr, i) {
1571
+ return _array_with_holes$4(arr) || _iterable_to_array_limit$4(arr, i) || _unsupported_iterable_to_array$7(arr, i) || _non_iterable_rest$4();
1394
1572
  }
1395
1573
  function _type_of$1(obj) {
1396
1574
  "@swc/helpers - typeof";
1397
1575
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
1398
1576
  }
1399
- function _unsupported_iterable_to_array$6(o, minLen) {
1577
+ function _unsupported_iterable_to_array$7(o, minLen) {
1400
1578
  if (!o) return;
1401
- if (typeof o === "string") return _array_like_to_array$6(o, minLen);
1579
+ if (typeof o === "string") return _array_like_to_array$7(o, minLen);
1402
1580
  var n = Object.prototype.toString.call(o).slice(8, -1);
1403
1581
  if (n === "Object" && o.constructor) n = o.constructor.name;
1404
1582
  if (n === "Map" || n === "Set") return Array.from(n);
1405
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
1583
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$7(o, minLen);
1406
1584
  }
1407
1585
  /**
1408
1586
  * Resolves the manifest entry for `modelType`. Lookup tries
@@ -1433,113 +1611,914 @@ function _unsupported_iterable_to_array$6(o, minLen) {
1433
1611
  _iterator.return();
1434
1612
  }
1435
1613
  } finally{
1436
- if (_didIteratorError) {
1437
- throw _iteratorError;
1438
- }
1614
+ if (_didIteratorError) {
1615
+ throw _iteratorError;
1616
+ }
1617
+ }
1618
+ }
1619
+ return result;
1620
+ }
1621
+ /**
1622
+ * Rewrites the persisted (short) keys in `data` to the long-name form
1623
+ * declared in the model's manifest entry. Recurses into nested object-array
1624
+ * and sub-object fields when the manifest captured a nested field map.
1625
+ *
1626
+ * Returns the input untouched when `modelType` is not in the manifest, when
1627
+ * the model has no fields, or when the input is not a plain object/array.
1628
+ * Unknown keys, primitives, `Date`, `null`, and `undefined` pass through
1629
+ * unchanged.
1630
+ *
1631
+ * @param modelType - the model identifier (`modelType`, `identityConst`,
1632
+ * or `collectionPrefix`) used to look up the rewrite map.
1633
+ * @param data - the value to rewrite (typically a `read`/`query` response
1634
+ * payload).
1635
+ * @param manifest - generated model manifest.
1636
+ * @returns the rewritten value, or `data` unchanged when no rewrite applies.
1637
+ * @__NO_SIDE_EFFECTS__
1638
+ */ function expandModelKeys(modelType, data, manifest) {
1639
+ var entry = findCliModelManifestEntry(modelType, manifest);
1640
+ if (!entry) return data;
1641
+ return rewriteWithFields(data, entry.fields);
1642
+ }
1643
+ function rewriteWithFields(value, fields) {
1644
+ if (Array.isArray(value)) {
1645
+ return value.map(function(item) {
1646
+ return rewriteWithFields(item, fields);
1647
+ });
1648
+ }
1649
+ if (!isPlainObject(value)) return value;
1650
+ var fieldByName = new Map();
1651
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1652
+ try {
1653
+ for(var _iterator = fields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1654
+ var field = _step.value;
1655
+ fieldByName.set(field.name, field);
1656
+ }
1657
+ } catch (err) {
1658
+ _didIteratorError = true;
1659
+ _iteratorError = err;
1660
+ } finally{
1661
+ try {
1662
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1663
+ _iterator.return();
1664
+ }
1665
+ } finally{
1666
+ if (_didIteratorError) {
1667
+ throw _iteratorError;
1668
+ }
1669
+ }
1670
+ }
1671
+ var out = {};
1672
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
1673
+ try {
1674
+ for(var _iterator1 = Object.entries(value)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
1675
+ var _step_value = _sliced_to_array$4(_step1.value, 2), key = _step_value[0], raw = _step_value[1];
1676
+ var field1 = fieldByName.get(key);
1677
+ if (!field1) {
1678
+ out[key] = raw;
1679
+ continue;
1680
+ }
1681
+ var longKey = field1.longName.length > 0 ? field1.longName : key;
1682
+ out[longKey] = rewriteFieldValue(raw, field1);
1683
+ }
1684
+ } catch (err) {
1685
+ _didIteratorError1 = true;
1686
+ _iteratorError1 = err;
1687
+ } finally{
1688
+ try {
1689
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
1690
+ _iterator1.return();
1691
+ }
1692
+ } finally{
1693
+ if (_didIteratorError1) {
1694
+ throw _iteratorError1;
1695
+ }
1696
+ }
1697
+ }
1698
+ return out;
1699
+ }
1700
+ function rewriteFieldValue(value, field) {
1701
+ var nested = field.nestedFields;
1702
+ if (!nested || nested.length === 0) return value;
1703
+ if (field.nestedIsArray) {
1704
+ if (!Array.isArray(value)) return value;
1705
+ return value.map(function(item) {
1706
+ return rewriteWithFields(item, nested);
1707
+ });
1708
+ }
1709
+ if (!isPlainObject(value)) return value;
1710
+ return rewriteWithFields(value, nested);
1711
+ }
1712
+ function isPlainObject(value) {
1713
+ if (value === null || (typeof value === "undefined" ? "undefined" : _type_of$1(value)) !== 'object') return false;
1714
+ if (Array.isArray(value)) return false;
1715
+ if (_instanceof$4(value, Date)) return false;
1716
+ // Objects from JSON.parse have Object.prototype as their proto. Anything
1717
+ // exotic (Map, Set, Buffer, class instances) we leave untouched.
1718
+ var proto = Object.getPrototypeOf(value);
1719
+ return proto === Object.prototype || proto === null;
1720
+ }
1721
+
1722
+ /**
1723
+ * Default command name for the model-decode command. Top-level so it stays
1724
+ * out of the API-call namespace owned by `model <model> <action>`.
1725
+ */ var DEFAULT_MODEL_DECODE_COMMAND_NAME = 'model-decode';
1726
+ /**
1727
+ * Builds the top-level `model-decode <key>` command.
1728
+ *
1729
+ * Splits the supplied Firestore key on `/`, walks `[prefix, id]` pairs, and
1730
+ * resolves each prefix against the manifest. Supports subcollection paths
1731
+ * (`nb/abc/nbn/def` → leaf `Notification` + parent `NotificationBox`).
1732
+ *
1733
+ * Flags:
1734
+ * - `--json` emits a structured `{ ok, data }` envelope instead of the
1735
+ * human-readable block (useful for scripting or LLM agents).
1736
+ *
1737
+ * @param manifest - The generated model manifest (e.g. `DEMO_CLI_MODEL_MANIFEST`).
1738
+ * @param options - Optional overrides; see {@link BuildModelDecodeCommandOptions}.
1739
+ * @returns A yargs `CommandModule` ready to be passed to `runCli({ configCommands })`.
1740
+ * @__NO_SIDE_EFFECTS__
1741
+ */ function buildModelDecodeCommand(manifest, options) {
1742
+ var _ref;
1743
+ var commandName = (_ref = options === null || options === void 0 ? void 0 : options.commandName) !== null && _ref !== void 0 ? _ref : DEFAULT_MODEL_DECODE_COMMAND_NAME;
1744
+ return {
1745
+ command: "".concat(commandName, " <key>"),
1746
+ describe: 'Decode a Firestore model key (e.g. "jwr/abc123") into model + id info using the registered manifest ('.concat(manifest.length, " model").concat(manifest.length === 1 ? '' : 's', ")."),
1747
+ builder: function builder(yargs) {
1748
+ return yargs.positional('key', {
1749
+ type: 'string',
1750
+ describe: 'Firestore model key — prefix/id, supports subcollection paths like `parentPrefix/parentId/childPrefix/childId`.'
1751
+ }).option('json', {
1752
+ type: 'boolean',
1753
+ default: false,
1754
+ describe: 'Emit a structured JSON envelope instead of the human-readable block.'
1755
+ });
1756
+ },
1757
+ handler: function handler(argv) {
1758
+ try {
1759
+ runHandler$1(manifest, argv);
1760
+ } catch (e) {
1761
+ outputError(e);
1762
+ process.exit(1);
1763
+ }
1764
+ }
1765
+ };
1766
+ }
1767
+ function runHandler$1(manifest, argv) {
1768
+ var rawKey = typeof argv.key === 'string' ? argv.key : '';
1769
+ var decoded = decodeFirestoreModelKey(rawKey, manifest);
1770
+ if (argv.json) {
1771
+ outputResult(decoded);
1772
+ return;
1773
+ }
1774
+ process.stdout.write(renderDecodedKey(decoded));
1775
+ }
1776
+ /**
1777
+ * Splits `rawKey` on `/`, resolves each `[prefix, id]` pair against the
1778
+ * manifest, and returns the leaf segment + ancestor chain. Throws
1779
+ * {@link CliError} for malformed inputs.
1780
+ *
1781
+ * @param rawKey - The Firestore key string.
1782
+ * @param manifest - The generated model manifest.
1783
+ * @returns The decoded key with leaf, ancestors, and any unresolved prefixes.
1784
+ * @__NO_SIDE_EFFECTS__
1785
+ */ function decodeFirestoreModelKey(rawKey, manifest) {
1786
+ var trimmed = rawKey.trim();
1787
+ if (trimmed.length === 0) {
1788
+ throw new CliError({
1789
+ message: 'Key is empty. Provide a Firestore key like `sf/abc123`.',
1790
+ code: 'MODEL_DECODE_INVALID_KEY'
1791
+ });
1792
+ }
1793
+ var segments = trimmed.split('/').filter(function(s) {
1794
+ return s.length > 0;
1795
+ });
1796
+ if (segments.length < 2 || segments.length % 2 !== 0) {
1797
+ throw new CliError({
1798
+ message: "Invalid Firestore key '".concat(trimmed, "'. Expected an even number of segments (`prefix/id` pairs). Got ").concat(segments.length, " segment(s)."),
1799
+ code: 'MODEL_DECODE_INVALID_KEY',
1800
+ suggestion: 'Use the format `prefix/id` (or `parentPrefix/parentId/childPrefix/childId` for subcollections).'
1801
+ });
1802
+ }
1803
+ var decoded = [];
1804
+ var unresolved = [];
1805
+ for(var i = 0; i < segments.length; i += 2){
1806
+ var prefix = segments[i];
1807
+ var id = segments[i + 1];
1808
+ var entry = findCliModelManifestEntry(prefix, manifest);
1809
+ if (!entry) {
1810
+ unresolved.push(prefix);
1811
+ }
1812
+ decoded.push(toSegment(prefix, id, entry));
1813
+ }
1814
+ var leaf = decoded[decoded.length - 1];
1815
+ var ancestors = decoded.slice(0, -1);
1816
+ return {
1817
+ key: trimmed,
1818
+ leaf: leaf,
1819
+ ancestors: ancestors,
1820
+ unresolvedPrefixes: unresolved
1821
+ };
1822
+ }
1823
+ function toSegment(prefix, id, entry) {
1824
+ if (!entry) {
1825
+ return {
1826
+ prefix: prefix,
1827
+ id: id
1828
+ };
1829
+ }
1830
+ return {
1831
+ prefix: prefix,
1832
+ id: id,
1833
+ modelName: entry.modelName,
1834
+ modelType: entry.modelType,
1835
+ modelGroup: entry.modelGroup,
1836
+ identityConst: entry.identityConst,
1837
+ parentIdentityConst: entry.parentIdentityConst,
1838
+ sourcePackage: entry.sourcePackage,
1839
+ sourceFile: entry.sourceFile
1840
+ };
1841
+ }
1842
+ /**
1843
+ * Renders a {@link DecodedKey} as a human-readable text block. Mirrors the
1844
+ * MCP `dbx_model_decode` key-mode output for consistency between agent and
1845
+ * shell consumers.
1846
+ *
1847
+ * @param decoded - the decoded key returned by {@link decodeFirestoreModelKey}.
1848
+ * @returns the formatted block with a trailing newline.
1849
+ * @__NO_SIDE_EFFECTS__
1850
+ */ function renderDecodedKey(decoded) {
1851
+ var lines = [];
1852
+ var leaf = decoded.leaf;
1853
+ if (leaf.modelName) {
1854
+ lines.push("Model: ".concat(leaf.modelName));
1855
+ if (leaf.identityConst) lines.push("identityConst: ".concat(leaf.identityConst));
1856
+ if (leaf.modelType) lines.push("modelType: ".concat(leaf.modelType));
1857
+ lines.push("prefix: ".concat(leaf.prefix));
1858
+ lines.push("id: ".concat(leaf.id));
1859
+ if (leaf.modelGroup) lines.push("modelGroup: ".concat(leaf.modelGroup));
1860
+ if (leaf.parentIdentityConst) lines.push("parentIdentityConst: ".concat(leaf.parentIdentityConst));
1861
+ if (leaf.sourcePackage) {
1862
+ var sourceSuffix = leaf.sourceFile ? " (".concat(leaf.sourceFile, ")") : '';
1863
+ lines.push("source: ".concat(leaf.sourcePackage).concat(sourceSuffix));
1864
+ }
1865
+ } else {
1866
+ lines.push("Model: <unknown — prefix '".concat(leaf.prefix, "' not in manifest>"));
1867
+ lines.push("prefix: ".concat(leaf.prefix));
1868
+ lines.push("id: ".concat(leaf.id));
1869
+ }
1870
+ if (decoded.ancestors.length > 0) {
1871
+ lines.push('');
1872
+ lines.push('Parent chain:');
1873
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1874
+ try {
1875
+ for(var _iterator = decoded.ancestors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1876
+ var ancestor = _step.value;
1877
+ if (ancestor.modelName) {
1878
+ lines.push("- ".concat(ancestor.modelName, " — prefix ").concat(ancestor.prefix, ", id ").concat(ancestor.id));
1879
+ } else {
1880
+ lines.push("- <unknown> — prefix ".concat(ancestor.prefix, ", id ").concat(ancestor.id));
1881
+ }
1882
+ }
1883
+ } catch (err) {
1884
+ _didIteratorError = true;
1885
+ _iteratorError = err;
1886
+ } finally{
1887
+ try {
1888
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1889
+ _iterator.return();
1890
+ }
1891
+ } finally{
1892
+ if (_didIteratorError) {
1893
+ throw _iteratorError;
1894
+ }
1895
+ }
1896
+ }
1897
+ }
1898
+ if (decoded.unresolvedPrefixes.length > 0) {
1899
+ lines.push('');
1900
+ lines.push("Unresolved prefix".concat(decoded.unresolvedPrefixes.length === 1 ? '' : 'es', ": ").concat(decoded.unresolvedPrefixes.join(', '), ". Run `model-info` to list known models."));
1901
+ }
1902
+ return lines.join('\n') + '\n';
1903
+ }
1904
+
1905
+ function _array_like_to_array$6(arr, len) {
1906
+ if (len == null || len > arr.length) len = arr.length;
1907
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1908
+ return arr2;
1909
+ }
1910
+ function _array_with_holes$3(arr) {
1911
+ if (Array.isArray(arr)) return arr;
1912
+ }
1913
+ function _array_without_holes$4(arr) {
1914
+ if (Array.isArray(arr)) return _array_like_to_array$6(arr);
1915
+ }
1916
+ function _iterable_to_array$4(iter) {
1917
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1918
+ }
1919
+ function _iterable_to_array_limit$3(arr, i) {
1920
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
1921
+ if (_i == null) return;
1922
+ var _arr = [];
1923
+ var _n = true;
1924
+ var _d = false;
1925
+ var _s, _e;
1926
+ try {
1927
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
1928
+ _arr.push(_s.value);
1929
+ if (i && _arr.length === i) break;
1930
+ }
1931
+ } catch (err) {
1932
+ _d = true;
1933
+ _e = err;
1934
+ } finally{
1935
+ try {
1936
+ if (!_n && _i["return"] != null) _i["return"]();
1937
+ } finally{
1938
+ if (_d) throw _e;
1939
+ }
1940
+ }
1941
+ return _arr;
1942
+ }
1943
+ function _non_iterable_rest$3() {
1944
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1945
+ }
1946
+ function _non_iterable_spread$4() {
1947
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1948
+ }
1949
+ function _sliced_to_array$3(arr, i) {
1950
+ return _array_with_holes$3(arr) || _iterable_to_array_limit$3(arr, i) || _unsupported_iterable_to_array$6(arr, i) || _non_iterable_rest$3();
1951
+ }
1952
+ function _to_consumable_array$4(arr) {
1953
+ return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$6(arr) || _non_iterable_spread$4();
1954
+ }
1955
+ function _unsupported_iterable_to_array$6(o, minLen) {
1956
+ if (!o) return;
1957
+ if (typeof o === "string") return _array_like_to_array$6(o, minLen);
1958
+ var n = Object.prototype.toString.call(o).slice(8, -1);
1959
+ if (n === "Object" && o.constructor) n = o.constructor.name;
1960
+ if (n === "Map" || n === "Set") return Array.from(n);
1961
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
1962
+ }
1963
+ /**
1964
+ * Parses the positionals for the top-level `get <modelOrKey> [key]` command into a
1965
+ * `{ modelType, key }` pair, using the supplied {@link CliModelManifest} to resolve
1966
+ * collection-name prefixes when the explicit-model form is not used.
1967
+ *
1968
+ * Rules:
1969
+ * 1. Two positionals (`modelOrKey` + `key`) — `modelOrKey` is treated as the explicit
1970
+ * `modelType` and `key` is passed through verbatim. No manifest lookup performed.
1971
+ * 2. One positional (`modelOrKey` only) — treated as a full Firestore key (`prefix/id`).
1972
+ * {@link decodeFirestoreModelKey} resolves the prefix against the manifest. Throws
1973
+ * {@link CliError} if the manifest is missing, the prefix is unresolved, or the leaf
1974
+ * has no `modelType`.
1975
+ *
1976
+ * @param input.modelOrKey - The first positional from yargs.
1977
+ * @param input.key - The optional second positional from yargs.
1978
+ * @param input.manifest - The generated model manifest (for prefix lookup).
1979
+ * @returns The parsed `{ modelType, key }` pair.
1980
+ * @__NO_SIDE_EFFECTS__
1981
+ */ function parseGetArgs(input) {
1982
+ var _input_modelOrKey;
1983
+ var _input_key;
1984
+ var modelOrKey = ((_input_modelOrKey = input.modelOrKey) !== null && _input_modelOrKey !== void 0 ? _input_modelOrKey : '').trim();
1985
+ if (modelOrKey.length === 0) {
1986
+ throw new CliError({
1987
+ message: 'get: missing required positional. Usage: `get <key>` or `get <model> <key>`.',
1988
+ code: 'INVALID_ARGUMENT'
1989
+ });
1990
+ }
1991
+ var explicitKey = (_input_key = input.key) === null || _input_key === void 0 ? void 0 : _input_key.trim();
1992
+ if (explicitKey != null && explicitKey.length > 0) {
1993
+ return {
1994
+ modelType: modelOrKey,
1995
+ key: explicitKey
1996
+ };
1997
+ }
1998
+ if (!modelOrKey.includes('/')) {
1999
+ throw new CliError({
2000
+ message: "get: '".concat(modelOrKey, "' looks like a bare doc id. Provide a full key (e.g. 'jws/abc123') or use 'get <model> <key>'."),
2001
+ code: 'INVALID_ARGUMENT'
2002
+ });
2003
+ }
2004
+ var manifest = input.manifest;
2005
+ if (!manifest || manifest.length === 0) {
2006
+ throw new CliError({
2007
+ message: 'get: cannot infer modelType — no model manifest is wired into the CLI. Pass `modelManifest` to `runCli`, or use `get <model> <key>` explicitly.',
2008
+ code: 'INVALID_ARGUMENT'
2009
+ });
2010
+ }
2011
+ var decoded = decodeFirestoreModelKey(modelOrKey, manifest);
2012
+ if (decoded.unresolvedPrefixes.length > 0 || !decoded.leaf.modelType) {
2013
+ throw new CliError({
2014
+ message: "get: unable to resolve modelType for key '".concat(modelOrKey, "'. Unknown prefix: ").concat(decoded.unresolvedPrefixes.join(', ') || decoded.leaf.prefix, ". Known prefixes: ").concat(manifestPrefixList(manifest), "."),
2015
+ code: 'INVALID_ARGUMENT',
2016
+ suggestion: "Run `<cli> model-decode '<key>'` to inspect a key, or use `get <model> <key>` explicitly."
2017
+ });
2018
+ }
2019
+ return {
2020
+ modelType: decoded.leaf.modelType,
2021
+ key: modelOrKey
2022
+ };
2023
+ }
2024
+ /**
2025
+ * Parses the positionals for the top-level `get-many <firstArg> [rest..]` command.
2026
+ *
2027
+ * Rules:
2028
+ * 1. If `firstArg` contains `/` it is treated as a key — all positionals (`firstArg` + `rest`)
2029
+ * are decoded via {@link decodeFirestoreModelKey}. All keys must resolve to the same
2030
+ * `modelType` or a {@link CliError} is thrown (the backend route is single-modelType per call).
2031
+ * 2. Otherwise `firstArg` is treated as the explicit `modelType` and `rest` are the keys.
2032
+ *
2033
+ * Always rejects empty key lists and lists exceeding 50 keys.
2034
+ *
2035
+ * @param input.firstArg - The first positional from yargs.
2036
+ * @param input.rest - The remaining positionals from yargs.
2037
+ * @param input.manifest - The generated model manifest (used only in the inferred-key branch).
2038
+ * @returns The parsed `{ modelType, keys }` pair.
2039
+ * @__NO_SIDE_EFFECTS__
2040
+ */ function parseGetManyArgs(input) {
2041
+ var _input_firstArg, _input_rest;
2042
+ var firstArg = ((_input_firstArg = input.firstArg) !== null && _input_firstArg !== void 0 ? _input_firstArg : '').trim();
2043
+ var rest = ((_input_rest = input.rest) !== null && _input_rest !== void 0 ? _input_rest : []).map(function(s) {
2044
+ return s.trim();
2045
+ }).filter(function(s) {
2046
+ return s.length > 0;
2047
+ });
2048
+ if (firstArg.length === 0) {
2049
+ throw new CliError({
2050
+ message: 'get-many: missing required positionals. Usage: `get-many <key...>` or `get-many <model> <key...>`.',
2051
+ code: 'INVALID_ARGUMENT'
2052
+ });
2053
+ }
2054
+ if (firstArg.includes('/')) {
2055
+ var keys = [
2056
+ firstArg
2057
+ ].concat(_to_consumable_array$4(rest));
2058
+ return inferModelTypeFromKeys(keys, input.manifest);
2059
+ }
2060
+ if (rest.length === 0) {
2061
+ throw new CliError({
2062
+ message: "get-many: '".concat(firstArg, "' has no '/' so it was treated as a model name, but no keys were supplied. Usage: 'get-many <model> <key...>'."),
2063
+ code: 'INVALID_ARGUMENT'
2064
+ });
2065
+ }
2066
+ return {
2067
+ modelType: firstArg,
2068
+ keys: rest
2069
+ };
2070
+ }
2071
+ function inferModelTypeFromKeys(keys, manifest) {
2072
+ if (!manifest || manifest.length === 0) {
2073
+ throw new CliError({
2074
+ message: 'get-many: cannot infer modelType — no model manifest is wired into the CLI. Pass `modelManifest` to `runCli`, or use `get-many <model> <key...>` explicitly.',
2075
+ code: 'INVALID_ARGUMENT'
2076
+ });
2077
+ }
2078
+ var decodedTypes = new Set();
2079
+ var unresolved = [];
2080
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2081
+ try {
2082
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2083
+ var key = _step.value;
2084
+ var decoded = decodeFirestoreModelKey(key, manifest);
2085
+ if (decoded.unresolvedPrefixes.length > 0 || !decoded.leaf.modelType) {
2086
+ unresolved.push(key);
2087
+ } else {
2088
+ decodedTypes.add(decoded.leaf.modelType);
2089
+ }
2090
+ }
2091
+ } catch (err) {
2092
+ _didIteratorError = true;
2093
+ _iteratorError = err;
2094
+ } finally{
2095
+ try {
2096
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2097
+ _iterator.return();
2098
+ }
2099
+ } finally{
2100
+ if (_didIteratorError) {
2101
+ throw _iteratorError;
2102
+ }
2103
+ }
2104
+ }
2105
+ if (unresolved.length > 0) {
2106
+ throw new CliError({
2107
+ message: "get-many: unable to resolve modelType for key(s): ".concat(unresolved.join(', '), ". Known prefixes: ").concat(manifestPrefixList(manifest), "."),
2108
+ code: 'INVALID_ARGUMENT'
2109
+ });
2110
+ }
2111
+ if (decodedTypes.size > 1) {
2112
+ throw new CliError({
2113
+ message: "get-many: all keys must belong to the same modelType. Got: ".concat(_to_consumable_array$4(decodedTypes).join(', '), ". Split into separate calls."),
2114
+ code: 'INVALID_ARGUMENT'
2115
+ });
2116
+ }
2117
+ var _decodedTypes = _sliced_to_array$3(decodedTypes, 1), modelType = _decodedTypes[0];
2118
+ return {
2119
+ modelType: modelType,
2120
+ keys: keys
2121
+ };
2122
+ }
2123
+ function manifestPrefixList(manifest) {
2124
+ var prefixes = manifest.map(function(e) {
2125
+ return e.collectionPrefix;
2126
+ }).sort();
2127
+ return prefixes.join(', ');
2128
+ }
2129
+
2130
+ function asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, key, arg) {
2131
+ try {
2132
+ var info = gen[key](arg);
2133
+ var value = info.value;
2134
+ } catch (error) {
2135
+ reject(error);
2136
+ return;
2137
+ }
2138
+ if (info.done) {
2139
+ resolve(value);
2140
+ } else {
2141
+ Promise.resolve(value).then(_next, _throw);
2142
+ }
2143
+ }
2144
+ function _async_to_generator$e(fn) {
2145
+ return function() {
2146
+ var self = this, args = arguments;
2147
+ return new Promise(function(resolve, reject) {
2148
+ var gen = fn.apply(self, args);
2149
+ function _next(value) {
2150
+ asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, "next", value);
2151
+ }
2152
+ function _throw(err) {
2153
+ asyncGeneratorStep$e(gen, resolve, reject, _next, _throw, "throw", err);
2154
+ }
2155
+ _next(undefined);
2156
+ });
2157
+ };
2158
+ }
2159
+ function _ts_generator$e(thisArg, body) {
2160
+ var f, y, t, _ = {
2161
+ label: 0,
2162
+ sent: function() {
2163
+ if (t[0] & 1) throw t[1];
2164
+ return t[1];
2165
+ },
2166
+ trys: [],
2167
+ ops: []
2168
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
2169
+ return d(g, "next", {
2170
+ value: verb(0)
2171
+ }), d(g, "throw", {
2172
+ value: verb(1)
2173
+ }), d(g, "return", {
2174
+ value: verb(2)
2175
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
2176
+ value: function() {
2177
+ return this;
2178
+ }
2179
+ }), g;
2180
+ function verb(n) {
2181
+ return function(v) {
2182
+ return step([
2183
+ n,
2184
+ v
2185
+ ]);
2186
+ };
2187
+ }
2188
+ function step(op) {
2189
+ if (f) throw new TypeError("Generator is already executing.");
2190
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
2191
+ 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;
2192
+ if (y = 0, t) op = [
2193
+ op[0] & 2,
2194
+ t.value
2195
+ ];
2196
+ switch(op[0]){
2197
+ case 0:
2198
+ case 1:
2199
+ t = op;
2200
+ break;
2201
+ case 4:
2202
+ _.label++;
2203
+ return {
2204
+ value: op[1],
2205
+ done: false
2206
+ };
2207
+ case 5:
2208
+ _.label++;
2209
+ y = op[1];
2210
+ op = [
2211
+ 0
2212
+ ];
2213
+ continue;
2214
+ case 7:
2215
+ op = _.ops.pop();
2216
+ _.trys.pop();
2217
+ continue;
2218
+ default:
2219
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
2220
+ _ = 0;
2221
+ continue;
2222
+ }
2223
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
2224
+ _.label = op[1];
2225
+ break;
2226
+ }
2227
+ if (op[0] === 6 && _.label < t[1]) {
2228
+ _.label = t[1];
2229
+ t = op;
2230
+ break;
2231
+ }
2232
+ if (t && _.label < t[2]) {
2233
+ _.label = t[2];
2234
+ _.ops.push(op);
2235
+ break;
2236
+ }
2237
+ if (t[2]) _.ops.pop();
2238
+ _.trys.pop();
2239
+ continue;
2240
+ }
2241
+ op = body.call(thisArg, _);
2242
+ } catch (e) {
2243
+ op = [
2244
+ 6,
2245
+ e
2246
+ ];
2247
+ y = 0;
2248
+ } finally{
2249
+ f = t = 0;
2250
+ }
2251
+ if (op[0] & 5) throw op[1];
2252
+ return {
2253
+ value: op[0] ? op[1] : void 0,
2254
+ done: true
2255
+ };
2256
+ }
2257
+ }
2258
+ /**
2259
+ * Top-level `get <modelOrKey> [key]` command.
2260
+ *
2261
+ * Reads a single Firestore document via the typed model-access endpoint. The `model` arg is optional:
2262
+ * when only one positional is supplied, the CLI resolves the modelType from the key's leading
2263
+ * collection-name prefix via {@link decodeFirestoreModelKey}. The two-positional form passes the
2264
+ * explicit `modelType` straight through.
2265
+ *
2266
+ * Backend: `GET <apiBaseUrl>/model/<modelType>/get?key=<key>` (ModelApiController.getOne).
2267
+ */ var getCommand = {
2268
+ command: 'get <modelOrKey> [key]',
2269
+ describe: 'Read a document by key. ModelType is inferred from the key prefix when only one positional is supplied.',
2270
+ builder: function builder(yargs) {
2271
+ return yargs.positional('modelOrKey', {
2272
+ type: 'string',
2273
+ describe: 'Full key (e.g. "jws/abc123") or model name when a second positional is supplied.'
2274
+ }).positional('key', {
2275
+ type: 'string',
2276
+ describe: 'Document key when the first positional is a model name.'
2277
+ });
2278
+ },
2279
+ handler: function handler(argv) {
2280
+ return _async_to_generator$e(function() {
2281
+ var context, _parseGetArgs, modelType, key, result, e;
2282
+ return _ts_generator$e(this, function(_state) {
2283
+ switch(_state.label){
2284
+ case 0:
2285
+ _state.trys.push([
2286
+ 0,
2287
+ 2,
2288
+ ,
2289
+ 3
2290
+ ]);
2291
+ context = requireCliContext();
2292
+ _parseGetArgs = parseGetArgs({
2293
+ modelOrKey: typeof argv.modelOrKey === 'string' ? argv.modelOrKey : undefined,
2294
+ key: typeof argv.key === 'string' ? argv.key : undefined,
2295
+ manifest: context.modelManifest
2296
+ }), modelType = _parseGetArgs.modelType, key = _parseGetArgs.key;
2297
+ return [
2298
+ 4,
2299
+ context.getModel(modelType, key)
2300
+ ];
2301
+ case 1:
2302
+ result = _state.sent();
2303
+ outputResult(result);
2304
+ return [
2305
+ 3,
2306
+ 3
2307
+ ];
2308
+ case 2:
2309
+ e = _state.sent();
2310
+ outputError(e);
2311
+ process.exit(1);
2312
+ return [
2313
+ 3,
2314
+ 3
2315
+ ];
2316
+ case 3:
2317
+ return [
2318
+ 2
2319
+ ];
2320
+ }
2321
+ });
2322
+ })();
2323
+ }
2324
+ };
2325
+
2326
+ function asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, key, arg) {
2327
+ try {
2328
+ var info = gen[key](arg);
2329
+ var value = info.value;
2330
+ } catch (error) {
2331
+ reject(error);
2332
+ return;
2333
+ }
2334
+ if (info.done) {
2335
+ resolve(value);
2336
+ } else {
2337
+ Promise.resolve(value).then(_next, _throw);
2338
+ }
2339
+ }
2340
+ function _async_to_generator$d(fn) {
2341
+ return function() {
2342
+ var self = this, args = arguments;
2343
+ return new Promise(function(resolve, reject) {
2344
+ var gen = fn.apply(self, args);
2345
+ function _next(value) {
2346
+ asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, "next", value);
2347
+ }
2348
+ function _throw(err) {
2349
+ asyncGeneratorStep$d(gen, resolve, reject, _next, _throw, "throw", err);
2350
+ }
2351
+ _next(undefined);
2352
+ });
2353
+ };
2354
+ }
2355
+ function _ts_generator$d(thisArg, body) {
2356
+ var f, y, t, _ = {
2357
+ label: 0,
2358
+ sent: function() {
2359
+ if (t[0] & 1) throw t[1];
2360
+ return t[1];
2361
+ },
2362
+ trys: [],
2363
+ ops: []
2364
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
2365
+ return d(g, "next", {
2366
+ value: verb(0)
2367
+ }), d(g, "throw", {
2368
+ value: verb(1)
2369
+ }), d(g, "return", {
2370
+ value: verb(2)
2371
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
2372
+ value: function() {
2373
+ return this;
2374
+ }
2375
+ }), g;
2376
+ function verb(n) {
2377
+ return function(v) {
2378
+ return step([
2379
+ n,
2380
+ v
2381
+ ]);
2382
+ };
2383
+ }
2384
+ function step(op) {
2385
+ if (f) throw new TypeError("Generator is already executing.");
2386
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
2387
+ 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;
2388
+ if (y = 0, t) op = [
2389
+ op[0] & 2,
2390
+ t.value
2391
+ ];
2392
+ switch(op[0]){
2393
+ case 0:
2394
+ case 1:
2395
+ t = op;
2396
+ break;
2397
+ case 4:
2398
+ _.label++;
2399
+ return {
2400
+ value: op[1],
2401
+ done: false
2402
+ };
2403
+ case 5:
2404
+ _.label++;
2405
+ y = op[1];
2406
+ op = [
2407
+ 0
2408
+ ];
2409
+ continue;
2410
+ case 7:
2411
+ op = _.ops.pop();
2412
+ _.trys.pop();
2413
+ continue;
2414
+ default:
2415
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
2416
+ _ = 0;
2417
+ continue;
2418
+ }
2419
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
2420
+ _.label = op[1];
2421
+ break;
2422
+ }
2423
+ if (op[0] === 6 && _.label < t[1]) {
2424
+ _.label = t[1];
2425
+ t = op;
2426
+ break;
2427
+ }
2428
+ if (t && _.label < t[2]) {
2429
+ _.label = t[2];
2430
+ _.ops.push(op);
2431
+ break;
2432
+ }
2433
+ if (t[2]) _.ops.pop();
2434
+ _.trys.pop();
2435
+ continue;
2436
+ }
2437
+ op = body.call(thisArg, _);
2438
+ } catch (e) {
2439
+ op = [
2440
+ 6,
2441
+ e
2442
+ ];
2443
+ y = 0;
2444
+ } finally{
2445
+ f = t = 0;
1439
2446
  }
2447
+ if (op[0] & 5) throw op[1];
2448
+ return {
2449
+ value: op[0] ? op[1] : void 0,
2450
+ done: true
2451
+ };
1440
2452
  }
1441
- return result;
1442
2453
  }
1443
2454
  /**
1444
- * Rewrites the persisted (short) keys in `data` to the long-name form
1445
- * declared in the model's manifest entry. Recurses into nested object-array
1446
- * and sub-object fields when the manifest captured a nested field map.
2455
+ * Top-level `get-many <firstArg> [rest..]` command.
1447
2456
  *
1448
- * Returns the input untouched when `modelType` is not in the manifest, when
1449
- * the model has no fields, or when the input is not a plain object/array.
1450
- * Unknown keys, primitives, `Date`, `null`, and `undefined` pass through
1451
- * unchanged.
2457
+ * Batch-reads up to 50 Firestore documents in a single request. The first positional can either
2458
+ * be an explicit modelType (followed by ≥1 keys) or a full key (followed by additional keys whose
2459
+ * prefixes must resolve to the same modelType).
1452
2460
  *
1453
- * @param modelType - the model identifier (`modelType`, `identityConst`,
1454
- * or `collectionPrefix`) used to look up the rewrite map.
1455
- * @param data - the value to rewrite (typically a `read`/`query` response
1456
- * payload).
1457
- * @param manifest - generated model manifest.
1458
- * @returns the rewritten value, or `data` unchanged when no rewrite applies.
1459
- * @__NO_SIDE_EFFECTS__
1460
- */ function expandModelKeys(modelType, data, manifest) {
1461
- var entry = findCliModelManifestEntry(modelType, manifest);
1462
- if (!entry) return data;
1463
- return rewriteWithFields(data, entry.fields);
1464
- }
1465
- function rewriteWithFields(value, fields) {
1466
- if (Array.isArray(value)) {
1467
- return value.map(function(item) {
1468
- return rewriteWithFields(item, fields);
1469
- });
1470
- }
1471
- if (!isPlainObject(value)) return value;
1472
- var fieldByName = new Map();
1473
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1474
- try {
1475
- for(var _iterator = fields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1476
- var field = _step.value;
1477
- fieldByName.set(field.name, field);
1478
- }
1479
- } catch (err) {
1480
- _didIteratorError = true;
1481
- _iteratorError = err;
1482
- } finally{
1483
- try {
1484
- if (!_iteratorNormalCompletion && _iterator.return != null) {
1485
- _iterator.return();
1486
- }
1487
- } finally{
1488
- if (_didIteratorError) {
1489
- throw _iteratorError;
1490
- }
1491
- }
1492
- }
1493
- var out = {};
1494
- var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
1495
- try {
1496
- for(var _iterator1 = Object.entries(value)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
1497
- var _step_value = _sliced_to_array$3(_step1.value, 2), key = _step_value[0], raw = _step_value[1];
1498
- var field1 = fieldByName.get(key);
1499
- if (!field1) {
1500
- out[key] = raw;
1501
- continue;
1502
- }
1503
- var longKey = field1.longName.length > 0 ? field1.longName : key;
1504
- out[longKey] = rewriteFieldValue(raw, field1);
1505
- }
1506
- } catch (err) {
1507
- _didIteratorError1 = true;
1508
- _iteratorError1 = err;
1509
- } finally{
1510
- try {
1511
- if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
1512
- _iterator1.return();
1513
- }
1514
- } finally{
1515
- if (_didIteratorError1) {
1516
- throw _iteratorError1;
1517
- }
1518
- }
1519
- }
1520
- return out;
1521
- }
1522
- function rewriteFieldValue(value, field) {
1523
- var nested = field.nestedFields;
1524
- if (!nested || nested.length === 0) return value;
1525
- if (field.nestedIsArray) {
1526
- if (!Array.isArray(value)) return value;
1527
- return value.map(function(item) {
1528
- return rewriteWithFields(item, nested);
2461
+ * Backend: `POST <apiBaseUrl>/model/<modelType>/get` with body `{ keys }` (ModelApiController.getMany).
2462
+ */ var getManyCommand = {
2463
+ command: 'get-many <firstArg> [rest..]',
2464
+ describe: 'Read up to 50 documents by key. ModelType is inferred from key prefixes when they all agree.',
2465
+ builder: function builder(yargs) {
2466
+ return yargs.positional('firstArg', {
2467
+ type: 'string',
2468
+ describe: 'Full key (e.g. "jws/abc") or model name when the remaining positionals are bare ids.'
2469
+ }).positional('rest', {
2470
+ type: 'string',
2471
+ array: true,
2472
+ default: [],
2473
+ describe: 'Additional keys (or bare ids when the first positional is a model name).'
1529
2474
  });
2475
+ },
2476
+ handler: function handler(argv) {
2477
+ return _async_to_generator$d(function() {
2478
+ var context, _parseGetManyArgs, modelType, keys, result, e;
2479
+ return _ts_generator$d(this, function(_state) {
2480
+ switch(_state.label){
2481
+ case 0:
2482
+ _state.trys.push([
2483
+ 0,
2484
+ 2,
2485
+ ,
2486
+ 3
2487
+ ]);
2488
+ context = requireCliContext();
2489
+ _parseGetManyArgs = parseGetManyArgs({
2490
+ firstArg: typeof argv.firstArg === 'string' ? argv.firstArg : undefined,
2491
+ rest: Array.isArray(argv.rest) ? argv.rest : [],
2492
+ manifest: context.modelManifest
2493
+ }), modelType = _parseGetManyArgs.modelType, keys = _parseGetManyArgs.keys;
2494
+ return [
2495
+ 4,
2496
+ context.getMultipleModels(modelType, keys)
2497
+ ];
2498
+ case 1:
2499
+ result = _state.sent();
2500
+ outputResult(result);
2501
+ return [
2502
+ 3,
2503
+ 3
2504
+ ];
2505
+ case 2:
2506
+ e = _state.sent();
2507
+ outputError(e);
2508
+ process.exit(1);
2509
+ return [
2510
+ 3,
2511
+ 3
2512
+ ];
2513
+ case 3:
2514
+ return [
2515
+ 2
2516
+ ];
2517
+ }
2518
+ });
2519
+ })();
1530
2520
  }
1531
- if (!isPlainObject(value)) return value;
1532
- return rewriteWithFields(value, nested);
1533
- }
1534
- function isPlainObject(value) {
1535
- if (value === null || (typeof value === "undefined" ? "undefined" : _type_of$1(value)) !== 'object') return false;
1536
- if (Array.isArray(value)) return false;
1537
- if (_instanceof$4(value, Date)) return false;
1538
- // Objects from JSON.parse have Object.prototype as their proto. Anything
1539
- // exotic (Map, Set, Buffer, class instances) we leave untouched.
1540
- var proto = Object.getPrototypeOf(value);
1541
- return proto === Object.prototype || proto === null;
1542
- }
2521
+ };
1543
2522
 
1544
2523
  function asyncGeneratorStep$c(gen, resolve, reject, _next, _throw, key, arg) {
1545
2524
  try {
@@ -1868,6 +2847,11 @@ function mergeOutputCommandsConfig(existing, updates) {
1868
2847
  'model.update',
1869
2848
  'model.delete'
1870
2849
  ];
2850
+ /**
2851
+ * The default redirect URI used by the CLI.
2852
+ *
2853
+ * Opens up to nothing in the browser so the user can copy/paste the resulting token url back into the CLI.
2854
+ */ var DEFAULT_CLI_REDIRECT_URI = 'http://127.0.0.1:0/callback';
1871
2855
  /**
1872
2856
  * Returns the input scope string with the `model.create`, `model.update`, and `model.delete`
1873
2857
  * scopes removed, preserving every other scope (including `model.read` and `model.query`).
@@ -2198,7 +3182,8 @@ function _ts_generator$b(thisArg, body) {
2198
3182
  }
2199
3183
  }
2200
3184
  /**
2201
- * Fetches the OIDC discovery document for the given issuer, trying these candidates in order:
3185
+ * Builds the ordered list of `.well-known/openid-configuration` URLs the CLI probes when
3186
+ * discovering OIDC metadata.
2202
3187
  *
2203
3188
  * 1. `<issuer>/.well-known/openid-configuration` (OpenID Connect Discovery 1.0).
2204
3189
  * 2. `<issuer-origin>/.well-known/openid-configuration` (host-rooted; matches projects that
@@ -2206,33 +3191,48 @@ function _ts_generator$b(thisArg, body) {
2206
3191
  * sub-path — e.g. demo's `OidcWellKnownController`).
2207
3192
  * 3. `<fallbackBaseUrl>/.well-known/openid-configuration` when supplied and not already covered.
2208
3193
  *
3194
+ * Exported so diagnostic surfaces (e.g. `doctor`) can show the exact URLs the discovery step
3195
+ * tried — without re-implementing the candidate ordering.
3196
+ *
3197
+ * @param input - The discovery request.
3198
+ * @param input.issuer - The OIDC issuer URL whose `.well-known/openid-configuration` is fetched first.
3199
+ * @param input.fallbackBaseUrl - Optional sibling base URL appended after the issuer-prefixed and origin-rooted candidates.
3200
+ * @returns The candidate URL list in probe order, de-duplicated.
3201
+ */ function buildOidcDiscoveryCandidates(input) {
3202
+ var candidates = [
3203
+ "".concat(trimSlash(input.issuer), "/.well-known/openid-configuration")
3204
+ ];
3205
+ try {
3206
+ var originCandidate = "".concat(new URL(input.issuer).origin, "/.well-known/openid-configuration");
3207
+ if (!candidates.includes(originCandidate)) {
3208
+ candidates.push(originCandidate);
3209
+ }
3210
+ } catch (unused) {
3211
+ // Issuer URL didn't parse — skip the origin-rooted candidate and let the explicit fallback handle it.
3212
+ }
3213
+ if (input.fallbackBaseUrl) {
3214
+ var fallbackCandidate = "".concat(trimSlash(input.fallbackBaseUrl), "/.well-known/openid-configuration");
3215
+ if (!candidates.includes(fallbackCandidate)) {
3216
+ candidates.push(fallbackCandidate);
3217
+ }
3218
+ }
3219
+ return candidates;
3220
+ }
3221
+ /**
3222
+ * Fetches the OIDC discovery document for the given issuer, trying the candidates returned by
3223
+ * {@link buildOidcDiscoveryCandidates} in order.
3224
+ *
2209
3225
  * @param input - The discovery request.
2210
3226
  * @param input.issuer - The OIDC issuer URL whose `.well-known/openid-configuration` is fetched first.
2211
3227
  * @param input.fallbackBaseUrl - Optional sibling base URL tried after the issuer-prefixed and origin-rooted candidates.
2212
3228
  * @returns The parsed {@link OidcDiscoveryMetadata}. Throws a {@link CliError} (`OIDC_DISCOVERY_FAILED`) when every candidate fails.
2213
3229
  */ function discoverOidcMetadata(input) {
2214
3230
  return _async_to_generator$b(function() {
2215
- var _ref, candidates, originCandidate, fallbackCandidate, lastError, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, url, res, e, err;
3231
+ var _ref, candidates, lastError, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, url, res, e, err;
2216
3232
  return _ts_generator$b(this, function(_state) {
2217
3233
  switch(_state.label){
2218
3234
  case 0:
2219
- candidates = [
2220
- "".concat(trimSlash(input.issuer), "/.well-known/openid-configuration")
2221
- ];
2222
- try {
2223
- originCandidate = "".concat(new URL(input.issuer).origin, "/.well-known/openid-configuration");
2224
- if (!candidates.includes(originCandidate)) {
2225
- candidates.push(originCandidate);
2226
- }
2227
- } catch (unused) {
2228
- // Issuer URL didn't parse — skip the origin-rooted candidate and let the explicit fallback handle it.
2229
- }
2230
- if (input.fallbackBaseUrl) {
2231
- fallbackCandidate = "".concat(trimSlash(input.fallbackBaseUrl), "/.well-known/openid-configuration");
2232
- if (!candidates.includes(fallbackCandidate)) {
2233
- candidates.push(fallbackCandidate);
2234
- }
2235
- }
3235
+ candidates = buildOidcDiscoveryCandidates(input);
2236
3236
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2237
3237
  _state.label = 1;
2238
3238
  case 1:
@@ -2289,7 +3289,7 @@ function _ts_generator$b(thisArg, body) {
2289
3289
  ];
2290
3290
  case 7:
2291
3291
  e = _state.sent();
2292
- lastError = _instanceof$3(e, Error) ? e : new Error(String(e));
3292
+ lastError = new Error("OIDC discovery failed at ".concat(url, ": ").concat(_instanceof$3(e, Error) ? e.message : String(e)));
2293
3293
  return [
2294
3294
  3,
2295
3295
  8
@@ -2328,7 +3328,7 @@ function _ts_generator$b(thisArg, body) {
2328
3328
  ];
2329
3329
  case 12:
2330
3330
  throw new CliError({
2331
- message: (_ref = lastError === null || lastError === void 0 ? void 0 : lastError.message) !== null && _ref !== void 0 ? _ref : 'OIDC discovery failed',
3331
+ message: (_ref = lastError === null || lastError === void 0 ? void 0 : lastError.message) !== null && _ref !== void 0 ? _ref : "OIDC discovery failed for all candidates: ".concat(candidates.join(', ')),
2332
3332
  code: 'OIDC_DISCOVERY_FAILED',
2333
3333
  suggestion: 'Verify the env oidcIssuer URL is reachable and serves /.well-known/openid-configuration.'
2334
3334
  });
@@ -2723,14 +3723,24 @@ function _ts_generator$a(thisArg, body) {
2723
3723
  /**
2724
3724
  * Builds the authorization URL the user opens in a browser to start the PKCE flow.
2725
3725
  *
2726
- * Resolves the user-facing endpoint by preferring `appClientUrl` (rebases the discovered
2727
- * authorization endpoint onto that origin) over `apiBaseUrl` (`/oidc/login/client` shortcut),
2728
- * and finally falls back to the discovered `authorizationEndpoint` itself.
3726
+ * The user-facing endpoint is the discovered `authorizationEndpoint` (typically `/oidc/auth`)
3727
+ * with its origin optionally rebased. The rebase origin is the first non-empty value among
3728
+ * `appClientUrl` `oidcIssuer` origin `apiBaseUrl` origin. In a typical single-host
3729
+ * deployment all three resolve to the same origin and the rebase is a no-op; in a split-host
3730
+ * setup (frontend dev server proxying `/oidc/**` to the API) `appClientUrl` redirects the user
3731
+ * through the frontend. When none of the three is provided, the discovered endpoint is used
3732
+ * unchanged.
3733
+ *
3734
+ * Always lands at the actual authorization endpoint so oidc-provider can create an interaction
3735
+ * and redirect to the app login page with a `uid`. (Earlier versions targeted a convenience
3736
+ * `/oidc/login/client` redirect that forwarded query params to the app without creating an
3737
+ * interaction — that branch is gone.)
2729
3738
  *
2730
3739
  * @param input - The authorization URL inputs.
2731
3740
  * @param input.authorizationEndpoint - The authorization endpoint discovered from OIDC metadata.
2732
- * @param input.apiBaseUrl - Optional API base URL; when set without `appClientUrl`, the URL is built against `<apiBaseUrl>/oidc/login/client`.
2733
- * @param input.appClientUrl - Optional frontend origin to rebase the authorization endpoint onto. Takes precedence over `apiBaseUrl`.
3741
+ * @param input.appClientUrl - Optional client origin to rebase the authorization endpoint onto. Takes precedence over `oidcIssuer` and `apiBaseUrl`.
3742
+ * @param input.oidcIssuer - Optional OIDC issuer URL; falls back to its origin as the rebase target when `appClientUrl` is missing.
3743
+ * @param input.apiBaseUrl - Optional API base URL; falls back to its origin as the rebase target when neither `appClientUrl` nor `oidcIssuer` is set.
2734
3744
  * @param input.clientId - The OAuth client ID.
2735
3745
  * @param input.redirectUri - The redirect URI registered with the OAuth client.
2736
3746
  * @param input.scopes - Space-separated scope list. Defaults to {@link DEFAULT_CLI_OIDC_SCOPES}.
@@ -2740,15 +3750,22 @@ function _ts_generator$a(thisArg, body) {
2740
3750
  * @__NO_SIDE_EFFECTS__
2741
3751
  */ function buildAuthorizationUrl(input) {
2742
3752
  var _input_scopes;
3753
+ var resolvedScope = (_input_scopes = input.scopes) !== null && _input_scopes !== void 0 ? _input_scopes : DEFAULT_CLI_OIDC_SCOPES;
2743
3754
  var authParams = {
2744
3755
  response_type: 'code',
2745
3756
  client_id: input.clientId,
2746
3757
  redirect_uri: input.redirectUri,
2747
- scope: (_input_scopes = input.scopes) !== null && _input_scopes !== void 0 ? _input_scopes : DEFAULT_CLI_OIDC_SCOPES,
3758
+ scope: resolvedScope,
2748
3759
  code_challenge: input.codeChallenge,
2749
3760
  code_challenge_method: 'S256',
2750
3761
  state: input.state
2751
3762
  };
3763
+ // oidc-provider's check_scope middleware silently strips `offline_access` unless the
3764
+ // auth request also includes `prompt=consent`. Auto-add it so refresh tokens are
3765
+ // actually issued whenever the CLI requests offline access.
3766
+ if (resolvedScope.split(/\s+/).includes('offline_access')) {
3767
+ authParams.prompt = 'consent';
3768
+ }
2752
3769
  if (input.requestedSessionTtlSeconds != null) {
2753
3770
  if (!Number.isInteger(input.requestedSessionTtlSeconds) || input.requestedSessionTtlSeconds <= 0) {
2754
3771
  throw new CliError({
@@ -2758,19 +3775,17 @@ function _ts_generator$a(thisArg, body) {
2758
3775
  }
2759
3776
  authParams.dbx_session_ttl = String(input.requestedSessionTtlSeconds);
2760
3777
  }
2761
- var endpoint;
2762
- if (input.appClientUrl) {
2763
- endpoint = rebaseUrlOrigin({
2764
- url: input.authorizationEndpoint,
2765
- originUrl: input.appClientUrl
2766
- });
2767
- } else if (input.apiBaseUrl) {
2768
- endpoint = "".concat(input.apiBaseUrl.replace(/\/+$/, ''), "/oidc/login/client");
2769
- } else {
2770
- endpoint = input.authorizationEndpoint;
2771
- }
3778
+ var rebaseOrigin = resolveAuthorizationRebaseOrigin({
3779
+ appClientUrl: input.appClientUrl,
3780
+ oidcIssuer: input.oidcIssuer,
3781
+ apiBaseUrl: input.apiBaseUrl
3782
+ });
3783
+ var endpoint = rebaseOrigin ? rebaseUrlOrigin({
3784
+ url: input.authorizationEndpoint,
3785
+ originUrl: rebaseOrigin
3786
+ }) : input.authorizationEndpoint;
2772
3787
  // Merge into the existing query string (preserving any params already on the endpoint) so
2773
- // a pre-baked endpoint like `/login/client?source=cli` survives unchanged.
3788
+ // a pre-baked endpoint like `/oidc/auth?source=cli` survives unchanged.
2774
3789
  var url = new URL(endpoint);
2775
3790
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2776
3791
  try {
@@ -2794,6 +3809,31 @@ function _ts_generator$a(thisArg, body) {
2794
3809
  }
2795
3810
  return url.toString();
2796
3811
  }
3812
+ /**
3813
+ * Picks the origin used to rebase the discovered authorization endpoint, in priority order:
3814
+ * 1. `appClientUrl` (verbatim — the explicit override)
3815
+ * 2. `oidcIssuer` (parsed `origin`, e.g. `https://api.example.com/oidc` → `https://api.example.com`)
3816
+ * 3. `apiBaseUrl` (parsed `origin`, e.g. `https://api.example.com/api` → `https://api.example.com`)
3817
+ *
3818
+ * Returns `undefined` when none is set or every candidate fails to parse; the caller should then
3819
+ * use the discovered endpoint unchanged.
3820
+ */ function resolveAuthorizationRebaseOrigin(input) {
3821
+ var result;
3822
+ if (input.appClientUrl) {
3823
+ result = input.appClientUrl;
3824
+ } else {
3825
+ var _input_oidcIssuer;
3826
+ var fallbackSource = (_input_oidcIssuer = input.oidcIssuer) !== null && _input_oidcIssuer !== void 0 ? _input_oidcIssuer : input.apiBaseUrl;
3827
+ if (fallbackSource) {
3828
+ try {
3829
+ result = new URL(fallbackSource).origin;
3830
+ } catch (unused) {
3831
+ // Fall through with result undefined
3832
+ }
3833
+ }
3834
+ }
3835
+ return result;
3836
+ }
2797
3837
  /**
2798
3838
  * Returns `url` with its origin replaced by the origin of `originUrl`. The path and search of
2799
3839
  * `url` are preserved. When `originUrl` is empty/missing or either URL fails to parse, returns
@@ -3457,11 +4497,11 @@ function maskEnv$1(env) {
3457
4497
  resolve({
3458
4498
  argvValue: argv.redirectUri,
3459
4499
  existingValue: existing === null || existing === void 0 ? void 0 : existing.redirectUri,
3460
- prompt: "Redirect URI [".concat((_ref4 = existing === null || existing === void 0 ? void 0 : existing.redirectUri) !== null && _ref4 !== void 0 ? _ref4 : 'http://127.0.0.1:0/callback', "]: ")
4500
+ prompt: "Redirect URI [".concat((_ref4 = existing === null || existing === void 0 ? void 0 : existing.redirectUri) !== null && _ref4 !== void 0 ? _ref4 : DEFAULT_CLI_REDIRECT_URI, "]: ")
3461
4501
  })
3462
4502
  ];
3463
4503
  case 9:
3464
- redirectUri = (_ref3 = _state.sent()) !== null && _ref3 !== void 0 ? _ref3 : 'http://127.0.0.1:0/callback';
4504
+ redirectUri = (_ref3 = _state.sent()) !== null && _ref3 !== void 0 ? _ref3 : DEFAULT_CLI_REDIRECT_URI;
3465
4505
  scopes = (_argv_scopes = argv.scopes) !== null && _argv_scopes !== void 0 ? _argv_scopes : existing === null || existing === void 0 ? void 0 : existing.scopes;
3466
4506
  if (!apiBaseUrl || !oidcIssuer || !clientId || !clientSecret) {
3467
4507
  throw new CliError({
@@ -3601,6 +4641,7 @@ function maskEnv$1(env) {
3601
4641
  }
3602
4642
  url = buildAuthorizationUrl({
3603
4643
  authorizationEndpoint: meta.authorization_endpoint,
4644
+ oidcIssuer: env.oidcIssuer,
3604
4645
  apiBaseUrl: env.apiBaseUrl,
3605
4646
  appClientUrl: env.appClientUrl,
3606
4647
  clientId: env.clientId,
@@ -4348,7 +5389,7 @@ function _ts_generator$8(thisArg, body) {
4348
5389
  function(param) {
4349
5390
  var env = param.env;
4350
5391
  return _async_to_generator$8(function() {
4351
- var meta, e;
5392
+ var candidates, meta, e;
4352
5393
  return _ts_generator$8(this, function(_state) {
4353
5394
  switch(_state.label){
4354
5395
  case 0:
@@ -4362,6 +5403,10 @@ function _ts_generator$8(thisArg, body) {
4362
5403
  }
4363
5404
  ];
4364
5405
  }
5406
+ candidates = buildOidcDiscoveryCandidates({
5407
+ issuer: env.oidcIssuer,
5408
+ fallbackBaseUrl: env.apiBaseUrl
5409
+ });
4365
5410
  _state.label = 1;
4366
5411
  case 1:
4367
5412
  _state.trys.push([
@@ -4385,6 +5430,7 @@ function _ts_generator$8(thisArg, body) {
4385
5430
  name: 'oidc-discovery-reachable',
4386
5431
  ok: true,
4387
5432
  detail: {
5433
+ candidates: candidates,
4388
5434
  authorization_endpoint: meta.authorization_endpoint,
4389
5435
  token_endpoint: meta.token_endpoint
4390
5436
  }
@@ -4398,6 +5444,7 @@ function _ts_generator$8(thisArg, body) {
4398
5444
  name: 'oidc-discovery-reachable',
4399
5445
  ok: false,
4400
5446
  detail: {
5447
+ candidates: candidates,
4401
5448
  error: _instanceof$2(e, Error) ? e.message : String(e)
4402
5449
  },
4403
5450
  suggestion: 'Verify the env oidcIssuer URL and that the API is running.'
@@ -4503,7 +5550,10 @@ function _ts_generator$8(thisArg, body) {
4503
5550
  {
4504
5551
  name: 'token-refresh-round-trip',
4505
5552
  ok: false,
4506
- suggestion: "Run `".concat(cliName, " auth login --env ").concat(envName, "`.")
5553
+ detail: {
5554
+ reason: 'no-refresh-token'
5555
+ },
5556
+ suggestion: 'No refresh token cached for env "'.concat(envName, '". Run `').concat(cliName, " auth login --env ").concat(envName, "` — if the env's scopes omit `offline_access`, the OIDC provider may not issue one.")
4507
5557
  }
4508
5558
  ];
4509
5559
  }
@@ -4580,6 +5630,7 @@ function _ts_generator$8(thisArg, body) {
4580
5630
  }
4581
5631
  ];
4582
5632
  }
5633
+ url = "".concat(env.apiBaseUrl.replace(/\/+$/, '')).concat(CALL_MODEL_API_PATH);
4583
5634
  _state.label = 1;
4584
5635
  case 1:
4585
5636
  _state.trys.push([
@@ -4588,7 +5639,6 @@ function _ts_generator$8(thisArg, body) {
4588
5639
  ,
4589
5640
  4
4590
5641
  ]);
4591
- url = "".concat(env.apiBaseUrl.replace(/\/+$/, '')).concat(CALL_MODEL_API_PATH);
4592
5642
  return [
4593
5643
  4,
4594
5644
  fetch(url, {
@@ -4603,6 +5653,7 @@ function _ts_generator$8(thisArg, body) {
4603
5653
  name: 'api-base-url-reachable',
4604
5654
  ok: res.status < 500,
4605
5655
  detail: {
5656
+ url: url,
4606
5657
  status: res.status
4607
5658
  }
4608
5659
  }
@@ -4615,6 +5666,7 @@ function _ts_generator$8(thisArg, body) {
4615
5666
  name: 'api-base-url-reachable',
4616
5667
  ok: false,
4617
5668
  detail: {
5669
+ url: url,
4618
5670
  error: _instanceof$2(e, Error) ? e.message : String(e)
4619
5671
  },
4620
5672
  suggestion: 'Verify the API is running at apiBaseUrl.'
@@ -6126,7 +7178,8 @@ function _ts_generator$6(thisArg, body) {
6126
7178
  cliName: input.cliName,
6127
7179
  envName: envName,
6128
7180
  env: env,
6129
- accessToken: entry.accessToken
7181
+ accessToken: entry.accessToken,
7182
+ modelManifest: input.modelManifest
6130
7183
  }));
6131
7184
  return [
6132
7185
  3,
@@ -7273,10 +8326,16 @@ function _ts_generator$2(thisArg, body) {
7273
8326
  if (input.modelManifest && input.disableModelInfo !== true) {
7274
8327
  builtInConfigCommands.push(buildModelInfoCommand(input.modelManifest));
7275
8328
  }
8329
+ if (input.modelManifest && input.disableModelDecode !== true) {
8330
+ builtInConfigCommands.push(buildModelDecodeCommand(input.modelManifest));
8331
+ }
7276
8332
  var allConfigCommands = _to_consumable_array$1(builtInConfigCommands).concat(_to_consumable_array$1((_input_configCommands = input.configCommands) !== null && _input_configCommands !== void 0 ? _input_configCommands : []));
7277
8333
  var builtInApiCommands = input.disableCallPassthrough ? [] : [
7278
8334
  callPassthroughCommand
7279
8335
  ];
8336
+ if (input.disableModelGet !== true) {
8337
+ builtInApiCommands.push(getCommand, getManyCommand);
8338
+ }
7280
8339
  var allApiCommands = _to_consumable_array$1(builtInApiCommands).concat(_to_consumable_array$1((_input_apiCommands = input.apiCommands) !== null && _input_apiCommands !== void 0 ? _input_apiCommands : []));
7281
8340
  var skipCommandNames = new Set(allConfigCommands.map(function(c) {
7282
8341
  return commandName(c);
@@ -7328,7 +8387,8 @@ function _ts_generator$2(thisArg, body) {
7328
8387
  createAuthMiddleware({
7329
8388
  cliName: cliName,
7330
8389
  skipCommands: skipCommandNames,
7331
- defaultEnvs: defaultEnvs
8390
+ defaultEnvs: defaultEnvs,
8391
+ modelManifest: input.modelManifest
7332
8392
  }),
7333
8393
  createOutputMiddleware({
7334
8394
  cliName: cliName,
@@ -7880,6 +8940,7 @@ function buildModelCommand(model, entries, context) {
7880
8940
  }
7881
8941
  }
7882
8942
  }
8943
+ yargs.command(buildPerModelGetCommand(model));
7883
8944
  hideGlobalOptions(yargs, context.hideOnFocus);
7884
8945
  return yargs.demandCommand(1, 'Please specify an action.');
7885
8946
  },
@@ -7888,6 +8949,71 @@ function buildModelCommand(model, entries, context) {
7888
8949
  }
7889
8950
  };
7890
8951
  }
8952
+ /**
8953
+ * Synthetic per-model `get <key>` sub-command appended to every model's command tree.
8954
+ *
8955
+ * The parent `model <name>` already fixes the `modelType`, so this command just passes the bare
8956
+ * `key` positional through to `context.getModel(modelType, key)`. Supports both the full
8957
+ * `<prefix>/<id>` form and a bare doc id (when the user knows the modelType from the parent).
8958
+ */ function buildPerModelGetCommand(model) {
8959
+ return {
8960
+ command: 'get <key>',
8961
+ describe: "Read a single ".concat(model, " document by key."),
8962
+ builder: function builder(yargs) {
8963
+ return yargs.positional('key', {
8964
+ type: 'string',
8965
+ describe: "Firestore key for the ".concat(model, " document (full `prefix/id` or bare id).")
8966
+ });
8967
+ },
8968
+ handler: function handler(argv) {
8969
+ return _async_to_generator$1(function() {
8970
+ var ctx, key, result, e;
8971
+ return _ts_generator$1(this, function(_state) {
8972
+ switch(_state.label){
8973
+ case 0:
8974
+ _state.trys.push([
8975
+ 0,
8976
+ 2,
8977
+ ,
8978
+ 3
8979
+ ]);
8980
+ ctx = requireCliContext();
8981
+ key = typeof argv.key === 'string' ? argv.key.trim() : '';
8982
+ if (key.length === 0) {
8983
+ throw new CliError({
8984
+ message: "get: missing required <key> positional for model '".concat(model, "'."),
8985
+ code: 'INVALID_ARGUMENT'
8986
+ });
8987
+ }
8988
+ return [
8989
+ 4,
8990
+ ctx.getModel(model, key)
8991
+ ];
8992
+ case 1:
8993
+ result = _state.sent();
8994
+ outputResult(result);
8995
+ return [
8996
+ 3,
8997
+ 3
8998
+ ];
8999
+ case 2:
9000
+ e = _state.sent();
9001
+ outputError(e);
9002
+ process.exit(1);
9003
+ return [
9004
+ 3,
9005
+ 3
9006
+ ];
9007
+ case 3:
9008
+ return [
9009
+ 2
9010
+ ];
9011
+ }
9012
+ });
9013
+ })();
9014
+ }
9015
+ };
9016
+ }
7891
9017
  function buildEntryCommand(entry, context) {
7892
9018
  var _oneLineDescription;
7893
9019
  var action = entry.specifier && entry.specifier !== '_' ? "".concat(entry.verb, "-").concat(entry.specifier) : entry.verb;
@@ -8836,13 +9962,16 @@ Object.defineProperty(exports, "CALL_MODEL_APP_FUNCTION_KEY", {
8836
9962
  exports.CALL_MODEL_API_PATH = CALL_MODEL_API_PATH;
8837
9963
  exports.CliError = CliError;
8838
9964
  exports.DEFAULT_CLI_OIDC_SCOPES = DEFAULT_CLI_OIDC_SCOPES;
9965
+ exports.DEFAULT_CLI_REDIRECT_URI = DEFAULT_CLI_REDIRECT_URI;
8839
9966
  exports.DEFAULT_CLI_SECRET_PATTERNS = DEFAULT_CLI_SECRET_PATTERNS;
8840
9967
  exports.DEFAULT_MANIFEST_HELP_DATA_FORMAT = DEFAULT_MANIFEST_HELP_DATA_FORMAT;
8841
9968
  exports.DEFAULT_MANIFEST_HELP_MODE = DEFAULT_MANIFEST_HELP_MODE;
8842
9969
  exports.DEFAULT_MANIFEST_MODEL_COMMAND_NAME = DEFAULT_MANIFEST_MODEL_COMMAND_NAME;
9970
+ exports.DEFAULT_MODEL_DECODE_COMMAND_NAME = DEFAULT_MODEL_DECODE_COMMAND_NAME;
8843
9971
  exports.DEFAULT_MODEL_INFO_COMMAND_NAME = DEFAULT_MODEL_INFO_COMMAND_NAME;
8844
9972
  exports.DUMP_MERGE_MODES = DUMP_MERGE_MODES;
8845
9973
  exports.DUMP_OUTPUT_MODES = DUMP_OUTPUT_MODES;
9974
+ exports.MAX_MODEL_ACCESS_MULTI_READ_KEYS = MAX_MODEL_ACCESS_MULTI_READ_KEYS;
8846
9975
  exports.MODEL_WRITE_OIDC_SCOPES = MODEL_WRITE_OIDC_SCOPES;
8847
9976
  exports.MULTIPLE_PAGES_OUTPUT_MODES = MULTIPLE_PAGES_OUTPUT_MODES;
8848
9977
  exports.PROMPT_CANCELLED_ERROR_CODE = PROMPT_CANCELLED_ERROR_CODE;
@@ -8853,7 +9982,9 @@ exports.buildCliPaths = buildCliPaths;
8853
9982
  exports.buildDumpFilePath = buildDumpFilePath;
8854
9983
  exports.buildErrorOutput = buildErrorOutput;
8855
9984
  exports.buildManifestCommands = buildManifestCommands;
9985
+ exports.buildModelDecodeCommand = buildModelDecodeCommand;
8856
9986
  exports.buildModelInfoCommand = buildModelInfoCommand;
9987
+ exports.buildOidcDiscoveryCandidates = buildOidcDiscoveryCandidates;
8857
9988
  exports.callModelOverHttp = callModelOverHttp;
8858
9989
  exports.callPassthroughCommand = callPassthroughCommand;
8859
9990
  exports.configureCliErrorMapper = configureCliErrorMapper;
@@ -8870,6 +10001,7 @@ exports.createDoctorCommand = createDoctorCommand;
8870
10001
  exports.createEnvCommand = createEnvCommand;
8871
10002
  exports.createOutputCommand = createOutputCommand;
8872
10003
  exports.createOutputMiddleware = createOutputMiddleware;
10004
+ exports.decodeFirestoreModelKey = decodeFirestoreModelKey;
8873
10005
  exports.defaultDoctorChecks = defaultDoctorChecks;
8874
10006
  exports.detectDataHelpFormat = detectDataHelpFormat;
8875
10007
  exports.detectHelpMode = detectHelpMode;
@@ -8884,6 +10016,10 @@ exports.findCliModelManifestEntry = findCliModelManifestEntry;
8884
10016
  exports.generateOAuthState = generateOAuthState;
8885
10017
  exports.generatePkceMaterial = generatePkceMaterial;
8886
10018
  exports.getCliContext = getCliContext;
10019
+ exports.getCommand = getCommand;
10020
+ exports.getManyCommand = getManyCommand;
10021
+ exports.getModelOverHttp = getModelOverHttp;
10022
+ exports.getMultipleModelsOverHttp = getMultipleModelsOverHttp;
8887
10023
  exports.getOutputOptions = getOutputOptions;
8888
10024
  exports.isCliEnvConfigComplete = isCliEnvConfigComplete;
8889
10025
  exports.isTokenExpired = isTokenExpired;
@@ -8895,10 +10031,13 @@ exports.mergeOutputConfig = mergeOutputConfig;
8895
10031
  exports.openStreamingDump = openStreamingDump;
8896
10032
  exports.outputError = outputError;
8897
10033
  exports.outputResult = outputResult;
10034
+ exports.parseGetArgs = parseGetArgs;
10035
+ exports.parseGetManyArgs = parseGetManyArgs;
8898
10036
  exports.parsePastedRedirect = parsePastedRedirect;
8899
10037
  exports.pickFields = pickFields;
8900
10038
  exports.promptLine = promptLine;
8901
10039
  exports.refreshAccessToken = refreshAccessToken;
10040
+ exports.renderDecodedKey = renderDecodedKey;
8902
10041
  exports.renderModelManifestEntry = renderModelManifestEntry;
8903
10042
  exports.renderModelManifestFields = renderModelManifestFields;
8904
10043
  exports.renderModelManifestList = renderModelManifestList;