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