@dereekb/dbx-components-mcp 13.41.0 → 13.43.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.
@@ -10,7 +10,7 @@ var __export = (target, all) => {
10
10
  // packages/dbx-components-mcp/package.json
11
11
  var package_default = {
12
12
  name: "@dereekb/dbx-components-mcp",
13
- version: "13.41.0",
13
+ version: "13.43.0",
14
14
  type: "module",
15
15
  bin: {
16
16
  "dbx-components-mcp": "dbx-components-mcp.js"
@@ -21,8 +21,8 @@ var package_default = {
21
21
  "ts-morph": "^21.0.0"
22
22
  },
23
23
  peerDependencies: {
24
- "@dereekb/dbx-cli": "13.41.0",
25
- "@dereekb/util": "13.41.0"
24
+ "@dereekb/dbx-cli": "13.43.0",
25
+ "@dereekb/util": "13.43.0"
26
26
  }
27
27
  };
28
28
 
@@ -1859,6 +1859,365 @@ var WORKSPACE_AUTH_CLAIMS = [...DEMO_CLAIMS];
1859
1859
 
1860
1860
  // packages/dbx-cli/generated/firebase-models.generated.ts
1861
1861
  var FIREBASE_MODELS = [
1862
+ {
1863
+ name: "Calendar",
1864
+ identityConst: "calendarIdentity",
1865
+ modelType: "calendar",
1866
+ collectionPrefix: "cal",
1867
+ sourcePackage: "@dereekb/firebase",
1868
+ sourceFile: "packages/firebase/src/lib/model/calendar/calendar.ts",
1869
+ fields: [
1870
+ {
1871
+ name: "t",
1872
+ longName: "calendarType",
1873
+ converter: "firestoreString<CalendarType>()",
1874
+ tsType: "CalendarType",
1875
+ optional: false,
1876
+ description: "The kind of calendar this is, resolving its retention policy and ICS emission config."
1877
+ },
1878
+ {
1879
+ name: "n",
1880
+ longName: "name",
1881
+ converter: "firestoreString<string>({ default: '' })",
1882
+ tsType: "string",
1883
+ optional: false,
1884
+ description: "Display name of the calendar. Emitted as NAME/X-WR-CALNAME."
1885
+ },
1886
+ {
1887
+ name: "d",
1888
+ longName: "description",
1889
+ converter: "optionalFirestoreString()",
1890
+ tsType: "Maybe<string>",
1891
+ optional: true,
1892
+ description: "Description of the calendar. Emitted as DESCRIPTION/X-WR-CALDESC."
1893
+ },
1894
+ {
1895
+ name: "tz",
1896
+ longName: "timezone",
1897
+ converter: "firestoreTimezoneString({ default: UTC_TIMEZONE_STRING })",
1898
+ tsType: "TimezoneString",
1899
+ optional: false,
1900
+ description: "Default timezone of the calendar. Emitted as X-WR-TIMEZONE, and the fallback for an event with no `tz`."
1901
+ },
1902
+ {
1903
+ name: "c",
1904
+ longName: "color",
1905
+ converter: "optionalFirestoreString()",
1906
+ tsType: "Maybe<string>",
1907
+ optional: true,
1908
+ description: "CSS3 color name for the calendar. Emitted as COLOR."
1909
+ },
1910
+ {
1911
+ name: "o",
1912
+ longName: "ownerKey",
1913
+ converter: "optionalFirestoreString()",
1914
+ tsType: "Maybe<FirebaseAuthOwnershipKey>",
1915
+ optional: true,
1916
+ description: "Ownership key, if applicable."
1917
+ },
1918
+ {
1919
+ name: "e",
1920
+ longName: "events",
1921
+ converter: "firestoreObjectArray({ objectField: calendarEventItem, sortWith: calendarEventItemsSortFunction<CalendarEventItem>(), filterUnique: calendarEventItemsFilterUniqueFunction<CalendarEventItem>() })",
1922
+ tsType: "CalendarEventItem[]",
1923
+ optional: false,
1924
+ description: "The calendar's one-off events, ascending by start instant and unique by id."
1925
+ },
1926
+ {
1927
+ name: "r",
1928
+ longName: "recurringEvents",
1929
+ converter: "firestoreObjectArray({ objectField: calendarRecurringEventItem, sortWith: calendarEventItemsSortFunction<CalendarRecurringEventItem>(), filterUnique: calendarEventItemsFilterUniqueFunction<CalendarRecurringEventItem>() })",
1930
+ tsType: "CalendarRecurringEventItem[]",
1931
+ optional: false,
1932
+ description: "The calendar's recurring events, ascending by anchor instant and unique by id."
1933
+ },
1934
+ {
1935
+ name: "x",
1936
+ longName: "extensionData",
1937
+ converter: "optionalFirestorePassthroughJsonField<CalendarExtensionData>({ filterEmptyValues: true, dontStoreIfEmpty: true })",
1938
+ tsType: "Maybe<CalendarExtensionData>",
1939
+ optional: true,
1940
+ description: `Extension data emitted as "X-" properties on the calendar's VCALENDAR.`
1941
+ },
1942
+ {
1943
+ name: "cat",
1944
+ longName: "createdAt",
1945
+ converter: "firestoreDate({ saveDefaultAsNow: true })",
1946
+ tsType: "Date",
1947
+ optional: false,
1948
+ description: "Created at date."
1949
+ },
1950
+ {
1951
+ name: "uat",
1952
+ longName: "updatedAt",
1953
+ converter: "firestoreDate({ saveDefaultAsNow: true })",
1954
+ tsType: "Date",
1955
+ optional: false,
1956
+ description: "Updated at date. Moves on every content change."
1957
+ },
1958
+ {
1959
+ name: "s",
1960
+ longName: "needsSync",
1961
+ converter: "optionalFirestoreBoolean({ dontStoreIf: false })",
1962
+ tsType: "Maybe<NeedsSyncBoolean>",
1963
+ optional: true,
1964
+ description: "True if this Calendar should be swept and its published ICS regenerated."
1965
+ },
1966
+ {
1967
+ name: "sat",
1968
+ longName: "syncedAt",
1969
+ converter: "optionalFirestoreDate()",
1970
+ tsType: "Maybe<Date>",
1971
+ optional: true,
1972
+ description: "The last date the published ICS was successfully uploaded."
1973
+ },
1974
+ {
1975
+ name: "rat",
1976
+ longName: "icsRotatedAt",
1977
+ converter: "optionalFirestoreDate()",
1978
+ tsType: "Maybe<Date>",
1979
+ optional: true,
1980
+ description: "The last date this calendar's published ICS link was rotated."
1981
+ },
1982
+ {
1983
+ name: "isf",
1984
+ longName: "icsStorageFileId",
1985
+ converter: "optionalFirestoreString()",
1986
+ tsType: "Maybe<StorageFileId>",
1987
+ optional: true,
1988
+ description: "StorageFile that holds the published ICS for this calendar."
1989
+ },
1990
+ {
1991
+ name: "iu",
1992
+ longName: "icsUrl",
1993
+ converter: "optionalFirestoreString<StorageFilePublicDownloadUrl>()",
1994
+ tsType: "Maybe<StorageFilePublicDownloadUrl>",
1995
+ optional: true,
1996
+ description: "The permanent, anonymously-readable URL the published ICS is served from."
1997
+ }
1998
+ ],
1999
+ enums: [],
2000
+ detectionHints: ["t", "n", "tz", "c", "e", "r", "x", "uat", "sat", "rat", "isf", "iu"],
2001
+ description: 'A calendar and all of its events, stored in one document and published as an ".ics" file.',
2002
+ modelGroup: "Calendar",
2003
+ collectionKind: "root",
2004
+ archetypes: ["root-entity"]
2005
+ },
2006
+ {
2007
+ name: "FormSpace",
2008
+ identityConst: "formSpaceIdentity",
2009
+ modelType: "formSpace",
2010
+ collectionPrefix: "fsp",
2011
+ sourcePackage: "@dereekb/firebase",
2012
+ sourceFile: "packages/firebase/src/lib/model/formspace/formspace.ts",
2013
+ fields: [
2014
+ {
2015
+ name: "t",
2016
+ longName: "formSpaceType",
2017
+ converter: "firestoreString<FormSpaceType>()",
2018
+ tsType: "FormSpaceType",
2019
+ optional: false,
2020
+ description: "The kind of form this space holds, resolving its upload restrictions, expiration policy, and the server-side handler its submission is dispatched to."
2021
+ },
2022
+ {
2023
+ name: "n",
2024
+ longName: "displayName",
2025
+ converter: "optionalFirestoreString()",
2026
+ tsType: "Maybe<string>",
2027
+ optional: true,
2028
+ description: "Display name of the space, for the owner's own list of in-progress forms."
2029
+ },
2030
+ {
2031
+ name: "s",
2032
+ longName: "state",
2033
+ converter: "firestoreEnum<FormSpaceState>({ default: FormSpaceState.DRAFT })",
2034
+ tsType: "FormSpaceState",
2035
+ optional: false,
2036
+ description: "Lifecycle state. Only DRAFT is editable.",
2037
+ enumRef: "FormSpaceState"
2038
+ },
2039
+ {
2040
+ name: "ps",
2041
+ longName: "processingState",
2042
+ converter: "firestoreEnum<FormSpaceProcessingState>({ default: FormSpaceProcessingState.INIT_OR_NONE })",
2043
+ tsType: "FormSpaceProcessingState",
2044
+ optional: false,
2045
+ description: "Processing state of the submission.",
2046
+ enumRef: "FormSpaceProcessingState"
2047
+ },
2048
+ {
2049
+ name: "d",
2050
+ longName: "data",
2051
+ converter: "optionalFirestorePassthroughJsonField<FormSpaceData>({ dontStoreIfEmpty: true })",
2052
+ tsType: "Maybe<T>",
2053
+ optional: true,
2054
+ description: "The form's own values, stored as pass-through JSON."
2055
+ },
2056
+ {
2057
+ name: "u",
2058
+ longName: "userId",
2059
+ converter: "firestoreUID()",
2060
+ tsType: "FirebaseAuthUserId",
2061
+ optional: false,
2062
+ description: "The user the space belongs to. Set at creation and never changed."
2063
+ },
2064
+ {
2065
+ name: "o",
2066
+ longName: "ownerKey",
2067
+ converter: "optionalFirestoreString()",
2068
+ tsType: "Maybe<FirebaseAuthOwnershipKey>",
2069
+ optional: true,
2070
+ description: "Ownership key, if applicable. Drives read access in the security rules."
2071
+ },
2072
+ {
2073
+ name: "m",
2074
+ longName: "targetModelKey",
2075
+ converter: "optionalFirestoreString()",
2076
+ tsType: "Maybe<FirestoreModelKey>",
2077
+ optional: true,
2078
+ description: "Key of the model this space was opened against, when it was opened against one."
2079
+ },
2080
+ {
2081
+ name: "uc",
2082
+ longName: "uploadCount",
2083
+ converter: "firestoreNumber({ default: 0 })",
2084
+ tsType: "number",
2085
+ optional: false,
2086
+ description: "Monotonic count of uploads this space has ACCEPTED over its whole lifetime."
2087
+ },
2088
+ {
2089
+ name: "fi",
2090
+ longName: "nextFileIndex",
2091
+ converter: "firestoreNumber({ default: 0 })",
2092
+ tsType: "number",
2093
+ optional: false,
2094
+ description: "The next index a file's permanent storage path is keyed by."
2095
+ },
2096
+ {
2097
+ name: "f",
2098
+ longName: "files",
2099
+ converter: "firestoreObjectArray({ objectField: formSpaceFileSubObject })",
2100
+ tsType: "FormSpaceFile[]",
2101
+ optional: false,
2102
+ description: "Every file the space currently holds, across every slot."
2103
+ },
2104
+ {
2105
+ name: "pn",
2106
+ longName: "processingNotificationKey",
2107
+ converter: "optionalFirestoreString()",
2108
+ tsType: "Maybe<NotificationKey>",
2109
+ optional: true,
2110
+ description: "The NotificationTask key processing this space's submission."
2111
+ },
2112
+ {
2113
+ name: "pat",
2114
+ longName: "processingAt",
2115
+ converter: "optionalFirestoreDate()",
2116
+ tsType: "Maybe<Date>",
2117
+ optional: true,
2118
+ description: "The date `ps` was last moved to PROCESSING. Used to detect a stuck task."
2119
+ },
2120
+ {
2121
+ name: "cat",
2122
+ longName: "createdAt",
2123
+ converter: "firestoreDate({ saveDefaultAsNow: true })",
2124
+ tsType: "Date",
2125
+ optional: false,
2126
+ description: "Created at date."
2127
+ },
2128
+ {
2129
+ name: "uat",
2130
+ longName: "updatedAt",
2131
+ converter: "firestoreDate({ saveDefaultAsNow: true })",
2132
+ tsType: "Date",
2133
+ optional: false,
2134
+ description: "Updated at date. Moves on every content change."
2135
+ },
2136
+ {
2137
+ name: "sat",
2138
+ longName: "submittedAt",
2139
+ converter: "optionalFirestoreDate()",
2140
+ tsType: "Maybe<Date>",
2141
+ optional: true,
2142
+ description: "The date the space was submitted, if it was. Its presence IS the lock."
2143
+ },
2144
+ {
2145
+ name: "cpat",
2146
+ longName: "completedAt",
2147
+ converter: "optionalFirestoreDate()",
2148
+ tsType: "Maybe<Date>",
2149
+ optional: true,
2150
+ description: "The date processing of the submission concluded, if it has."
2151
+ },
2152
+ {
2153
+ name: "eat",
2154
+ longName: "expiresAt",
2155
+ converter: "optionalFirestoreDate()",
2156
+ tsType: "Maybe<Date>",
2157
+ optional: true,
2158
+ description: "The date this space becomes eligible for the expiration sweep, if it expires at all."
2159
+ }
2160
+ ],
2161
+ enums: [
2162
+ {
2163
+ name: "FormSpaceState",
2164
+ values: [
2165
+ {
2166
+ name: "DRAFT",
2167
+ value: 0
2168
+ },
2169
+ {
2170
+ name: "SUBMITTED",
2171
+ value: 1
2172
+ },
2173
+ {
2174
+ name: "EXPIRED",
2175
+ value: 2
2176
+ },
2177
+ {
2178
+ name: "ARCHIVED",
2179
+ value: 3
2180
+ }
2181
+ ],
2182
+ description: "Lifecycle state of a {@link FormSpace}."
2183
+ },
2184
+ {
2185
+ name: "FormSpaceProcessingState",
2186
+ values: [
2187
+ {
2188
+ name: "INIT_OR_NONE",
2189
+ value: 0
2190
+ },
2191
+ {
2192
+ name: "QUEUED_FOR_PROCESSING",
2193
+ value: 1
2194
+ },
2195
+ {
2196
+ name: "PROCESSING",
2197
+ value: 2
2198
+ },
2199
+ {
2200
+ name: "FAILED",
2201
+ value: 3
2202
+ },
2203
+ {
2204
+ name: "SUCCESS",
2205
+ value: 4
2206
+ },
2207
+ {
2208
+ name: "DO_NOT_PROCESS",
2209
+ value: 5
2210
+ }
2211
+ ],
2212
+ description: "Processing state of a submitted {@link FormSpace}."
2213
+ }
2214
+ ],
2215
+ detectionHints: ["t", "n", "ps", "m", "uc", "f", "pn", "pat", "uat", "sat", "cpat", "eat"],
2216
+ description: "A type-registered container for a client-side form: its in-progress JSON, its uploads, and its submission state.",
2217
+ modelGroup: "FormSpace",
2218
+ collectionKind: "root",
2219
+ archetypes: ["root-entity", "state-machine-item"]
2220
+ },
1862
2221
  {
1863
2222
  name: "NotificationBox",
1864
2223
  identityConst: "notificationBoxIdentity",
@@ -2987,6 +3346,16 @@ var RESERVED_MODEL_FOLDERS = [
2987
3346
  name: "storagefile",
2988
3347
  reason: "StorageFile is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (group, upload, file, etc.); downstream projects extend rather than redeclare it.",
2989
3348
  recommendedTool: "dbx_storagefile_m_validate_folder"
3349
+ },
3350
+ {
3351
+ name: "formspace",
3352
+ reason: "FormSpace is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (type, upload, task, util, etc.); a downstream project only registers its own types and does not redeclare the model.",
3353
+ recommendedTool: "dbx_model_validate_folder"
3354
+ },
3355
+ {
3356
+ name: "calendar",
3357
+ reason: "Calendar is a canonical group from `@dereekb/firebase` with a richer layout than the base 5 files (type, expand, ics, processing, etc.); downstream projects extend rather than redeclare it.",
3358
+ recommendedTool: "dbx_model_validate_folder"
2990
3359
  }
2991
3360
  ];
2992
3361
 
@@ -4375,7 +4744,7 @@ function extractGroupModelNames(text) {
4375
4744
  while ((match = MODEL_NAME_RE.exec(text)) !== null) {
4376
4745
  seen.add(match[1]);
4377
4746
  }
4378
- return [...seen].sort((a, b) => a.localeCompare(b));
4747
+ return Array.from(seen).sort((a, b) => a.localeCompare(b));
4379
4748
  }
4380
4749
 
4381
4750
  // packages/dbx-cli/src/lib/mcp-scan/scan/_jsdoc-tagged-export/extract-base.ts
@@ -8124,7 +8493,7 @@ function collectTokensReadFromBody(body) {
8124
8493
  while ((match = CSS_VAR_REFERENCE_RE.exec(body)) !== null) {
8125
8494
  set.add(match[1]);
8126
8495
  }
8127
- return [...set].sort((a, b) => a.localeCompare(b));
8496
+ return Array.from(set).sort((a, b) => a.localeCompare(b));
8128
8497
  }
8129
8498
  function collectTokensSet(declarations) {
8130
8499
  const set = /* @__PURE__ */ new Set();
@@ -8133,7 +8502,7 @@ function collectTokensSet(declarations) {
8133
8502
  set.add(decl.property);
8134
8503
  }
8135
8504
  }
8136
- return [...set].sort((a, b) => a.localeCompare(b));
8505
+ return Array.from(set).sort((a, b) => a.localeCompare(b));
8137
8506
  }
8138
8507
 
8139
8508
  // packages/dbx-cli/src/lib/mcp-scan/scan/css-utilities-scan-config-schema.ts
@@ -9050,7 +9419,7 @@ async function discoverConventionalDirs(workspaceRoot) {
9050
9419
  found.add(rel);
9051
9420
  }
9052
9421
  }
9053
- return [...found];
9422
+ return Array.from(found);
9054
9423
  }
