@geekmidas/manifest 10.0.0-alpha.99 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,1196 +1,10 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
- //#region src/declaration.ts
25
- /**
26
- * The version used when a database names none.
27
- *
28
- * The point is not which number this is but that there is only one of them.
29
- * Local ran 18 while Aurora provisioned its own default of 17.7, and nothing in
30
- * any declaration recorded the difference — a stage could behave differently
31
- * from a developer's machine for a reason neither could see. Both now read
32
- * this.
33
- */
34
- const DEFAULT_POSTGRES_VERSION = 18;
35
- /**
36
- * What a `Telemetry` node provides to each process with an edge to it.
37
- *
38
- * `OTEL_SERVICE_NAME` is resolved per process — the app's name — so it is
39
- * listed here but composed by whichever target hands it over.
40
- */
41
- const TELEMETRY_KEYS = [
42
- "OTEL_EXPORTER_OTLP_ENDPOINT",
43
- "OTEL_EXPORTER_OTLP_HEADERS",
44
- "OTEL_SERVICE_NAME",
45
- "OTEL_TRACES_SAMPLER",
46
- "OTEL_TRACES_SAMPLER_ARG"
47
- ];
48
- /**
49
- * What each kind may derive from.
50
- *
51
- * Small enough to state exhaustively, and stating it makes cycles impossible
52
- * without a graph walk: readers are terminal, so no chain can return to its
53
- * start. There is no `writer` — the database *is* the writer, which is what
54
- * keeps a replica from being reached by accident.
55
- */
56
- const DERIVES_FROM = {
57
- "database-reader": ["database", "database-schema"],
58
- "database-schema": ["database"],
59
- "file-server": ["objects"],
60
- cache: ["database", "database-schema"]
61
- };
62
- /**
63
- * Which provided values may be shipped to a browser.
64
- *
65
- * Drives client-side prefixing (`VITE_`, `NEXT_PUBLIC_`) and nothing else — it
66
- * is not a restriction on what may be depended on, since a server-side consumer
67
- * can legitimately use any of them. A bucket's `url` presigns and stays private.
68
- */
69
- const PUBLIC = {
70
- objects: [],
71
- "file-server": ["url"],
72
- email: ["inboxUrl"],
73
- database: [],
74
- "database-reader": [],
75
- "database-schema": [],
76
- cache: [],
77
- secret: [],
78
- credential: [],
79
- encryption: [],
80
- "rest-api": ["url"],
81
- queue: [],
82
- topic: [],
83
- oidc: ["issuer", "audience"],
84
- "external-api": [],
85
- function: [],
86
- cron: [],
87
- "mobile-app": [],
88
- site: ["url"],
89
- worker: [],
90
- telemetry: []
91
- };
92
- //#endregion
93
- //#region src/errors.ts
94
- /**
95
- * Manifest errors.
96
- *
97
- * Messages state the rule, which is constant; the offending value is a field.
98
- * An interpolated message cannot be matched on, reads differently every time it
99
- * is thrown, and carries user input into every log line that touches it.
100
- */
101
- /** A construct id that cannot survive the names derived from it. */
102
- var InvalidConstructId = class extends Error {
103
- /** What was passed in. */
104
- input;
105
- /** What canonicalising it produced, which is what failed the rule. */
106
- canonical;
107
- constructor(input, canonical) {
108
- super("A construct id must start with a letter and contain only letters and digits");
109
- this.name = "InvalidConstructId";
110
- this.input = input;
111
- this.canonical = canonical;
112
- }
113
- };
114
- /** A derived construct naming a parent the manifest does not contain. */
115
- var UnknownParent = class extends Error {
116
- /** The derived construct. */
117
- id;
118
- /** The parent it named. */
119
- of;
120
- /** Ids the manifest does contain, for the caller to match against. */
121
- available;
122
- constructor(id, of, available) {
123
- super("A derived construct must name a parent present in the manifest");
124
- this.name = "UnknownParent";
125
- this.id = id;
126
- this.of = of;
127
- this.available = available;
128
- }
129
- };
130
- /**
131
- * A derived construct naming a parent that may not vend it — a reader of a
132
- * reader, a schema of a schema.
133
- */
134
- var IllegalDerivation = class extends Error {
135
- id;
136
- kind;
137
- /** The kind of the parent it named. */
138
- parentKind;
139
- /** The parent kinds that may vend this one. */
140
- allowed;
141
- constructor(id, kind, parentKind, allowed) {
142
- super("A derived construct must name a parent whose kind may vend it");
143
- this.name = "IllegalDerivation";
144
- this.id = id;
145
- this.kind = kind;
146
- this.parentKind = parentKind;
147
- this.allowed = allowed;
148
- }
149
- };
150
- //#endregion
151
- //#region src/naming.ts
152
- var import_lodash_snakecase = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
153
- /** `Object#toString` result references. */
154
- var symbolTag = "[object Symbol]";
155
- /** Used to match words composed of alphanumeric characters. */
156
- var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
157
- /** Used to match Latin Unicode letters (excluding mathematical operators). */
158
- var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
159
- /** Used to compose unicode character classes. */
160
- var rsAstralRange = "\\ud800-\\udfff";
161
- var rsComboMarksRange = "\\u0300-\\u036f\\ufe20-\\ufe23";
162
- var rsComboSymbolsRange = "\\u20d0-\\u20f0";
163
- var rsDingbatRange = "\\u2700-\\u27bf";
164
- var rsLowerRange = "a-z\\xdf-\\xf6\\xf8-\\xff";
165
- var rsMathOpRange = "\\xac\\xb1\\xd7\\xf7";
166
- var rsNonCharRange = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf";
167
- var rsPunctuationRange = "\\u2000-\\u206f";
168
- var rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000";
169
- var rsUpperRange = "A-Z\\xc0-\\xd6\\xd8-\\xde";
170
- var rsVarRange = "\\ufe0e\\ufe0f";
171
- var rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
172
- /** Used to compose unicode capture groups. */
173
- var rsApos = "['’]";
174
- var rsBreak = "[" + rsBreakRange + "]";
175
- var rsCombo = "[" + rsComboMarksRange + rsComboSymbolsRange + "]";
176
- var rsDigits = "\\d+";
177
- var rsDingbat = "[" + rsDingbatRange + "]";
178
- var rsLower = "[" + rsLowerRange + "]";
179
- var rsMisc = "[^" + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + "]";
180
- var rsModifier = "(?:" + rsCombo + "|\\ud83c[\\udffb-\\udfff])";
181
- var rsNonAstral = "[^" + rsAstralRange + "]";
182
- var rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}";
183
- var rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]";
184
- var rsUpper = "[" + rsUpperRange + "]";
185
- var rsZWJ = "\\u200d";
186
- /** Used to compose unicode regexes. */
187
- var rsLowerMisc = "(?:" + rsLower + "|" + rsMisc + ")";
188
- var rsUpperMisc = "(?:" + rsUpper + "|" + rsMisc + ")";
189
- var rsOptLowerContr = "(?:" + rsApos + "(?:d|ll|m|re|s|t|ve))?";
190
- var rsOptUpperContr = "(?:" + rsApos + "(?:D|LL|M|RE|S|T|VE))?";
191
- var reOptMod = rsModifier + "?";
192
- var rsOptVar = "[" + rsVarRange + "]?";
193
- var rsOptJoin = "(?:" + rsZWJ + "(?:" + [
194
- rsNonAstral,
195
- rsRegional,
196
- rsSurrPair
197
- ].join("|") + ")" + rsOptVar + reOptMod + ")*";
198
- var rsSeq = rsOptVar + reOptMod + rsOptJoin;
199
- var rsEmoji = "(?:" + [
200
- rsDingbat,
201
- rsRegional,
202
- rsSurrPair
203
- ].join("|") + ")" + rsSeq;
204
- /** Used to match apostrophes. */
205
- var reApos = RegExp(rsApos, "g");
206
- /**
207
- * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
208
- * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
209
- */
210
- var reComboMark = RegExp(rsCombo, "g");
211
- /** Used to match complex or compound words. */
212
- var reUnicodeWord = RegExp([
213
- rsUpper + "?" + rsLower + "+" + rsOptLowerContr + "(?=" + [
214
- rsBreak,
215
- rsUpper,
216
- "$"
217
- ].join("|") + ")",
218
- rsUpperMisc + "+" + rsOptUpperContr + "(?=" + [
219
- rsBreak,
220
- rsUpper + rsLowerMisc,
221
- "$"
222
- ].join("|") + ")",
223
- rsUpper + "?" + rsLowerMisc + "+" + rsOptLowerContr,
224
- rsUpper + "+" + rsOptUpperContr,
225
- rsDigits,
226
- rsEmoji
227
- ].join("|"), "g");
228
- /** Used to detect strings that need a more robust regexp to match words. */
229
- var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
230
- /** Used to map Latin Unicode letters to basic Latin letters. */
231
- var deburredLetters = {
232
- "À": "A",
233
- "Á": "A",
234
- "Â": "A",
235
- "Ã": "A",
236
- "Ä": "A",
237
- "Å": "A",
238
- "à": "a",
239
- "á": "a",
240
- "â": "a",
241
- "ã": "a",
242
- "ä": "a",
243
- "å": "a",
244
- "Ç": "C",
245
- "ç": "c",
246
- "Ð": "D",
247
- "ð": "d",
248
- "È": "E",
249
- "É": "E",
250
- "Ê": "E",
251
- "Ë": "E",
252
- "è": "e",
253
- "é": "e",
254
- "ê": "e",
255
- "ë": "e",
256
- "Ì": "I",
257
- "Í": "I",
258
- "Î": "I",
259
- "Ï": "I",
260
- "ì": "i",
261
- "í": "i",
262
- "î": "i",
263
- "ï": "i",
264
- "Ñ": "N",
265
- "ñ": "n",
266
- "Ò": "O",
267
- "Ó": "O",
268
- "Ô": "O",
269
- "Õ": "O",
270
- "Ö": "O",
271
- "Ø": "O",
272
- "ò": "o",
273
- "ó": "o",
274
- "ô": "o",
275
- "õ": "o",
276
- "ö": "o",
277
- "ø": "o",
278
- "Ù": "U",
279
- "Ú": "U",
280
- "Û": "U",
281
- "Ü": "U",
282
- "ù": "u",
283
- "ú": "u",
284
- "û": "u",
285
- "ü": "u",
286
- "Ý": "Y",
287
- "ý": "y",
288
- "ÿ": "y",
289
- "Æ": "Ae",
290
- "æ": "ae",
291
- "Þ": "Th",
292
- "þ": "th",
293
- "ß": "ss",
294
- "Ā": "A",
295
- "Ă": "A",
296
- "Ą": "A",
297
- "ā": "a",
298
- "ă": "a",
299
- "ą": "a",
300
- "Ć": "C",
301
- "Ĉ": "C",
302
- "Ċ": "C",
303
- "Č": "C",
304
- "ć": "c",
305
- "ĉ": "c",
306
- "ċ": "c",
307
- "č": "c",
308
- "Ď": "D",
309
- "Đ": "D",
310
- "ď": "d",
311
- "đ": "d",
312
- "Ē": "E",
313
- "Ĕ": "E",
314
- "Ė": "E",
315
- "Ę": "E",
316
- "Ě": "E",
317
- "ē": "e",
318
- "ĕ": "e",
319
- "ė": "e",
320
- "ę": "e",
321
- "ě": "e",
322
- "Ĝ": "G",
323
- "Ğ": "G",
324
- "Ġ": "G",
325
- "Ģ": "G",
326
- "ĝ": "g",
327
- "ğ": "g",
328
- "ġ": "g",
329
- "ģ": "g",
330
- "Ĥ": "H",
331
- "Ħ": "H",
332
- "ĥ": "h",
333
- "ħ": "h",
334
- "Ĩ": "I",
335
- "Ī": "I",
336
- "Ĭ": "I",
337
- "Į": "I",
338
- "İ": "I",
339
- "ĩ": "i",
340
- "ī": "i",
341
- "ĭ": "i",
342
- "į": "i",
343
- "ı": "i",
344
- "Ĵ": "J",
345
- "ĵ": "j",
346
- "Ķ": "K",
347
- "ķ": "k",
348
- "ĸ": "k",
349
- "Ĺ": "L",
350
- "Ļ": "L",
351
- "Ľ": "L",
352
- "Ŀ": "L",
353
- "Ł": "L",
354
- "ĺ": "l",
355
- "ļ": "l",
356
- "ľ": "l",
357
- "ŀ": "l",
358
- "ł": "l",
359
- "Ń": "N",
360
- "Ņ": "N",
361
- "Ň": "N",
362
- "Ŋ": "N",
363
- "ń": "n",
364
- "ņ": "n",
365
- "ň": "n",
366
- "ŋ": "n",
367
- "Ō": "O",
368
- "Ŏ": "O",
369
- "Ő": "O",
370
- "ō": "o",
371
- "ŏ": "o",
372
- "ő": "o",
373
- "Ŕ": "R",
374
- "Ŗ": "R",
375
- "Ř": "R",
376
- "ŕ": "r",
377
- "ŗ": "r",
378
- "ř": "r",
379
- "Ś": "S",
380
- "Ŝ": "S",
381
- "Ş": "S",
382
- "Š": "S",
383
- "ś": "s",
384
- "ŝ": "s",
385
- "ş": "s",
386
- "š": "s",
387
- "Ţ": "T",
388
- "Ť": "T",
389
- "Ŧ": "T",
390
- "ţ": "t",
391
- "ť": "t",
392
- "ŧ": "t",
393
- "Ũ": "U",
394
- "Ū": "U",
395
- "Ŭ": "U",
396
- "Ů": "U",
397
- "Ű": "U",
398
- "Ų": "U",
399
- "ũ": "u",
400
- "ū": "u",
401
- "ŭ": "u",
402
- "ů": "u",
403
- "ű": "u",
404
- "ų": "u",
405
- "Ŵ": "W",
406
- "ŵ": "w",
407
- "Ŷ": "Y",
408
- "ŷ": "y",
409
- "Ÿ": "Y",
410
- "Ź": "Z",
411
- "Ż": "Z",
412
- "Ž": "Z",
413
- "ź": "z",
414
- "ż": "z",
415
- "ž": "z",
416
- "IJ": "IJ",
417
- "ij": "ij",
418
- "Œ": "Oe",
419
- "œ": "oe",
420
- "ʼn": "'n",
421
- "ſ": "ss"
422
- };
423
- /** Detect free variable `global` from Node.js. */
424
- var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
425
- /** Detect free variable `self`. */
426
- var freeSelf = typeof self == "object" && self && self.Object === Object && self;
427
- /** Used as a reference to the global object. */
428
- var root = freeGlobal || freeSelf || Function("return this")();
429
- /**
430
- * A specialized version of `_.reduce` for arrays without support for
431
- * iteratee shorthands.
432
- *
433
- * @private
434
- * @param {Array} [array] The array to iterate over.
435
- * @param {Function} iteratee The function invoked per iteration.
436
- * @param {*} [accumulator] The initial value.
437
- * @param {boolean} [initAccum] Specify using the first element of `array` as
438
- * the initial value.
439
- * @returns {*} Returns the accumulated value.
440
- */
441
- function arrayReduce(array, iteratee, accumulator, initAccum) {
442
- var index = -1, length = array ? array.length : 0;
443
- if (initAccum && length) accumulator = array[++index];
444
- while (++index < length) accumulator = iteratee(accumulator, array[index], index, array);
445
- return accumulator;
446
- }
447
- /**
448
- * Splits an ASCII `string` into an array of its words.
449
- *
450
- * @private
451
- * @param {string} The string to inspect.
452
- * @returns {Array} Returns the words of `string`.
453
- */
454
- function asciiWords(string) {
455
- return string.match(reAsciiWord) || [];
456
- }
457
- /**
458
- * The base implementation of `_.propertyOf` without support for deep paths.
459
- *
460
- * @private
461
- * @param {Object} object The object to query.
462
- * @returns {Function} Returns the new accessor function.
463
- */
464
- function basePropertyOf(object) {
465
- return function(key) {
466
- return object == null ? void 0 : object[key];
467
- };
468
- }
469
- /**
470
- * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
471
- * letters to basic Latin letters.
472
- *
473
- * @private
474
- * @param {string} letter The matched letter to deburr.
475
- * @returns {string} Returns the deburred letter.
476
- */
477
- var deburrLetter = basePropertyOf(deburredLetters);
478
- /**
479
- * Checks if `string` contains a word composed of Unicode symbols.
480
- *
481
- * @private
482
- * @param {string} string The string to inspect.
483
- * @returns {boolean} Returns `true` if a word is found, else `false`.
484
- */
485
- function hasUnicodeWord(string) {
486
- return reHasUnicodeWord.test(string);
487
- }
488
- /**
489
- * Splits a Unicode `string` into an array of its words.
490
- *
491
- * @private
492
- * @param {string} The string to inspect.
493
- * @returns {Array} Returns the words of `string`.
494
- */
495
- function unicodeWords(string) {
496
- return string.match(reUnicodeWord) || [];
497
- }
498
- /**
499
- * Used to resolve the
500
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
501
- * of values.
502
- */
503
- var objectToString = Object.prototype.toString;
504
- /** Built-in value references. */
505
- var Symbol = root.Symbol;
506
- /** Used to convert symbols to primitives and strings. */
507
- var symbolProto = Symbol ? Symbol.prototype : void 0;
508
- var symbolToString = symbolProto ? symbolProto.toString : void 0;
509
- /**
510
- * The base implementation of `_.toString` which doesn't convert nullish
511
- * values to empty strings.
512
- *
513
- * @private
514
- * @param {*} value The value to process.
515
- * @returns {string} Returns the string.
516
- */
517
- function baseToString(value) {
518
- if (typeof value == "string") return value;
519
- if (isSymbol(value)) return symbolToString ? symbolToString.call(value) : "";
520
- var result = value + "";
521
- return result == "0" && 1 / value == -Infinity ? "-0" : result;
522
- }
523
- /**
524
- * Creates a function like `_.camelCase`.
525
- *
526
- * @private
527
- * @param {Function} callback The function to combine each word.
528
- * @returns {Function} Returns the new compounder function.
529
- */
530
- function createCompounder(callback) {
531
- return function(string) {
532
- return arrayReduce(words(deburr(string).replace(reApos, "")), callback, "");
533
- };
534
- }
535
- /**
536
- * Checks if `value` is object-like. A value is object-like if it's not `null`
537
- * and has a `typeof` result of "object".
538
- *
539
- * @static
540
- * @memberOf _
541
- * @since 4.0.0
542
- * @category Lang
543
- * @param {*} value The value to check.
544
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
545
- * @example
546
- *
547
- * _.isObjectLike({});
548
- * // => true
549
- *
550
- * _.isObjectLike([1, 2, 3]);
551
- * // => true
552
- *
553
- * _.isObjectLike(_.noop);
554
- * // => false
555
- *
556
- * _.isObjectLike(null);
557
- * // => false
558
- */
559
- function isObjectLike(value) {
560
- return !!value && typeof value == "object";
561
- }
562
- /**
563
- * Checks if `value` is classified as a `Symbol` primitive or object.
564
- *
565
- * @static
566
- * @memberOf _
567
- * @since 4.0.0
568
- * @category Lang
569
- * @param {*} value The value to check.
570
- * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
571
- * @example
572
- *
573
- * _.isSymbol(Symbol.iterator);
574
- * // => true
575
- *
576
- * _.isSymbol('abc');
577
- * // => false
578
- */
579
- function isSymbol(value) {
580
- return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
581
- }
582
- /**
583
- * Converts `value` to a string. An empty string is returned for `null`
584
- * and `undefined` values. The sign of `-0` is preserved.
585
- *
586
- * @static
587
- * @memberOf _
588
- * @since 4.0.0
589
- * @category Lang
590
- * @param {*} value The value to process.
591
- * @returns {string} Returns the string.
592
- * @example
593
- *
594
- * _.toString(null);
595
- * // => ''
596
- *
597
- * _.toString(-0);
598
- * // => '-0'
599
- *
600
- * _.toString([1, 2, 3]);
601
- * // => '1,2,3'
602
- */
603
- function toString(value) {
604
- return value == null ? "" : baseToString(value);
605
- }
606
- /**
607
- * Deburrs `string` by converting
608
- * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
609
- * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
610
- * letters to basic Latin letters and removing
611
- * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
612
- *
613
- * @static
614
- * @memberOf _
615
- * @since 3.0.0
616
- * @category String
617
- * @param {string} [string=''] The string to deburr.
618
- * @returns {string} Returns the deburred string.
619
- * @example
620
- *
621
- * _.deburr('déjà vu');
622
- * // => 'deja vu'
623
- */
624
- function deburr(string) {
625
- string = toString(string);
626
- return string && string.replace(reLatin, deburrLetter).replace(reComboMark, "");
627
- }
628
- /**
629
- * Converts `string` to
630
- * [snake case](https://en.wikipedia.org/wiki/Snake_case).
631
- *
632
- * @static
633
- * @memberOf _
634
- * @since 3.0.0
635
- * @category String
636
- * @param {string} [string=''] The string to convert.
637
- * @returns {string} Returns the snake cased string.
638
- * @example
639
- *
640
- * _.snakeCase('Foo Bar');
641
- * // => 'foo_bar'
642
- *
643
- * _.snakeCase('fooBar');
644
- * // => 'foo_bar'
645
- *
646
- * _.snakeCase('--FOO-BAR--');
647
- * // => 'foo_bar'
648
- */
649
- var snakeCase = createCompounder(function(result, word, index) {
650
- return result + (index ? "_" : "") + word.toLowerCase();
651
- });
652
- /**
653
- * Splits `string` into an array of its words.
654
- *
655
- * @static
656
- * @memberOf _
657
- * @since 3.0.0
658
- * @category String
659
- * @param {string} [string=''] The string to inspect.
660
- * @param {RegExp|string} [pattern] The pattern to match words.
661
- * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
662
- * @returns {Array} Returns the words of `string`.
663
- * @example
664
- *
665
- * _.words('fred, barney, & pebbles');
666
- * // => ['fred', 'barney', 'pebbles']
667
- *
668
- * _.words('fred, barney, & pebbles', /[^, ]+/g);
669
- * // => ['fred', 'barney', '&', 'pebbles']
670
- */
671
- function words(string, pattern, guard) {
672
- string = toString(string);
673
- pattern = guard ? void 0 : pattern;
674
- if (pattern === void 0) return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
675
- return string.match(pattern) || [];
676
- }
677
- module.exports = snakeCase;
678
- })))(), 1);
679
- /**
680
- * `UPPER_SNAKE_CASE`, with numbers kept against the word they follow.
681
- *
682
- * Matches `environmentCase` in `@geekmidas/envkit`, which reads the values these
683
- * names key. The two must agree exactly, so this is the implementation and that
684
- * one should defer to it.
685
- *
686
- * @example environmentCase('sendEmail') // 'SEND_EMAIL'
687
- * @example environmentCase('api2') // 'API2' (digit joins its word)
688
- */
689
- function environmentCase(name) {
690
- return (0, import_lodash_snakecase.default)(name).toUpperCase().replace(/_\d+/g, (r) => r.replace("_", ""));
691
- }
692
- /**
693
- * The env key a construct provides for one of its roles.
694
- *
695
- * @example provideKey('Uploads', 'url') // 'UPLOADS_URL'
696
- * @example provideKey('Uploads', 'cdnUrl') // 'UPLOADS_CDN_URL'
697
- */
698
- function provideKey(id, role) {
699
- return environmentCase(`${id}_${role}`);
700
- }
701
- /**
702
- * A construct's canonical id — PascalCase.
703
- *
704
- * `uploads`, `Uploads`, `user_uploads`, and `user-uploads` all canonicalise to
705
- * the same id, so declaring two of them is a duplicate rather than a collision
706
- * to detect.
707
- *
708
- * Runtime only. Writing the id in PascalCase is what keeps the *type* usable:
709
- * the service key is `Uncapitalize<TName>`, a TypeScript intrinsic, so no
710
- * type-level transform is needed and none has to be kept in step with this one.
711
- *
712
- * @example canonicalId('user-uploads') // 'UserUploads'
713
- */
714
- function canonicalId(input) {
715
- const id = (0, import_lodash_snakecase.default)(input).split("_").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
716
- if (!VALID_ID.test(id)) throw new InvalidConstructId(input, id);
717
- return id;
718
- }
719
- /**
720
- * A canonical id: PascalCase, letters and digits only.
721
- *
722
- * Narrower than a JavaScript identifier — `_id` and `$ref` are legal JavaScript
723
- * and rejected here — because the id also has to survive `environmentCase` into
724
- * an env key and `cloudName` into a DNS-safe resource name.
725
- */
726
- const VALID_ID = /^[A-Z][A-Za-z0-9]*$/;
727
- /**
728
- * The key a construct is reached under in the service record.
729
- *
730
- * The runtime twin of `Uncapitalize<TName>`, which types it — they must agree,
731
- * so they live next to each other rather than being re-derived by each
732
- * construct.
733
- *
734
- * @example serviceKey('UserUploads') // 'userUploads' → services.userUploads
735
- */
736
- function serviceKey(id) {
737
- return id.charAt(0).toLowerCase() + id.slice(1);
738
- }
739
- /**
740
- * The table a cache keeps its entries in, when nobody named one.
741
- *
742
- * Derived from the cache's own id rather than fixed at `cache`, because a
743
- * database may hold more than one and two caches sharing a table share a
744
- * keyspace — `orders.cache('Sessions')` and `orders.cache('Rates')` would
745
- * silently read each other's entries and evict each other's keys.
746
- *
747
- * Prefixed rather than suffixed so every cache sorts together in `\dt`, and
748
- * prefixed at all so a cache named for a thing the application also stores —
749
- * `orders.cache('Users')` — cannot collide with the table holding that thing.
750
- *
751
- * Read by whoever composes the URL and by whoever creates the table, so both
752
- * default the same way.
753
- *
754
- * @example cacheTable('Sessions') // 'cache_sessions'
755
- */
756
- function cacheTable(id) {
757
- return `cache_${id.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase()}`;
758
- }
759
- /**
760
- * Kebab-cases an identifier, acronym- and digit-aware.
761
- *
762
- * `userName` → `user-name`, `APIKey` → `api-key`, `S3Bucket` → `s3-bucket`.
763
- *
764
- * The last of those is why this is here rather than `snakecase(id)` with the
765
- * underscores swapped: lodash splits a digit from the letter beside it, so
766
- * `S3Bucket` became `s-3-bucket` on one provider and `s3-bucket` on the other.
767
- * Two implementations of one rule, agreeing on every id anybody had tried.
768
- *
769
- * `environmentCase` already corrected for the same thing in the other
770
- * direction — `api2` keeps its digit — so the two spellings of "kebab this id"
771
- * in this file did not even agree with each other.
772
- */
773
- function kebabCase(value) {
774
- return value.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
775
- }
776
- /**
777
- * The physical name a target provisions a construct under — lowercase kebab,
778
- * scoped so two stages or apps sharing an account cannot collide.
779
- *
780
- * **One rule, every provider.** A construct is named the same thing on AWS and
781
- * on Dokploy, which is what lets a name be read across them: `Database` in the
782
- * `production` stage of `kitchen-sink` is `production-kitchen-sink-database`
783
- * wherever it lands. The SST target's `prefixedName` is this function under
784
- * another signature and defers to it.
785
- *
786
- * Idempotent in its prefix: an id that already carries the scope is not given a
787
- * second one, so composing names cannot double up.
788
- *
789
- * @example cloudName({ stage: 'prod', app: 'myapp' }, 'UserUploads')
790
- * // 'prod-myapp-user-uploads'
791
- */
792
- function cloudName(scope, id) {
793
- return scopedName([scope.stage, scope.app], id);
794
- }
795
- /**
796
- * {@link cloudName} for a caller that holds its scope as a list.
797
- *
798
- * The SST target's stacks add a segment of their own, so the prefix is not
799
- * always two parts — which is the only reason this signature exists.
800
- */
801
- function scopedName(scope, id) {
802
- const prefix = scope.join("-").toLowerCase();
803
- const name = kebabCase(id);
804
- return name.startsWith(prefix) ? name : `${prefix}-${name}`;
805
- }
806
- /**
807
- * The domain a cookie must be scoped to so a surface and its callers share it.
808
- *
809
- * Derived from the addresses rather than configured, for the same reason the
810
- * origins are: the set of things that talk to a surface is already in the graph,
811
- * and the domain they have in common is a fact about that set. Returned with the
812
- * leading dot a `Domain` attribute wants.
813
- *
814
- * Returns `undefined` when there is nothing to scope, which is the common case
815
- * and not a failure:
816
- *
817
- * - **One host.** Locally everything is `localhost` on different ports, and
818
- * cookies ignore the port — so a `Domain` would add nothing and `.localhost`
819
- * is not a domain a browser will accept.
820
- * - **Nothing in common.** Unrelated hosts cannot share a cookie at all, and
821
- * emitting the longest common suffix anyway would be a value that silently
822
- * fails to set.
823
- *
824
- * **The public-suffix limit, stated rather than discovered.** Two apps on
825
- * `a.vercel.app` and `b.vercel.app` share `.vercel.app`, which every browser
826
- * rejects because it is a registrable suffix rather than a registrable domain.
827
- * Resolving that correctly needs the Public Suffix List, which is a downloaded,
828
- * expiring dataset — so this requires at least two labels and otherwise trusts
829
- * the addresses, and the value stays overridable for the case it gets wrong.
830
- */
831
- function cookieDomain(urls) {
832
- const hosts = /* @__PURE__ */ new Set();
833
- for (const url of urls) try {
834
- const { hostname } = new URL(url);
835
- if (/^\d+(\.\d+){3}$/.test(hostname) || hostname.includes(":")) return;
836
- hosts.add(hostname.toLowerCase());
837
- } catch {
838
- return;
839
- }
840
- if (hosts.size === 0) return;
841
- if (hosts.size === 1) return;
842
- const [first = [], ...rest] = [...hosts].map((host) => host.split(".").reverse());
843
- const shared = [];
844
- for (const [index, label] of first.entries()) {
845
- if (!rest.every((labels) => labels[index] === label)) break;
846
- shared.push(label);
847
- }
848
- if (shared.length < 2) return;
849
- return `.${shared.reverse().join(".")}`;
850
- }
851
- /**
852
- * The env key a construct's provided role actually becomes.
853
- *
854
- * Almost always `provideKey(id, role)` — and `secret` is the exception, because
855
- * a secret's *name* is its key: `Auth` signs with `AUTH_SECRET`, which is also
856
- * what better-auth's own tooling looks for, and qualifying it by role would
857
- * produce `AUTH_SECRET_VALUE`.
858
- *
859
- * It lives here rather than in each target because two targets deriving the
860
- * same key separately is exactly the drift the app/infra contract check exists
861
- * to catch — and a check deriving the key differently from the thing it checks
862
- * cannot catch anything.
863
- */
864
- function providedKeyFor(id, kind, role) {
865
- if (kind === "secret") return environmentCase(id);
866
- if (kind === "telemetry") return "OTEL_EXPORTER_OTLP_ENDPOINT";
867
- return provideKey(id, role);
868
- }
869
- //#endregion
870
- //#region src/derive.ts
871
- /** Whether a declaration names a parent. */
872
- function isDerived(declaration) {
873
- return declaration.kind in DERIVES_FROM && "of" in declaration && typeof declaration.of === "string";
874
- }
875
- /**
876
- * Check every derived construct against its parent.
877
- *
878
- * Two rules: the parent exists, and its kind may vend this one. Together they
879
- * make cycles unreachable — a reader is terminal, so no chain of `of` can
880
- * return to where it started, and no walk is needed to prove it.
881
- */
882
- function assertDerivations(manifest) {
883
- for (const [id, declaration] of Object.entries(manifest)) {
884
- if (!isDerived(declaration)) continue;
885
- const parent = manifest[declaration.of];
886
- if (!parent) throw new UnknownParent(id, declaration.of, Object.keys(manifest));
887
- const allowed = DERIVES_FROM[declaration.kind];
888
- if (!allowed.includes(parent.kind)) throw new IllegalDerivation(id, declaration.kind, parent.kind, allowed);
889
- }
890
- }
891
- /**
892
- * The order constructs must be provisioned in: every parent before its children.
893
- *
894
- * Resources are leaves and so come first in any order; only derived nodes
895
- * constrain the sequence, and they form a shallow forest rather than a general
896
- * graph. This walks each node's ancestors on demand instead of running a full
897
- * topological sort, which is the same result at this depth and reads as what it
898
- * is.
899
- *
900
- * Assumes {@link assertDerivations} has passed — a missing parent would
901
- * otherwise be a silent omission here rather than an error.
902
- */
903
- function provisionOrder(manifest) {
904
- const ordered = [];
905
- const placed = /* @__PURE__ */ new Set();
906
- const place = (id) => {
907
- if (placed.has(id)) return;
908
- const declaration = manifest[id];
909
- if (!declaration) return;
910
- placed.add(id);
911
- if (isDerived(declaration)) place(declaration.of);
912
- ordered.push(id);
913
- };
914
- for (const id of Object.keys(manifest)) place(id);
915
- return ordered;
916
- }
917
- /**
918
- * Every edge a declaration carries, wherever the kind happens to keep them.
919
- *
920
- * Dependencies live in two places by design: on a node when the whole construct
921
- * is the consumer (a site), and on each nested handler when the construct is a
922
- * surface (a `rest-api`, whose routes each depend on their own things and
923
- * nothing more). Flattening that difference here is what lets every consumer of
924
- * the graph — reverse lookups, filtering, reference checks — ask one question.
925
- */
926
- function dependenciesOf(declaration) {
927
- const own = "dependencies" in declaration ? declaration.dependencies ?? [] : [];
928
- const calls = "calls" in declaration ? declaration.calls ?? [] : [];
929
- const nested = declaration.kind === "rest-api" ? declaration.endpoints.flatMap((endpoint) => endpoint.dependencies) : [];
930
- const telemetry = "telemetry" in declaration && typeof declaration.telemetry === "string" ? [{
931
- target: declaration.telemetry,
932
- kind: "telemetry"
933
- }] : [];
934
- return [
935
- ...own,
936
- ...calls,
937
- ...nested,
938
- ...telemetry
939
- ];
940
- }
941
- /**
942
- * The ids that depend on one construct — the graph read backwards.
943
- *
944
- * This is the whole mechanism behind CORS origins and trusted origins. Both are
945
- * lists of *callers*, and a caller is exactly an inbound edge, so neither is
946
- * ever written down: a surface that listed its own callers would have to be
947
- * edited every time something new called it, which is the hand-maintained list
948
- * this replaces.
949
- *
950
- * Sorted, because it feeds a comma-separated env value that would otherwise
951
- * change whenever the manifest's key order did — and a value that churns is a
952
- * container that redeploys for no reason.
953
- */
954
- function dependentsOf(manifest, id) {
955
- const callers = [];
956
- for (const [callerId, declaration] of Object.entries(manifest)) {
957
- if (callerId === id) continue;
958
- if (dependenciesOf(declaration).some((edge) => edge.target === id)) callers.push(callerId);
959
- }
960
- return callers.sort();
1
+ //#region src/index.ts
2
+ /** Flatten a manifest field (array or partitioned) into a plain array. */
3
+ function flattenManifestField(field) {
4
+ if (!field) return [];
5
+ return Array.isArray(field) ? [...field] : Object.values(field).flat();
961
6
  }
962
- /**
963
- * How each site variant names a value it ships to the browser.
964
- *
965
- * The prefix *is* the framework's contract — `VITE_`, `NEXT_PUBLIC_` and
966
- * `EXPO_PUBLIC_` all mean "inline this into the bundle" — so it is the one thing
967
- * a variant changes, and it changes nothing else.
968
- */
969
- const PUBLIC_PREFIX = {
970
- static: "VITE_",
971
- tanstack: "VITE_",
972
- next: "NEXT_PUBLIC_",
973
- expo: "EXPO_PUBLIC_"
974
- };
975
- /**
976
- * The keys a site's bundle needs, mapped to the key each value comes from —
977
- * `{ VITE_API_URL: 'API_URL' }`.
978
- *
979
- * A rename, not a second derivation: `API_URL` is resolved once, by whatever
980
- * resolved it for the server, and the site reads the same value under the name
981
- * its bundler will inline. That is what keeps a site and its API from coming to
982
- * disagree about where the API is.
983
- *
984
- * Filtered by `PUBLIC` rather than by what the site asked for. A site may
985
- * legitimately depend on anything — its server half, where it has one, reads env
986
- * exactly as a function does — so this is not a restriction on edges. It decides
987
- * one thing: which values may be prefixed into a bundle, which is what keeps
988
- * `ORDERS_URL` and its password out of a JavaScript file served to the public.
989
- *
990
- * Shared by every target for the same reason `providedKeyFor` is: a site built
991
- * locally and the same site built by a deploy must inline the same names.
992
- */
993
- function publicEnvFor(declaration, manifest) {
994
- const prefix = PUBLIC_PREFIX[declaration.variant];
995
- const keys = {};
996
- for (const edge of declaration.dependencies) {
997
- const target = manifest[edge.target];
998
- if (!target) continue;
999
- for (const role of PUBLIC[target.kind] ?? []) {
1000
- const key = provideKey(edge.target, role);
1001
- keys[`${prefix}${key}`] = key;
1002
- }
1003
- }
1004
- return keys;
1005
- }
1006
- //#endregion
1007
- //#region src/encryption.ts
1008
- /**
1009
- * The `kms://` URL an `Encryption` construct reads on AWS.
1010
- *
1011
- * Here because two packages meet on it: `@geekmidas/cloud` composes it from
1012
- * the keys it provisioned, and `@geekmidas/constructs` parses it to reach
1013
- * them. One function, so the two cannot disagree about a parameter's name.
1014
- */
1015
- const KMS_SCHEME = "kms:";
1016
- /**
1017
- * `kms://<region>?key=<key arn>&index=<hmac key arn>[&endpoint=<url>]`
1018
- *
1019
- * `endpoint` reaches an emulator instead of AWS — floci, locally and in tests —
1020
- * the same parameter an `sns://` connection string carries for the same reason.
1021
- */
1022
- function kmsUrl(input) {
1023
- const query = new URLSearchParams({
1024
- key: input.key,
1025
- index: input.index,
1026
- ...input.endpoint ? { endpoint: input.endpoint } : {}
1027
- });
1028
- return `${KMS_SCHEME}//${input.region}?${query}`;
1029
- }
1030
- //#endregion
1031
- //#region src/external.ts
1032
- /** The key in a by-stage `url` that answers for every stage not listed. */
1033
- const DEFAULT_STAGE_URL = "default";
1034
- /**
1035
- * Where an external API answers on a deployed stage.
1036
- *
1037
- * One URL answers every stage; a record answers by stage name, falling back
1038
- * to `default`. Read at build and deploy, so a stage nobody gave a URL fails
1039
- * there — with the stage named — rather than at the first request.
1040
- *
1041
- * @throws {NoUrlForStage} when a record names neither the stage nor a default.
1042
- */
1043
- function externalApiUrl(declaration, stage) {
1044
- const { url } = declaration;
1045
- if (typeof url === "string") return url;
1046
- const resolved = url[stage] ?? url["default"];
1047
- if (!resolved) throw new NoUrlForStage(declaration.id, stage, Object.keys(url));
1048
- return resolved;
1049
- }
1050
- /** An external API's `url` record has nothing for the stage being deployed. */
1051
- var NoUrlForStage = class extends Error {
1052
- id;
1053
- stage;
1054
- stages;
1055
- constructor(id, stage, stages) {
1056
- super(`'${id}' has no URL for the stage '${stage}': its url names ${stages.length ? stages.map((s) => `'${s}'`).join(", ") : "no stages"}. Add '${stage}', or a '${DEFAULT_STAGE_URL}' for every stage not listed.`);
1057
- this.id = id;
1058
- this.stage = stage;
1059
- this.stages = stages;
1060
- this.name = "NoUrlForStage";
1061
- }
1062
- };
1063
- //#endregion
1064
- //#region src/headers.ts
1065
- /**
1066
- * Headers gkm reserves for its own services' calls to each other.
1067
- *
1068
- * Shared by `@geekmidas/constructs`, which sends and reads them, and
1069
- * `@geekmidas/cli`, whose edges strip them from every request that arrives
1070
- * from outside — so the two cannot name them differently.
1071
- */
1072
- /**
1073
- * The address of the client a service-to-service call is made on behalf of.
1074
- *
1075
- * An API asking its auth server for a session sends the client's address in
1076
- * this rather than `X-Forwarded-For`: a forwarding header marks a request as
1077
- * outside traffic, which would start the auth server's span in a new trace,
1078
- * and the address is still needed — Better Auth rate-limits per client.
1079
- *
1080
- * Reserved: the stack's edge (Caddy, Traefik, the `gkm dev` edge) removes it
1081
- * from incoming requests, and the auth server ignores it on any request that
1082
- * is not an internal caller's, so it cannot be spoofed from outside.
1083
- */
1084
- const CLIENT_IP_HEADER = "x-gkm-client-ip";
1085
- //#endregion
1086
- //#region src/migrations.ts
1087
- /** Where every construct's folder lives, from the project root. */
1088
- const MIGRATIONS_ROOT = "db";
1089
- /** The two folders a construct's folder holds, and nothing else. */
1090
- const DATABASE_FOLDERS = ["migrations", "seeds"];
1091
- /**
1092
- * The constructs that take migrations, parents before the tenants inside them.
1093
- *
1094
- * A database and each schema tenant: every one has an owner role and a schema
1095
- * of its own, and so a history of its own. A reader has neither — it reads its
1096
- * parent's schema — and a cache's table is created by provisioning, not by a
1097
- * migration anyone writes.
1098
- */
1099
- function migrationTargets(manifest) {
1100
- return provisionOrder(manifest).flatMap((id) => {
1101
- const declaration = manifest[id];
1102
- if (!declaration) return [];
1103
- if (declaration.kind === "database") return [target(id)];
1104
- if (declaration.kind === "database-schema") return [{
1105
- ...target(id),
1106
- of: declaration.of
1107
- }];
1108
- return [];
1109
- });
1110
- }
1111
- /**
1112
- * A construct's folder, relative to the project root.
1113
- *
1114
- * Named by the construct — `AuthDatabase` is `db/auth-database` — in the case
1115
- * every other name outside TypeScript takes. Lowercase, because a folder that
1116
- * differs from another only in case is two folders on Linux and one on a Mac;
1117
- * and `canonicalId` reads it back to the construct exactly, which is how a
1118
- * folder naming nothing is caught rather than skipped.
1119
- */
1120
- function databaseFolder(id) {
1121
- return `db/${kebabCase(id)}`;
1122
- }
1123
- /** Where a construct's migrations live: `db/auth-database/migrations`. */
1124
- function migrationFolder(id) {
1125
- return `${databaseFolder(id)}/migrations`;
1126
- }
1127
- /**
1128
- * Where a construct's seeds live: `db/auth-database/seeds`.
1129
- *
1130
- * Reference data the app needs to run — a permission catalogue, roles, lookup
1131
- * tables. Seeds are upserts run on every pass, after the migrations, so a
1132
- * changed seed is applied by running it again. Sample data is factories'.
1133
- */
1134
- function seedFolder(id) {
1135
- return `${databaseFolder(id)}/seeds`;
1136
- }
1137
- function target(id) {
1138
- return {
1139
- id,
1140
- folder: databaseFolder(id),
1141
- migrations: migrationFolder(id),
1142
- seeds: seedFolder(id)
1143
- };
1144
- }
1145
- //#endregion
1146
- //#region src/mobile.ts
1147
- /**
1148
- * How a mobile app is reached: its URL scheme, and the origins a surface trusts
1149
- * for it.
1150
- *
1151
- * Stated once, here, because three targets ask — the local one (`gkm dev`,
1152
- * `gkm test`), Dokploy and AWS — and a scheme one of them derived differently
1153
- * would be an app whose sign-in callback the auth server refuses on exactly one
1154
- * of them.
1155
- */
1156
- /**
1157
- * An app's scheme: the one given, or the project's name made a valid scheme.
1158
- *
1159
- * One for every stage. A development build and the store build register the
1160
- * same scheme, so the auth server of whichever stage a build talks to trusts
1161
- * it, and nothing about the app differs between stages but its URLs.
1162
- *
1163
- * A scheme is a letter followed by letters, digits, `+`, `-` or `.` — so
1164
- * `Corner Shop` becomes `corner-shop`, and a name that starts with a digit gets a
1165
- * leading `app`.
1166
- */
1167
- function schemeBase(project, given) {
1168
- const raw = (given ?? project).toLowerCase().replace(/[^a-z0-9+.-]+/g, "-").replace(/^-+|-+$/g, "");
1169
- if (!raw) return "app";
1170
- return /^[a-z]/.test(raw) ? raw : `app${raw}`;
1171
- }
1172
- /**
1173
- * The origins a surface trusts for a mobile caller.
1174
- *
1175
- * Better Auth's Expo plugin sends the app's scheme as its origin
1176
- * (`shop://`), and a link can carry a path after it (`shop://*`).
1177
- * In development, Expo Go sends `exp://<host>:<port>` instead — so a local
1178
- * stage adds the hosts a device actually reaches Metro on, and Metro's port
1179
- * when the target placed it: a whole subnet is not trusted because one phone
1180
- * is on it.
1181
- */
1182
- function mobileOrigins(scheme, metro) {
1183
- return [
1184
- `${scheme}://`,
1185
- `${scheme}://*`,
1186
- ...(metro?.hosts ?? []).flatMap((host) => [`exp://${host}:${metro?.port ?? "*"}`, `exp://${host}:${metro?.port ?? "*"}/**`])
1187
- ];
1188
- }
1189
- /** Whether an origin is a web one — what a cookie domain is derived from. */
1190
- function isWebOrigin(origin) {
1191
- return origin.startsWith("http://") || origin.startsWith("https://");
1192
- }
1193
- //#endregion
1194
- export { CLIENT_IP_HEADER, DATABASE_FOLDERS, DEFAULT_POSTGRES_VERSION, DEFAULT_STAGE_URL, DERIVES_FROM, IllegalDerivation, InvalidConstructId, KMS_SCHEME, MIGRATIONS_ROOT, NoUrlForStage, PUBLIC, PUBLIC_PREFIX, TELEMETRY_KEYS, UnknownParent, assertDerivations, cacheTable, canonicalId, cloudName, cookieDomain, databaseFolder, dependenciesOf, dependentsOf, environmentCase, externalApiUrl, isDerived, isWebOrigin, kebabCase, kmsUrl, migrationFolder, migrationTargets, mobileOrigins, provideKey, providedKeyFor, provisionOrder, publicEnvFor, schemeBase, scopedName, seedFolder, serviceKey };
1195
7
 
8
+ //#endregion
9
+ export { flattenManifestField };
1196
10
  //# sourceMappingURL=index.mjs.map