9055
9424
  function normaliseExplicitDirs(dirs) {
9056
9425
  const result = [];
@@ -9155,7 +9524,7 @@ async function detectCandidateClusters(absDir) {
9155
9524
  }
9156
9525
  } catch {
9157
9526
  }
9158
- return [...found];
9527
+ return Array.from(found);
9159
9528
  }
9160
9529
  function mergeClusters(...lists) {
9161
9530
  const seen = /* @__PURE__ */ new Set();
@@ -10216,11 +10585,18 @@ function analyzeSequence(input) {
10216
10585
  if (isSingleFieldQuery(buckets)) {
10217
10586
  return analyzeSingleField({ buckets, collection, scope, warnings });
10218
10587
  }
10588
+ if (scope === "COLLECTION" && isEqualityOnlySequence(buckets)) {
10589
+ warnings.push({ kind: "equality-only-composite-skipped", factoryName, fields: buckets.equalities.map((e) => e.fieldPath) });
10590
+ return { kind: "auto", warnings };
10591
+ }
10219
10592
  return analyzeMultiField({ buckets, sequenceEntries: sequence.entries, collection, scope, factoryName, warnings });
10220
10593
  }
10221
10594
  function isSingleFieldQuery(buckets) {
10222
10595
  return buckets.distinctFieldCount === 1;
10223
10596
  }
10597
+ function isEqualityOnlySequence(buckets) {
10598
+ return buckets.ranges.length === 0 && buckets.arrays.length === 0 && buckets.orderBys.length === 0 && buckets.equalities.length > 0 && buckets.equalities.every((e) => (e.operator ?? "==") === "==");
10599
+ }
10224
10600
  function analyzeSingleField(input) {
10225
10601
  const { buckets, collection, scope, warnings } = input;
10226
10602
  if (scope === "COLLECTION") {
@@ -10315,7 +10691,7 @@ function collectOrderByDirections(input) {
10315
10691
  }
10316
10692
  }
10317
10693
  for (const [field, dirs] of conflicts) {
10318
- warnings.push({ kind: "orderby-conflict", factoryName, field, directions: [...dirs] });
10694
+ warnings.push({ kind: "orderby-conflict", factoryName, field, directions: Array.from(dirs) });
10319
10695
  }
10320
10696
  return out;
10321
10697
  }
@@ -10778,7 +11154,7 @@ function composeEntry(input) {
10778
11154
  }
10779
11155
  function resolveConstraintSequences(input) {
10780
11156
  const { candidate, tags, name, line, filePath, warnings } = input;
10781
- const bodyResult = extractConstraintsFromBody({ decl: candidate.decl, factoryName: name, filePath, dispatcher: tags.dispatcher });
11157
+ const bodyResult = extractConstraintsFromBody({ decl: candidate.decl, factoryName: name, filePath, dispatcher: tags.dispatcher, suppressed: tags.skip || tags.specOnly });
10782
11158
  for (const warning of bodyResult.warnings) {
10783
11159
  warnings.push(warning);
10784
11160
  }
@@ -10859,11 +11235,14 @@ function buildConstraintSequences(input) {
10859
11235
  return sequences;
10860
11236
  }
10861
11237
  function extractConstraintsFromBody(input) {
10862
- const { decl, factoryName, filePath, dispatcher } = input;
11238
+ const { decl, factoryName, filePath, dispatcher, suppressed } = input;
10863
11239
  const entries = [];
10864
11240
  const conditionalFieldSet = /* @__PURE__ */ new Set();
10865
11241
  const warnings = [];
10866
11242
  const body = decl.getBody();
11243
+ if (suppressed) {
11244
+ return { entries, conditionalFields: [], warnings, skipped: true, dispatcherDelegates: [] };
11245
+ }
10867
11246
  if (dispatcher) {
10868
11247
  const violation = body === void 0 ? void 0 : findFirstConstraintCall(body);
10869
11248
  if (violation !== void 0) {
@@ -11584,6 +11963,9 @@ function formatModelFirebaseIndexBuildWarning(warning) {
11584
11963
  case "unsupported-array-contains-any":
11585
11964
  result = `${w.factoryName} field "${w.field}" uses array-contains-any \u2014 index support is partial`;
11586
11965
  break;
11966
+ case "equality-only-composite-skipped":
11967
+ result = `${w.factoryName} is equality-only on [${w.fields.join(", ")}] \u2014 no composite emitted, Firestore serves this by merging the automatic single-field indexes`;
11968
+ break;
11587
11969
  }
11588
11970
  }
11589
11971
  return result;
@@ -14171,13 +14553,13 @@ async function discoverClaimsFiles(cwd) {
14171
14553
  } catch {
14172
14554
  }
14173
14555
  }
14174
- return [...found].sort((a, b) => a.localeCompare(b));
14556
+ return Array.from(found).sort((a, b) => a.localeCompare(b));
14175
14557
  }
14176
14558
  function mergeAndNormalisePaths(discovered, extra) {
14177
14559
  const out = /* @__PURE__ */ new Set();
14178
14560
  for (const p of discovered) out.add(p);
14179
14561
  for (const p of extra) out.add(toPosix(p));
14180
- return [...out].sort((a, b) => a.localeCompare(b));
14562
+ return Array.from(out).sort((a, b) => a.localeCompare(b));
14181
14563
  }
14182
14564
  function toPosix(value) {
14183
14565
  return value.split(sep4).join("/");
@@ -14827,12 +15209,13 @@ function pushInto13(map, key, entry) {
14827
15209
  var DEFAULT_BIN_NAME = "dbx-cli-generate-firestore-indexes";
14828
15210
  function buildUsage(binName) {
14829
15211
  return [
14830
- `Usage: ${binName} --component <dir> [--output <path>] [--check] [--json] [--help]`,
15212
+ `Usage: ${binName} --component <dir> [--component <dir> ...] [--output <path>] [--check] [--json] [--help]`,
14831
15213
  "",
14832
15214
  "Generates `firestore.indexes.json` from `@dbxModelFirebaseIndex`-tagged factories.",
14833
15215
  "",
14834
15216
  "Options:",
14835
- " --component <dir> Required. Relative path to the `-firebase` component package.",
15217
+ " --component <dir> Required, repeatable. Relative path to a `-firebase` component or package.",
15218
+ " Repeat to derive one indexes file from several packages at once.",
14836
15219
  " --output <path> Output path. Defaults to `firestore.indexes.json` at the cwd.",
14837
15220
  " --check Compare against the on-disk file; exit 1 on drift, do not write.",
14838
15221
  " --json Print the diff summary as JSON instead of human-readable text.",
@@ -14852,23 +15235,40 @@ async function runGenerateFirestoreIndexesCli(input) {
14852
15235
  stderr(usage);
14853
15236
  return { exitCode: 2 };
14854
15237
  }
14855
- if (parsed.component === void 0) {
15238
+ if (parsed.components.length === 0) {
14856
15239
  stderr("generate-firestore-indexes: --component is required");
14857
15240
  stderr(usage);
14858
15241
  return { exitCode: 2 };
14859
15242
  }
14860
- const componentAbs = resolve26(cwd, parsed.component);
14861
15243
  const outputAbs = resolve26(cwd, parsed.output);
14862
- const buildOutcome = await buildModelFirebaseIndexManifest({
14863
- projectRoot: componentAbs,
14864
- generator
14865
- });
14866
- if (buildOutcome.kind !== "success") {
14867
- stderr(formatBuildFailure(buildOutcome));
15244
+ const entries = [];
15245
+ const loadedSources = [];
15246
+ let sawUnresolvedModel = false;
15247
+ for (const component of parsed.components) {
15248
+ const buildOutcome = await buildModelFirebaseIndexManifest({
15249
+ projectRoot: resolve26(cwd, component),
15250
+ generator
15251
+ });
15252
+ if (buildOutcome.kind !== "success") {
15253
+ stderr(formatBuildFailure(buildOutcome));
15254
+ return { exitCode: 1 };
15255
+ }
15256
+ for (const warning of buildOutcome.extractWarnings) {
15257
+ stderr(`${warning.stage}-warning: ${formatModelFirebaseIndexBuildWarning(warning)}`);
15258
+ if (warning.stage === "extract" && warning.warning.kind === "unresolved-model") {
15259
+ sawUnresolvedModel = true;
15260
+ }
15261
+ }
15262
+ for (const entry of buildOutcome.manifest.entries) {
15263
+ entries.push(toModelFirebaseIndexEntryInfo(entry));
15264
+ }
15265
+ loadedSources.push(buildOutcome.manifest.source);
15266
+ }
15267
+ if (sawUnresolvedModel) {
15268
+ stderr("generate-firestore-indexes: one or more @dbxModelFirebaseIndexModel tags could not be resolved, so their indexes were dropped. Add the missing identity file to the component\u2019s `dbx-mcp.scan.json` include globs.");
14868
15269
  return { exitCode: 1 };
14869
15270
  }
14870
- const entries = buildOutcome.manifest.entries.map(toModelFirebaseIndexEntryInfo);
14871
- const registry = createModelFirebaseIndexRegistryFromEntries({ entries, loadedSources: [buildOutcome.manifest.source] });
15271
+ const registry = createModelFirebaseIndexRegistryFromEntries({ entries, loadedSources });
14872
15272
  const existingJson = await readExistingIndexes({ outputAbs, readFile: readFile33, stderr });
14873
15273
  const { json, diff } = generateFirestoreIndexesJson({ entries: registry.all, existingJson });
14874
15274
  const serialized = serializeFirestoreIndexesJson(json);
@@ -14891,7 +15291,7 @@ async function runGenerateFirestoreIndexesCli(input) {
14891
15291
  return { exitCode: 0 };
14892
15292
  }
14893
15293
  function parseArgv(argv) {
14894
- let component;
15294
+ const components = [];
14895
15295
  let output = "firestore.indexes.json";
14896
15296
  let check = false;
14897
15297
  let json = false;
@@ -14906,7 +15306,7 @@ function parseArgv(argv) {
14906
15306
  if (i >= argv.length) {
14907
15307
  error = "generate-firestore-indexes: --component requires a value";
14908
15308
  } else {
14909
- component = argv[i];
15309
+ components.push(argv[i]);
14910
15310
  }
14911
15311
  break;
14912
15312
  case "--output":
@@ -14933,7 +15333,7 @@ function parseArgv(argv) {
14933
15333
  }
14934
15334
  i += 1;
14935
15335
  }
14936
- return { component, output, check, json, help, error };
15336
+ return { components, output, check, json, help, error };
14937
15337
  }
14938
15338
  async function readExistingIndexes(input) {
14939
15339
  const text = await readExistingIndexesText(input);
@@ -16350,7 +16750,7 @@ function warnDroppedFutureStates(tree, realNames, warnings) {
16350
16750
  continue;
16351
16751
  }
16352
16752
  const prefix = node.data.name.slice(0, -3);
16353
- const hasRealSubtree = realNames.has(prefix) || [...realNames].some((name) => name.startsWith(`${prefix}.`));
16753
+ const hasRealSubtree = realNames.has(prefix) || Array.from(realNames).some((name) => name.startsWith(`${prefix}.`));
16354
16754
  if (!hasRealSubtree) {
16355
16755
  warnings.push({ kind: "dropped-future-state", severity: "warning", message: `Future state \`${node.data.name}\` was dropped and has no real subtree under \`${prefix}\`; its page will not match any URL.`, stateName: node.data.name });
16356
16756
  }
@@ -19044,9 +19444,9 @@ function scanFirestoreRules(source) {
19044
19444
  if (allow.ops.has("list") || allow.ops.has("read")) current.list = mergeAccess(current.list, allow.access);
19045
19445
  }
19046
19446
  });
19047
- const collections = [...accumulated.entries()].map(([collection, value]) => ({
19447
+ const collections = Array.from(accumulated.entries()).map(([collection, value]) => ({
19048
19448
  collection,
19049
- paths: [...value.paths].sort(),
19449
+ paths: Array.from(value.paths).sort(),
19050
19450
  get: value.get,
19051
19451
  list: value.list,
19052
19452
  collectionGroup: value.collectionGroup,
@@ -21958,7 +22358,7 @@ function formatDownstreamSection(downstream) {
21958
22358
  bucket.push(model);
21959
22359
  byPackage.set(model.sourcePackage, bucket);
21960
22360
  }
21961
- const packageNames = [...byPackage.keys()].sort((a, b) => a.localeCompare(b));
22361
+ const packageNames = Array.from(byPackage.keys()).sort((a, b) => a.localeCompare(b));
21962
22362
  for (const pkg of packageNames) {
21963
22363
  lines.push(`### \`${pkg}\``, "");
21964
22364
  const bucket = byPackage.get(pkg) ?? [];
@@ -28680,13 +29080,18 @@ function readJsDocSummary(node) {
28680
29080
  }
28681
29081
 
28682
29082
  // packages/dbx-cli/manifest-extract/src/lib/extract-models.ts
28683
- import { Node as Node24, Project as Project9 } from "ts-morph";
29083
+ import { Node as Node24, SyntaxKind as SyntaxKind10, Project as Project9 } from "ts-morph";
28684
29084
  var READ_LEVEL_VALUES2 = /* @__PURE__ */ new Set(["system", "owner", "admin-only", "permissions"]);
28685
29085
  var SERVICE_FACTORY_TAG = "dbxModelServiceFactory";
28686
29086
  var MCP_TOOL_NAME_SEGMENT_TAG = "dbxModelMcpToolNameSegment";
28687
29087
  var MODEL_TYPE_VALUE_PATTERN2 = /^[a-z][A-Za-z0-9_$]*$/;
28688
29088
  var TOOL_NAME_SEGMENT_PATTERN = /^[A-Za-z][A-Za-z0-9_$]*$/;
28689
29089
  var IDENTITY_FN = "firestoreModelIdentity";
29090
+ var SINGLE_ITEM_COLLECTION_FN = "singleItemFirestoreCollection";
29091
+ var ROOT_SINGLE_ITEM_COLLECTION_FN = "rootSingleItemFirestoreCollection";
29092
+ var SINGLE_ITEM_COLLECTION_FN_NAMES = [SINGLE_ITEM_COLLECTION_FN, ROOT_SINGLE_ITEM_COLLECTION_FN];
29093
+ var MODEL_IDENTITY_KEY = "modelIdentity";
29094
+ var SINGLE_ITEM_IDENTIFIER_KEY = "singleItemIdentifier";
28690
29095
  var CONVERTER_FN_NAMES = ["snapshotConverterFunctions", "firestoreSubObject", "firestoreObjectArray"];
28691
29096
  var SUB_OBJECT_FN = "firestoreSubObject";
28692
29097
  var OBJECT_ARRAY_FN = "firestoreObjectArray";
@@ -28703,7 +29108,9 @@ function extractModelsFromSource(input) {
28703
29108
  const enums = readEnums(sourceFile);
28704
29109
  const modelGroups = readModelGroups(sourceFile);
28705
29110
  const serviceFactories = readServiceFactories(sourceFile);
28706
- return { identities, interfaces, converters, enums, modelGroups, serviceFactories };
29111
+ const singleItemCollections = readSingleItemCollections(sourceFile);
29112
+ const stringConstants = readStringConstants(sourceFile);
29113
+ return { identities, interfaces, converters, enums, modelGroups, serviceFactories, singleItemCollections, stringConstants };
28707
29114
  }
28708
29115
  function readIdentities(sourceFile) {
28709
29116
  const out = [];
@@ -28823,6 +29230,65 @@ function readServiceFactoryModelType(jsDocs) {
28823
29230
  }
28824
29231
  return result;
28825
29232
  }
29233
+ function readSingleItemCollections(sourceFile) {
29234
+ const out = [];
29235
+ const text = sourceFile.getFullText();
29236
+ if (SINGLE_ITEM_COLLECTION_FN_NAMES.some((name) => text.includes(name))) {
29237
+ for (const call of sourceFile.getDescendantsOfKind(SyntaxKind10.CallExpression)) {
29238
+ const fnName = readCalleeName(call);
29239
+ if (fnName !== SINGLE_ITEM_COLLECTION_FN && fnName !== ROOT_SINGLE_ITEM_COLLECTION_FN) continue;
29240
+ const entry = buildSingleItemCollection(call, fnName === ROOT_SINGLE_ITEM_COLLECTION_FN);
29241
+ if (entry) out.push(entry);
29242
+ }
29243
+ }
29244
+ return out;
29245
+ }
29246
+ function readCalleeName(call) {
29247
+ const expression = call.getExpression();
29248
+ return Node24.isPropertyAccessExpression(expression) ? expression.getName() : expression.getText();
29249
+ }
29250
+ function buildSingleItemCollection(call, root) {
29251
+ let result;
29252
+ const args = call.getArguments();
29253
+ if (args.length > 0) {
29254
+ const config = args[0];
29255
+ if (Node24.isObjectLiteralExpression(config)) {
29256
+ const identityNode = readPropertyValue(config, MODEL_IDENTITY_KEY);
29257
+ if (identityNode && Node24.isIdentifier(identityNode)) {
29258
+ const identifierNode = readPropertyValue(config, SINGLE_ITEM_IDENTIFIER_KEY);
29259
+ result = {
29260
+ identityConst: identityNode.getText(),
29261
+ root,
29262
+ documentId: readStringLiteralText(identifierNode),
29263
+ documentIdConstRef: identifierNode && Node24.isIdentifier(identifierNode) ? identifierNode.getText() : void 0,
29264
+ explicitIdentifier: config.getProperty(SINGLE_ITEM_IDENTIFIER_KEY) !== void 0,
29265
+ line: call.getStartLineNumber()
29266
+ };
29267
+ }
29268
+ }
29269
+ }
29270
+ return result;
29271
+ }
29272
+ function readStringConstants(sourceFile) {
29273
+ const out = [];
29274
+ for (const statement of sourceFile.getVariableStatements()) {
29275
+ if (!statement.isExported()) continue;
29276
+ for (const decl of statement.getDeclarations()) {
29277
+ const value = readStringLiteralText(decl.getInitializer());
29278
+ if (value !== void 0) {
29279
+ out.push({ name: decl.getName(), value });
29280
+ }
29281
+ }
29282
+ }
29283
+ return out;
29284
+ }
29285
+ function readStringLiteralText(node) {
29286
+ let current = node;
29287
+ while (current !== void 0 && Node24.isAsExpression(current)) {
29288
+ current = current.getExpression();
29289
+ }
29290
+ return current !== void 0 && (Node24.isStringLiteral(current) || Node24.isNoSubstitutionTemplateLiteral(current)) ? current.getLiteralText() : void 0;
29291
+ }
28826
29292
  function readConverters(sourceFile) {
28827
29293
  const out = [];
28828
29294
  for (const statement of sourceFile.getVariableStatements()) {
@@ -29368,7 +29834,7 @@ function buildSummaries(entries, issues) {
29368
29834
  const summary = byModel.get(issue.model);
29369
29835
  if (summary) summary.errorCount += 1;
29370
29836
  }
29371
- return [...byModel.entries()].map(([model, s]) => ({ model, ...s })).sort((a, b) => a.model.localeCompare(b.model));
29837
+ return Array.from(byModel.entries()).map(([model, s]) => ({ model, ...s })).sort((a, b) => a.model.localeCompare(b.model));
29372
29838
  }
29373
29839
  function compareEntries(a, b) {
29374
29840
  return a.model.localeCompare(b.model) || a.verb.localeCompare(b.verb) || (a.specifier ?? "").localeCompare(b.specifier ?? "");
@@ -29444,7 +29910,7 @@ async function readComponentDereekbDeps(componentAbs) {
29444
29910
  addScopedDependencyNames(json[field], out);
29445
29911
  }
29446
29912
  }
29447
- return [...out];
29913
+ return Array.from(out);
29448
29914
  }
29449
29915
  function addScopedDependencyNames(field, out) {
29450
29916
  if (isRecord(field)) {
@@ -29804,7 +30270,7 @@ __export(dbx_asset_validate_app_exports, {
29804
30270
  import { Node as Node27, Project as Project12 } from "ts-morph";
29805
30271
 
29806
30272
  // packages/dbx-cli/validate/src/lib/_core/_validate/ast.ts
29807
- import { Node as Node26, Project as Project11, SyntaxKind as SyntaxKind10 } from "ts-morph";
30273
+ import { Node as Node26, Project as Project11, SyntaxKind as SyntaxKind11 } from "ts-morph";
29808
30274
  var COMPONENT_VIRTUAL_PREFIX = "__component__/";
29809
30275
  var API_VIRTUAL_PREFIX = "__api__/";
29810
30276
  // @__NO_SIDE_EFFECTS__
@@ -29906,7 +30372,7 @@ function findLocalVariable(sf, name) {
29906
30372
  if (decl.getName() === name) return decl;
29907
30373
  }
29908
30374
  }
29909
- for (const decl of sf.getDescendantsOfKind(SyntaxKind10.VariableDeclaration)) {
30375
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind11.VariableDeclaration)) {
29910
30376
  if (decl.getName() === name) return decl;
29911
30377
  }
29912
30378
  return void 0;
@@ -29916,7 +30382,7 @@ function collectTypeofReferences(node, out) {
29916
30382
  out.push(node.getExprName().getText());
29917
30383
  return;
29918
30384
  }
29919
- for (const tq of node.getDescendantsOfKind(SyntaxKind10.TypeQuery)) {
30385
+ for (const tq of node.getDescendantsOfKind(SyntaxKind11.TypeQuery)) {
29920
30386
  out.push(tq.getExprName().getText());
29921
30387
  }
29922
30388
  }
@@ -30607,7 +31073,7 @@ __export(notification_m_validate_app_exports, {
30607
31073
  });
30608
31074
 
30609
31075
  // packages/dbx-cli/validate/src/lib/notification-m-validate-app/extract.ts
30610
- import { Node as Node28, SyntaxKind as SyntaxKind11 } from "ts-morph";
31076
+ import { Node as Node28, SyntaxKind as SyntaxKind12 } from "ts-morph";
30611
31077
  var NOTIF_TEMPLATE_TYPE = "NotificationTemplateType";
30612
31078
  var NOTIF_TEMPLATE_TYPE_INFO = "NotificationTemplateTypeInfo";
30613
31079
  var NOTIF_TEMPLATE_TYPE_INFO_ARRAY = "NotificationTemplateTypeInfo[]";
@@ -30877,7 +31343,7 @@ function tryReadTemplateInfoRecord(decl, rel, index) {
30877
31343
  symbolName: decl.getName(),
30878
31344
  directInfoIdentifiers: direct,
30879
31345
  spreadAggregateIdentifiers: spreads,
30880
- resolvedInfoIdentifiers: [...resolved],
31346
+ resolvedInfoIdentifiers: Array.from(resolved),
30881
31347
  unresolvedSpreadIdentifiers: unresolved,
30882
31348
  sourceFile: rel
30883
31349
  };
@@ -30914,7 +31380,7 @@ function extractTemplateInfoRecordWiring(sources) {
30914
31380
  let result;
30915
31381
  outer: for (const sf of sources) {
30916
31382
  const rel = apiRelPath(sf);
30917
- for (const call of sf.getDescendantsOfKind(SyntaxKind11.CallExpression)) {
31383
+ for (const call of sf.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
30918
31384
  if (call.getExpression().getText() !== TEMPLATE_INFO_RECORD_SERVICE) continue;
30919
31385
  const args = call.getArguments();
30920
31386
  const first = args[0];
@@ -30934,7 +31400,7 @@ function extractTemplateConfigsArrayWiring(sources) {
30934
31400
  let result;
30935
31401
  outer: for (const sf of sources) {
30936
31402
  const rel = apiRelPath(sf);
30937
- for (const obj of sf.getDescendantsOfKind(SyntaxKind11.ObjectLiteralExpression)) {
31403
+ for (const obj of sf.getDescendantsOfKind(SyntaxKind12.ObjectLiteralExpression)) {
30938
31404
  const provideIdent = readIdentifierProperty(obj, "provide");
30939
31405
  if (provideIdent !== TEMPLATE_CONFIGS_ARRAY_TOKEN) continue;
30940
31406
  const useFactoryIdent = readIdentifierProperty(obj, "useFactory");
@@ -31128,7 +31594,7 @@ function extractTaskServiceCalls(sources, index, trustedExternal) {
31128
31594
  const out = [];
31129
31595
  for (const sf of sources) {
31130
31596
  const rel = apiRelPath(sf);
31131
- for (const call of sf.getDescendantsOfKind(SyntaxKind11.CallExpression)) {
31597
+ for (const call of sf.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
31132
31598
  const expr = call.getExpression();
31133
31599
  if (!Node28.isIdentifier(expr) || expr.getText() !== TASK_SERVICE_FACTORY) continue;
31134
31600
  const args = call.getArguments();
@@ -31315,7 +31781,7 @@ function extractTaskHandlerEntries(sources) {
31315
31781
  const seenSymbols = /* @__PURE__ */ new Set();
31316
31782
  for (const sf of sources) {
31317
31783
  const rel = apiRelPath(sf);
31318
- for (const decl of sf.getDescendantsOfKind(SyntaxKind11.VariableDeclaration)) {
31784
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind12.VariableDeclaration)) {
31319
31785
  const entry = tryReadTaskHandlerEntry(decl, rel, seenSymbols);
31320
31786
  if (entry) {
31321
31787
  out.push(entry);
@@ -31994,7 +32460,7 @@ __export(storagefile_m_validate_app_exports, {
31994
32460
  });
31995
32461
 
31996
32462
  // packages/dbx-cli/validate/src/lib/storagefile-m-validate-app/extract.ts
31997
- import { Node as Node29, SyntaxKind as SyntaxKind12 } from "ts-morph";
32463
+ import { Node as Node29, SyntaxKind as SyntaxKind13 } from "ts-morph";
31998
32464
 
31999
32465
  // packages/dbx-cli/validate/src/lib/storagefile-m-validate-app/group-ids.ts
32000
32466
  var GROUP_IDS_FUNCTION_SUFFIXES = ["StorageFileGroupIds", "FileGroupIds"];
@@ -32138,7 +32604,7 @@ function extractUploadInitializerEntries(sources) {
32138
32604
  const out = [];
32139
32605
  for (const sf of sources) {
32140
32606
  const rel = apiRelPath(sf);
32141
- for (const decl of sf.getDescendantsOfKind(SyntaxKind12.VariableDeclaration)) {
32607
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind13.VariableDeclaration)) {
32142
32608
  const typeText = typeAnnotationText(decl);
32143
32609
  if (typeText !== UPLOAD_SERVICE_INITIALIZER_TYPE) continue;
32144
32610
  const obj = asObjectLiteral(decl.getInitializer());
@@ -32303,7 +32769,7 @@ function extractUploadServiceCalls(sources, index) {
32303
32769
  const out = [];
32304
32770
  for (const sf of sources) {
32305
32771
  const rel = apiRelPath(sf);
32306
- for (const call of sf.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
32772
+ for (const call of sf.getDescendantsOfKind(SyntaxKind13.CallExpression)) {
32307
32773
  const expr = call.getExpression();
32308
32774
  if (!Node29.isIdentifier(expr) || expr.getText() !== UPLOAD_SERVICE_FACTORY) continue;
32309
32775
  const args = call.getArguments();
@@ -32380,7 +32846,7 @@ function extractUploadServiceWirings(sources) {
32380
32846
  const out = [];
32381
32847
  for (const sf of sources) {
32382
32848
  const rel = apiRelPath(sf);
32383
- for (const obj of sf.getDescendantsOfKind(SyntaxKind12.ObjectLiteralExpression)) {
32849
+ for (const obj of sf.getDescendantsOfKind(SyntaxKind13.ObjectLiteralExpression)) {
32384
32850
  const provideIdent = readIdentifierProperty(obj, "provide");
32385
32851
  if (provideIdent !== UPLOAD_SERVICE_PROVIDE_TOKEN) continue;
32386
32852
  const useFactory = readIdentifierProperty(obj, "useFactory");
@@ -32393,7 +32859,7 @@ function extractProcessingConfigs(sources) {
32393
32859
  const out = [];
32394
32860
  for (const sf of sources) {
32395
32861
  const rel = apiRelPath(sf);
32396
- for (const decl of sf.getDescendantsOfKind(SyntaxKind12.VariableDeclaration)) {
32862
+ for (const decl of sf.getDescendantsOfKind(SyntaxKind13.VariableDeclaration)) {
32397
32863
  const config = extractProcessingConfigFromDecl(decl, rel);
32398
32864
  if (config) {
32399
32865
  out.push(config);
@@ -32437,7 +32903,7 @@ function extractProcessingHandlerCalls(sources) {
32437
32903
  const out = [];
32438
32904
  for (const sf of sources) {
32439
32905
  const rel = apiRelPath(sf);
32440
- for (const call of sf.getDescendantsOfKind(SyntaxKind12.CallExpression)) {
32906
+ for (const call of sf.getDescendantsOfKind(SyntaxKind13.CallExpression)) {
32441
32907
  const expr = call.getExpression();
32442
32908
  if (!Node29.isIdentifier(expr) || expr.getText() !== PROCESSING_HANDLER_FACTORY) continue;
32443
32909
  const args = call.getArguments();
@@ -32657,7 +33123,7 @@ function flagUploadServiceWiring(extracted, violations) {
32657
33123
  if (!anyWired) {
32658
33124
  pushViolation9(violations, {
32659
33125
  code: "STORAGEFILE_UPLOAD_SERVICE_NOT_WIRED",
32660
- message: `No NestJS provider with \`provide: StorageFileInitializeFromUploadService, useFactory: ${factoryNames.size > 0 ? [...factoryNames].join(" | ") : "<storage-file-upload-factory>"}\` found. Bind the factory function in a NestJS module.`,
33126
+ message: `No NestJS provider with \`provide: StorageFileInitializeFromUploadService, useFactory: ${factoryNames.size > 0 ? Array.from(factoryNames).join(" | ") : "<storage-file-upload-factory>"}\` found. Bind the factory function in a NestJS module.`,
32661
33127
  side: "api",
32662
33128
  file: void 0
32663
33129
  });
@@ -33833,7 +34299,7 @@ function toPosix2(p) {
33833
34299
  }
33834
34300
 
33835
34301
  // packages/dbx-cli/model-test/src/lib/test/extract.ts
33836
- import { Node as Node31, Project as Project14, SyntaxKind as SyntaxKind13 } from "ts-morph";
34302
+ import { Node as Node31, Project as Project14, SyntaxKind as SyntaxKind14 } from "ts-morph";
33837
34303
  var SPEC_FILE_VIRTUAL_PATH = "__spec__/spec.ts";
33838
34304
  var FIXTURE_CONTEXT_SUFFIX = "Context";
33839
34305
  var FIXTURE_FACTORY_SUFFIX = "ContextFactory";
@@ -33919,7 +34385,7 @@ function collectFixtureImports(sourceFile) {
33919
34385
  seen.add(name);
33920
34386
  }
33921
34387
  }
33922
- return [...seen];
34388
+ return Array.from(seen);
33923
34389
  }
33924
34390
  function matchesFixtureModulePath(spec) {
33925
34391
  return /(^|\/)test\/fixture(\.[a-z]+)?$/.test(spec);
@@ -33951,7 +34417,7 @@ function trimToCamelBoundary(s) {
33951
34417
  return s;
33952
34418
  }
33953
34419
  function dedupedSorted(names) {
33954
- return [...new Set(names)].sort((a, b) => a.localeCompare(b));
34420
+ return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b));
33955
34421
  }
33956
34422
  function walkCall(call, ctx) {
33957
34423
  const calleeName = getCalleeName(call);
@@ -34161,7 +34627,7 @@ function appendHelperIfUsesDescribeOrIt(input) {
34161
34627
  function scanForDescribeOrIt(node) {
34162
34628
  const usage = { emitsDescribe: false, emitsIt: false };
34163
34629
  node.forEachDescendant((descendant) => {
34164
- if (descendant.getKind() !== SyntaxKind13.CallExpression) return;
34630
+ if (descendant.getKind() !== SyntaxKind14.CallExpression) return;
34165
34631
  const call = descendant;
34166
34632
  const expr = call.getExpression();
34167
34633
  if (!Node31.isIdentifier(expr)) return;
@@ -34180,7 +34646,7 @@ import { readFile as readFile14 } from "node:fs/promises";
34180
34646
  import { join as join15 } from "node:path";
34181
34647
 
34182
34648
  // packages/dbx-cli/model-test/src/lib/fixture/extract.ts
34183
- import { Node as Node32, Project as Project15, SyntaxKind as SyntaxKind14 } from "ts-morph";
34649
+ import { Node as Node32, Project as Project15, SyntaxKind as SyntaxKind15 } from "ts-morph";
34184
34650
 
34185
34651
  // packages/dbx-cli/model-test/src/lib/fixture/archetype.ts
34186
34652
  function classifyFixtureArchetype(input) {
@@ -34557,7 +35023,7 @@ function readParamsAccessFieldName(fn) {
34557
35023
  if (!Node32.isArrowFunction(fn) && !Node32.isFunctionExpression(fn)) return void 0;
34558
35024
  const body = fn.getBody();
34559
35025
  if (!body) return void 0;
34560
- for (const access2 of body.getDescendantsOfKind(SyntaxKind14.PropertyAccessExpression)) {
35026
+ for (const access2 of body.getDescendantsOfKind(SyntaxKind15.PropertyAccessExpression)) {
34561
35027
  const expr = access2.getExpression();
34562
35028
  if (Node32.isIdentifier(expr) && expr.getText() === "params") {
34563
35029
  return access2.getName();
@@ -34612,7 +35078,7 @@ function collectAllModels(fixtures, instances) {
34612
35078
  const all = /* @__PURE__ */ new Set();
34613
35079
  for (const k of fixtures.keys()) all.add(k);
34614
35080
  for (const k of instances.keys()) all.add(k);
34615
- const list = [...all];
35081
+ const list = Array.from(all);
34616
35082
  list.sort((a, b) => {
34617
35083
  const aLine = (fixtures.get(a) ?? instances.get(a))?.getStartLineNumber() ?? 0;
34618
35084
  const bLine = (fixtures.get(b) ?? instances.get(b))?.getStartLineNumber() ?? 0;
@@ -34647,8 +35113,8 @@ function readMethod(m) {
34647
35113
  return result;
34648
35114
  }
34649
35115
  function readVisibility(m) {
34650
- if (m.hasModifier(SyntaxKind14.PrivateKeyword)) return "private";
34651
- if (m.hasModifier(SyntaxKind14.ProtectedKeyword)) return "protected";
35116
+ if (m.hasModifier(SyntaxKind15.PrivateKeyword)) return "private";
35117
+ if (m.hasModifier(SyntaxKind15.ProtectedKeyword)) return "protected";
34652
35118
  return "public";
34653
35119
  }
34654
35120
  function readExtendsGenerics(cls) {
@@ -34666,7 +35132,7 @@ function collectIdentityImports(sourceFile) {
34666
35132
  }
34667
35133
  }
34668
35134
  }
34669
- const list = [...out];
35135
+ const list = Array.from(out);
34670
35136
  list.sort((a, b) => a.localeCompare(b));
34671
35137
  return list;
34672
35138
  }
@@ -36290,7 +36756,7 @@ import { join as join20, relative as relative16, sep as sep14 } from "node:path"
36290
36756
  // packages/dbx-cli/validate/src/lib/model-api-lookup/extract-actions.ts
36291
36757
  import { readFile as readFile19 } from "node:fs/promises";
36292
36758
  import { join as join19, relative as relative15, sep as sep13 } from "node:path";
36293
- import { Project as Project17, SyntaxKind as SyntaxKind15 } from "ts-morph";
36759
+ import { Project as Project17, SyntaxKind as SyntaxKind16 } from "ts-morph";
36294
36760
  var ACTION_SERVER_SUFFIX = ".action.server.ts";
36295
36761
  var COMMON_MODEL_SUBPATH = "src/app/common/model";
36296
36762
  async function buildActionLookup(apiAbs) {
@@ -36363,7 +36829,7 @@ function collectFactoryFunctions(input) {
36363
36829
  }
36364
36830
  }
36365
36831
  function findValidatorArgInBody(fn) {
36366
- for (const call of fn.getDescendantsOfKind(SyntaxKind15.CallExpression)) {
36832
+ for (const call of fn.getDescendantsOfKind(SyntaxKind16.CallExpression)) {
36367
36833
  const expr = call.getExpression();
36368
36834
  const exprText = expr.getText();
36369
36835
  if (!exprText.endsWith("firebaseServerActionTransformFunctionFactory")) continue;
@@ -37586,7 +38052,7 @@ async function readFileIfExists2(absPath) {
37586
38052
  }
37587
38053
 
37588
38054
  // packages/dbx-cli/validate/src/lib/dbx-color-template-list-app/extract.ts
37589
- import { Node as Node35, Project as Project19, SyntaxKind as SyntaxKind16 } from "ts-morph";
38055
+ import { Node as Node35, Project as Project19, SyntaxKind as SyntaxKind17 } from "ts-morph";
37590
38056
  var PROVIDE_FN_NAME = "provideDbxStyleService";
37591
38057
  var COLOR_SERVICE_CONFIG_PROP = "dbxColorServiceConfig";
37592
38058
  var TEMPLATES_PROP = "templates";
@@ -37612,7 +38078,7 @@ function extractColorTemplates(inspection) {
37612
38078
  }
37613
38079
  function findProvideCall(sf) {
37614
38080
  let result;
37615
- for (const call of sf.getDescendantsOfKind(SyntaxKind16.CallExpression)) {
38081
+ for (const call of sf.getDescendantsOfKind(SyntaxKind17.CallExpression)) {
37616
38082
  const callee = call.getExpression();
37617
38083
  if (Node35.isIdentifier(callee) && callee.getText() === PROVIDE_FN_NAME) {
37618
38084
  result = call;
@@ -37710,9 +38176,9 @@ function parseConfig(ctx, sf, obj) {
37710
38176
  function assignConfigField(input) {
37711
38177
  const { ctx, sf, result, name, value } = input;
37712
38178
  if (name === "tonal") {
37713
- if (value.getKind() === SyntaxKind16.TrueKeyword) {
38179
+ if (value.getKind() === SyntaxKind17.TrueKeyword) {
37714
38180
  result.tonal = true;
37715
- } else if (value.getKind() === SyntaxKind16.FalseKeyword) {
38181
+ } else if (value.getKind() === SyntaxKind17.FalseKeyword) {
37716
38182
  result.tonal = false;
37717
38183
  } else {
37718
38184
  ctx.warnings.push(buildWarning(sf, value, `Template config field \`tonal\` is not a boolean literal; ignored.`));
@@ -37831,7 +38297,7 @@ __export(dbx_color_smell_check_exports, {
37831
38297
  });
37832
38298
 
37833
38299
  // packages/dbx-cli/validate/src/lib/dbx-color-smell-check/extract.ts
37834
- import { Node as Node36, Project as Project20, SyntaxKind as SyntaxKind17 } from "ts-morph";
38300
+ import { Node as Node36, Project as Project20, SyntaxKind as SyntaxKind18 } from "ts-morph";
37835
38301
  var COLOR_INPUT_NAMES = /* @__PURE__ */ new Set(["color", "dbxColor", "dbxTextColor"]);
37836
38302
  var COLOR_TYPE_NAMES = /* @__PURE__ */ new Set(["DbxColorConfig", "DbxColorInput", "Maybe<DbxColorInput>", "Maybe<DbxColorConfig>"]);
37837
38303
  var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set(["template", "color", "contrast", "tone", "tonal"]);
@@ -37839,7 +38305,7 @@ function extractTsLiterals(filePath, text) {
37839
38305
  const project = new Project20({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
37840
38306
  const sf = project.createSourceFile(filePath, text, { overwrite: true });
37841
38307
  const out = [];
37842
- for (const obj of sf.getDescendantsOfKind(SyntaxKind17.ObjectLiteralExpression)) {
38308
+ for (const obj of sf.getDescendantsOfKind(SyntaxKind18.ObjectLiteralExpression)) {
37843
38309
  if (!isInColorPosition(obj)) continue;
37844
38310
  const literal = parseObjectLiteral({ filePath, sf, obj });
37845
38311
  if (literal !== void 0) out.push(literal);
@@ -37905,8 +38371,8 @@ function parseObjectLiteral(input) {
37905
38371
  function assignRawField(input) {
37906
38372
  const { raw, name, value, onDynamic } = input;
37907
38373
  if (name === "tonal") {
37908
- if (value.getKind() === SyntaxKind17.TrueKeyword) raw.tonal = true;
37909
- else if (value.getKind() === SyntaxKind17.FalseKeyword) raw.tonal = false;
38374
+ if (value.getKind() === SyntaxKind18.TrueKeyword) raw.tonal = true;
38375
+ else if (value.getKind() === SyntaxKind18.FalseKeyword) raw.tonal = false;
37910
38376
  else onDynamic();
37911
38377
  return;
37912
38378
  }
@@ -41667,7 +42133,7 @@ function collectConflicts(extraction, rendered) {
41667
42133
  if (e.factoryName === rendered.factoryName) out.push(rendered.factoryName);
41668
42134
  if (e.singletonName === rendered.singletonName) out.push(rendered.singletonName);
41669
42135
  }
41670
- return [...new Set(out)];
42136
+ return Array.from(new Set(out));
41671
42137
  }
41672
42138
  var MODEL_FIXTURE_SCAFFOLD_TOOL = { definition: TOOL7, run: run6 };
41673
42139
 
@@ -43973,7 +44439,7 @@ function buildRemoteBase(args) {
43973
44439
  return { fragment, imports: buildImportLines(importsSet), notes };
43974
44440
  }
43975
44441
  function buildImportLines(symbols) {
43976
- const sorted = [...symbols].sort((a, b) => a.localeCompare(b));
44442
+ const sorted = Array.from(symbols).sort((a, b) => a.localeCompare(b));
43977
44443
  const result = [`import { ${sorted.join(", ")} } from '@dereekb/rxjs';`];
43978
44444
  return result;
43979
44445
  }
@@ -51217,7 +51683,7 @@ function groupBySource(entries) {
51217
51683
  bucket.push(entry);
51218
51684
  }
51219
51685
  }
51220
- return [...map.entries()].sort(([a], [b]) => a.localeCompare(b));
51686
+ return Array.from(map.entries()).sort(([a], [b]) => a.localeCompare(b));
51221
51687
  }
51222
51688
  var EXPLAIN_RULE_TOOL = { definition: TOOL16, run: run17 };
51223
51689
 
@@ -52129,7 +52595,7 @@ async function scanModelFacts(input) {
52129
52595
  }
52130
52596
  }
52131
52597
  }
52132
- return { interfaces: [...interfaces.values()], identities: [...identities.values()] };
52598
+ return { interfaces: Array.from(interfaces.values()), identities: Array.from(identities.values()) };
52133
52599
  }
52134
52600
  async function walkTypeScriptFiles(dir) {
52135
52601
  const out = [];
@@ -52152,7 +52618,7 @@ async function walkTypeScriptFiles(dir) {
52152
52618
  return out;
52153
52619
  }
52154
52620
  function readManifestModelTypes(source) {
52155
- return [...source.matchAll(/modelType:\s*'([^']+)'/g)].map((m) => m[1]);
52621
+ return Array.from(source.matchAll(/modelType:\s*'([^']+)'/g)).map((m) => m[1]);
52156
52622
  }
52157
52623
  async function readOptionalFile(path) {
52158
52624
  return readFile31(path, "utf8").catch(() => void 0);
@@ -53947,7 +54413,7 @@ function expandIntentQuery(query) {
53947
54413
  if (trimmed.length === 0) {
53948
54414
  result = [];
53949
54415
  } else {
53950
- result = [...collectSynonyms(trimmed)];
54416
+ result = Array.from(collectSynonyms(trimmed));
53951
54417
  }
53952
54418
  return result;
53953
54419
  }