@sponson/adapters 0.0.0-stage → 0.5.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/LICENSE +202 -0
- package/README.md +4 -2
- package/dist/algolia.d.ts +6 -0
- package/dist/algolia.js +151 -0
- package/dist/algolia.js.map +1 -0
- package/dist/clerk.d.ts +8 -0
- package/dist/clerk.js +107 -0
- package/dist/clerk.js.map +1 -0
- package/dist/cloudflare.d.ts +25 -0
- package/dist/cloudflare.js +310 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/common.d.ts +73 -0
- package/dist/common.js +140 -0
- package/dist/common.js.map +1 -0
- package/dist/digest.d.ts +46 -0
- package/dist/digest.js +129 -0
- package/dist/digest.js.map +1 -0
- package/dist/digitalocean.d.ts +5 -0
- package/dist/digitalocean.js +243 -0
- package/dist/digitalocean.js.map +1 -0
- package/dist/http-adapter-action.d.ts +63 -0
- package/dist/http-adapter-action.js +369 -0
- package/dist/http-adapter-action.js.map +1 -0
- package/dist/http-adapter-auth.d.ts +88 -0
- package/dist/http-adapter-auth.js +437 -0
- package/dist/http-adapter-auth.js.map +1 -0
- package/dist/http-adapter-client.d.ts +51 -0
- package/dist/http-adapter-client.js +156 -0
- package/dist/http-adapter-client.js.map +1 -0
- package/dist/http-adapter-graphql.d.ts +39 -0
- package/dist/http-adapter-graphql.js +157 -0
- package/dist/http-adapter-graphql.js.map +1 -0
- package/dist/http-adapter-list.d.ts +33 -0
- package/dist/http-adapter-list.js +421 -0
- package/dist/http-adapter-list.js.map +1 -0
- package/dist/http-adapter-resource.d.ts +29 -0
- package/dist/http-adapter-resource.js +462 -0
- package/dist/http-adapter-resource.js.map +1 -0
- package/dist/http-adapter-spec.d.ts +216 -0
- package/dist/http-adapter-spec.js +660 -0
- package/dist/http-adapter-spec.js.map +1 -0
- package/dist/http-adapter.d.ts +16 -0
- package/dist/http-adapter.js +28 -0
- package/dist/http-adapter.js.map +1 -0
- package/dist/http.d.ts +179 -0
- package/dist/http.js +352 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/launchdarkly.d.ts +15 -0
- package/dist/launchdarkly.js +337 -0
- package/dist/launchdarkly.js.map +1 -0
- package/dist/manual.d.ts +13 -0
- package/dist/manual.js +201 -0
- package/dist/manual.js.map +1 -0
- package/dist/neon.d.ts +8 -0
- package/dist/neon.js +167 -0
- package/dist/neon.js.map +1 -0
- package/dist/netlify.d.ts +18 -0
- package/dist/netlify.js +436 -0
- package/dist/netlify.js.map +1 -0
- package/dist/planetscale.d.ts +10 -0
- package/dist/planetscale.js +311 -0
- package/dist/planetscale.js.map +1 -0
- package/dist/providers.d.ts +26 -0
- package/dist/providers.js +36 -0
- package/dist/providers.js.map +1 -0
- package/dist/recipes.d.ts +167 -0
- package/dist/recipes.js +246 -0
- package/dist/recipes.js.map +1 -0
- package/dist/secrets.d.ts +72 -0
- package/dist/secrets.js +476 -0
- package/dist/secrets.js.map +1 -0
- package/dist/sigv4.d.ts +56 -0
- package/dist/sigv4.js +118 -0
- package/dist/sigv4.js.map +1 -0
- package/dist/supabase.d.ts +9 -0
- package/dist/supabase.js +385 -0
- package/dist/supabase.js.map +1 -0
- package/dist/vercel.d.ts +8 -0
- package/dist/vercel.js +475 -0
- package/dist/vercel.js.map +1 -0
- package/dist/xata.d.ts +8 -0
- package/dist/xata.js +142 -0
- package/dist/xata.js.map +1 -0
- package/dist/xml.d.ts +25 -0
- package/dist/xml.js +211 -0
- package/dist/xml.js.map +1 -0
- package/package.json +58 -3
- package/recipes/amplify.yaml +147 -0
- package/recipes/auth0.yaml +178 -0
- package/recipes/azure_swa.yaml +116 -0
- package/recipes/cloud_run.yaml +97 -0
- package/recipes/cloudflare.yaml +108 -0
- package/recipes/cockroachdb.yaml +132 -0
- package/recipes/configcat.yaml +123 -0
- package/recipes/datadog.yaml +136 -0
- package/recipes/firebase.yaml +84 -0
- package/recipes/flagsmith.yaml +98 -0
- package/recipes/fly.yaml +97 -0
- package/recipes/fly_machines.yaml +67 -0
- package/recipes/gcs.yaml +102 -0
- package/recipes/github.yaml +123 -0
- package/recipes/growthbook.yaml +124 -0
- package/recipes/heroku.yaml +98 -0
- package/recipes/honeycomb.yaml +89 -0
- package/recipes/inngest.yaml +97 -0
- package/recipes/kinde.yaml +120 -0
- package/recipes/mongodb_atlas.yaml +119 -0
- package/recipes/okta.yaml +177 -0
- package/recipes/posthog.yaml +127 -0
- package/recipes/postmark.yaml +105 -0
- package/recipes/postmark_server.yaml +93 -0
- package/recipes/prisma.yaml +150 -0
- package/recipes/qstash.yaml +134 -0
- package/recipes/railway.yaml +130 -0
- package/recipes/render.yaml +103 -0
- package/recipes/resend.yaml +130 -0
- package/recipes/s3.yaml +108 -0
- package/recipes/sendgrid.yaml +165 -0
- package/recipes/sentry.yaml +158 -0
- package/recipes/split.yaml +121 -0
- package/recipes/statsig.yaml +124 -0
- package/recipes/stripe.yaml +310 -0
- package/recipes/stytch.yaml +113 -0
- package/recipes/svix.yaml +109 -0
- package/recipes/turso.yaml +98 -0
- package/recipes/unleash.yaml +149 -0
- package/recipes/upstash.yaml +130 -0
- package/recipes/vercel.yaml +116 -0
- package/recipes/workos.yaml +70 -0
package/dist/recipes.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipes: verified `http` specs for one provider's operations, shipped as YAML in `packages/adapters/recipes/`
|
|
3
|
+
* (one file per provider), so that a plan line names an operation and fills in its typed params instead of writing
|
|
4
|
+
* request templates (ADR 0020, docs/recipes.md).
|
|
5
|
+
*
|
|
6
|
+
* providers: { http: { cloudflare: { recipe: cloudflare } } } # optional: the recipe's API defaults
|
|
7
|
+
* - { id: dns, adapter: http, op: resource, recipe: cloudflare.dns_cname, zone_id: …, name: …, target: … }
|
|
8
|
+
*
|
|
9
|
+
* A recipe line expands, before anything else reads it, into the `http.resource`, `http.list_item` or `http.action` params the
|
|
10
|
+
* recipe declares, with `{ param: <name> }` values and `{<name>}` path placeholders filled from the line. Identity
|
|
11
|
+
* is never the recipe's text: the ledger records the resolved API block (base URL, credential variable names,
|
|
12
|
+
* headers, encoding) and the keys and record ids the expanded requests produce, exactly as for a hand-written
|
|
13
|
+
* line. Pure apart from reading the shipped files once.
|
|
14
|
+
*/
|
|
15
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import { parse as parseYaml } from "yaml";
|
|
18
|
+
import { SponsonError, markerKind } from "@sponson/core";
|
|
19
|
+
import { paramError } from "./common.js";
|
|
20
|
+
import { isObject } from "./http.js";
|
|
21
|
+
/** Where the shipped recipe files are, in the source tree and in the published package alike. */
|
|
22
|
+
export const RECIPES_DIR = fileURLToPath(new URL("../recipes/", import.meta.url));
|
|
23
|
+
/**
|
|
24
|
+
* The environment variables a recipe's API block reads its credential from, in the order the block names them.
|
|
25
|
+
* Empty for a recipe without an API block and for a token a command prints (`az`, `gcloud`: their own login).
|
|
26
|
+
*/
|
|
27
|
+
export function recipeCredentialEnv(recipe) {
|
|
28
|
+
const auth = recipe.api?.auth;
|
|
29
|
+
if (!isObject(auth))
|
|
30
|
+
return [];
|
|
31
|
+
const names = (o, keys) => (isObject(o) ? keys.flatMap((k) => (typeof o[k] === "string" ? [o[k]] : [])) : []);
|
|
32
|
+
if (Array.isArray(auth.headers))
|
|
33
|
+
return auth.headers.flatMap((h) => names(h, ["value_env"]));
|
|
34
|
+
return [
|
|
35
|
+
...names(auth, ["bearer_env", "value_env"]),
|
|
36
|
+
...names(auth.oauth2_client_credentials, ["client_id_env", "client_secret_env"]),
|
|
37
|
+
...names(auth.aws_sigv4, ["access_key_id_env", "secret_access_key_env"]),
|
|
38
|
+
...names(auth.digest, ["user_env", "password_env"]),
|
|
39
|
+
...names(auth.basic, ["user_env", "password_env"]),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
const ADAPTER = "http";
|
|
43
|
+
const cache = new Map();
|
|
44
|
+
/** Recipes made known without a file (`useRecipe`), by provider. */
|
|
45
|
+
const unshipped = new Map();
|
|
46
|
+
/** The providers that have a recipe, sorted. */
|
|
47
|
+
export function recipeNames() {
|
|
48
|
+
const files = readdirSync(RECIPES_DIR)
|
|
49
|
+
.filter((f) => f.endsWith(".yaml"))
|
|
50
|
+
.map((f) => f.slice(0, -".yaml".length));
|
|
51
|
+
return [...new Set([...files, ...unshipped.keys()])].sort();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Make a recipe known for this process as if it were shipped, until the returned function is called. For tests of
|
|
55
|
+
* code that recipes drive (the adapter's own tests use it for a list item recipe); not exported by the package.
|
|
56
|
+
*/
|
|
57
|
+
export function useRecipe(recipe) {
|
|
58
|
+
unshipped.set(recipe.provider, recipe);
|
|
59
|
+
cache.set(recipe.provider, recipe);
|
|
60
|
+
return () => {
|
|
61
|
+
unshipped.delete(recipe.provider);
|
|
62
|
+
cache.delete(recipe.provider);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** A provider's recipe; PARAM_INVALID naming the known ones when there is none. */
|
|
66
|
+
export function loadRecipe(provider, param = "recipe") {
|
|
67
|
+
const cached = cache.get(provider);
|
|
68
|
+
if (cached)
|
|
69
|
+
return cached;
|
|
70
|
+
const known = recipeNames();
|
|
71
|
+
if (!known.includes(provider))
|
|
72
|
+
throw paramError(ADAPTER, `no recipe for \`${provider}\` (known: ${known.join(", ") || "none"})`, param);
|
|
73
|
+
const recipe = parseYaml(readFileSync(`${RECIPES_DIR}${provider}.yaml`, "utf8"));
|
|
74
|
+
// A malformed shipped file is a bug of this package (packages/adapters/src/recipes.test.ts checks every one).
|
|
75
|
+
if (!isObject(recipe) || recipe.provider !== provider || !isObject(recipe.ops) || (recipe.api !== undefined && !isObject(recipe.api))) {
|
|
76
|
+
throw new SponsonError("INTERNAL", `${ADAPTER}: recipes/${provider}.yaml is malformed`, { adapter: ADAPTER, recipe: provider });
|
|
77
|
+
}
|
|
78
|
+
cache.set(provider, recipe);
|
|
79
|
+
return recipe;
|
|
80
|
+
}
|
|
81
|
+
/** Every shipped recipe. */
|
|
82
|
+
export function loadRecipes() {
|
|
83
|
+
return recipeNames().map((p) => loadRecipe(p));
|
|
84
|
+
}
|
|
85
|
+
/** A line's `recipe: <provider>.<op>`, located. */
|
|
86
|
+
export function recipeOp(ref) {
|
|
87
|
+
if (typeof ref !== "string" || !/^[a-z0-9][a-z0-9_-]*\.[a-z0-9_]+$/.test(ref)) {
|
|
88
|
+
throw paramError(ADAPTER, "`recipe` must be `<provider>.<op>`, e.g. `cloudflare.dns_cname` (see docs/recipes.md)", "recipe");
|
|
89
|
+
}
|
|
90
|
+
const [provider, name] = ref.split(".");
|
|
91
|
+
const recipe = loadRecipe(provider);
|
|
92
|
+
const op = recipe.ops[name];
|
|
93
|
+
if (!op)
|
|
94
|
+
throw paramError(ADAPTER, `recipe \`${provider}\` has no op \`${name}\` (known: ${Object.keys(recipe.ops).join(", ")})`, "recipe");
|
|
95
|
+
return { recipe, name, op };
|
|
96
|
+
}
|
|
97
|
+
/** The API a line uses: its `api`, or for a recipe line without one, the recipe's provider. */
|
|
98
|
+
export function lineApi(params) {
|
|
99
|
+
if (params.api !== undefined || typeof params.recipe !== "string")
|
|
100
|
+
return params.api;
|
|
101
|
+
return params.recipe.split(".")[0];
|
|
102
|
+
}
|
|
103
|
+
/** Params of a recipe line that are the line's own, not the recipe's. */
|
|
104
|
+
const LINE_PARAMS = ["api", "recipe", "destroy", "credential"];
|
|
105
|
+
/** A value the engine fills in later or keeps as it is: a reference, a marker, an uninterpolated `${…}`. */
|
|
106
|
+
function isDeferred(v) {
|
|
107
|
+
if (markerKind(v) !== null)
|
|
108
|
+
return true;
|
|
109
|
+
if (typeof v === "string")
|
|
110
|
+
return v.includes("${");
|
|
111
|
+
if (!isObject(v))
|
|
112
|
+
return false;
|
|
113
|
+
const keys = Object.keys(v);
|
|
114
|
+
return keys.length === 1 && ["from", "secret", "keep"].includes(keys[0]);
|
|
115
|
+
}
|
|
116
|
+
const TYPE_CHECK = {
|
|
117
|
+
string: (v) => typeof v === "string",
|
|
118
|
+
integer: (v) => Number.isInteger(v),
|
|
119
|
+
number: (v) => typeof v === "number" && Number.isFinite(v),
|
|
120
|
+
boolean: (v) => typeof v === "boolean",
|
|
121
|
+
list: (v) => Array.isArray(v),
|
|
122
|
+
map: (v) => isObject(v),
|
|
123
|
+
};
|
|
124
|
+
function checkValue(where, name, p, v) {
|
|
125
|
+
if (isDeferred(v))
|
|
126
|
+
return;
|
|
127
|
+
const fail = (why) => paramError(ADAPTER, `${where}: \`${name}\` ${why}`, name);
|
|
128
|
+
if (!TYPE_CHECK[p.type](v))
|
|
129
|
+
throw fail(`must be ${p.type === "integer" ? "an" : "a"} ${p.type} (${p.description})`);
|
|
130
|
+
if (p.enum && !p.enum.some((e) => e === v))
|
|
131
|
+
throw fail(`must be one of ${p.enum.map((e) => JSON.stringify(e)).join(", ")}`);
|
|
132
|
+
if (p.pattern && typeof v === "string" && !new RegExp(p.pattern).test(v))
|
|
133
|
+
throw fail(`must match ${p.pattern} (${p.description})`);
|
|
134
|
+
}
|
|
135
|
+
/** The value of every param the line sets or the recipe defaults, checked; PARAM_INVALID naming the param otherwise. */
|
|
136
|
+
export function recipeValues(params) {
|
|
137
|
+
const { recipe, name, op } = recipeOp(params.recipe);
|
|
138
|
+
const where = `recipe ${recipe.provider}.${name}`;
|
|
139
|
+
const declared = Object.keys(op.params);
|
|
140
|
+
const extra = Object.keys(params).find((k) => !LINE_PARAMS.includes(k) && !declared.includes(k));
|
|
141
|
+
if (extra)
|
|
142
|
+
throw paramError(ADAPTER, `${where}: \`${extra}\` is not one of its params (known: ${declared.join(", ")})`, extra);
|
|
143
|
+
const values = {};
|
|
144
|
+
for (const [p, spec] of Object.entries(op.params)) {
|
|
145
|
+
const v = params[p] ?? spec.default;
|
|
146
|
+
if (v === undefined || v === null) {
|
|
147
|
+
if (spec.required)
|
|
148
|
+
throw paramError(ADAPTER, `${where}: \`${p}\` is required: ${spec.description}`, p);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
checkValue(where, p, spec, v);
|
|
152
|
+
values[p] = v;
|
|
153
|
+
}
|
|
154
|
+
return values;
|
|
155
|
+
}
|
|
156
|
+
/** `{ param: <name> }`, the one template form of a recipe's http spec. */
|
|
157
|
+
function paramRef(v) {
|
|
158
|
+
return isObject(v) && Object.keys(v).length === 1 && typeof v.param === "string" ? v.param : undefined;
|
|
159
|
+
}
|
|
160
|
+
/** `{ join: [ … ] }`'s parts, when `v` is one: the other template form, concatenating whole values. */
|
|
161
|
+
function joinParts(v) {
|
|
162
|
+
return isObject(v) && Object.keys(v).length === 1 && Array.isArray(v.join) ? v.join : undefined;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* `{ join: [<part>, …] }`: the parts (literal strings, numbers, or `{ param: <name> }`) as one string, such as a
|
|
166
|
+
* preview URL and a path. A part that is not known yet (a reference, a marker) stands for the whole value, so a
|
|
167
|
+
* pending URL makes the joined value pending; a param without a value removes the value. Never anything richer:
|
|
168
|
+
* a recipe stays data (ADR 0020, "Amendment").
|
|
169
|
+
*/
|
|
170
|
+
function join(parts, values) {
|
|
171
|
+
const filled = parts.map((p) => substitute(p, values));
|
|
172
|
+
if (filled.some((p) => p === undefined))
|
|
173
|
+
return undefined;
|
|
174
|
+
// `${ctx.*}` inside a string joins like any text; a marker or a `{ from }` the engine has not resolved does not.
|
|
175
|
+
const deferred = filled.find((p) => markerKind(p) !== null || isObject(p));
|
|
176
|
+
if (deferred !== undefined)
|
|
177
|
+
return deferred;
|
|
178
|
+
return filled.map((p) => String(p)).join("");
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* `tpl` with every `{ param: <name> }` replaced by its value (a param without one removes its map key or list
|
|
182
|
+
* item) and every `{ join: [...] }` by its parts joined.
|
|
183
|
+
*/
|
|
184
|
+
export function substitute(tpl, values) {
|
|
185
|
+
const ref = paramRef(tpl);
|
|
186
|
+
if (ref !== undefined)
|
|
187
|
+
return values[ref];
|
|
188
|
+
const parts = joinParts(tpl);
|
|
189
|
+
if (parts !== undefined)
|
|
190
|
+
return join(parts, values);
|
|
191
|
+
if (Array.isArray(tpl))
|
|
192
|
+
return tpl.map((x) => substitute(x, values)).filter((x) => x !== undefined);
|
|
193
|
+
if (!isObject(tpl))
|
|
194
|
+
return tpl;
|
|
195
|
+
const out = {};
|
|
196
|
+
for (const [k, v] of Object.entries(tpl)) {
|
|
197
|
+
const s = substitute(v, values);
|
|
198
|
+
if (s !== undefined)
|
|
199
|
+
out[k] = s;
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* A line's params as the `http.<kind>` op reads them: unchanged without `recipe`, else the recipe's spec with the
|
|
205
|
+
* line's values filled in (`vars` holds every value, for the `{<name>}` path placeholders).
|
|
206
|
+
*/
|
|
207
|
+
export function expandRecipe(params, kind) {
|
|
208
|
+
if (params.recipe === undefined)
|
|
209
|
+
return params;
|
|
210
|
+
const { recipe, name, op } = recipeOp(params.recipe);
|
|
211
|
+
if (op.kind !== kind)
|
|
212
|
+
throw paramError(ADAPTER, `recipe ${recipe.provider}.${name} is an \`http.${op.kind}\` recipe: write \`op: ${op.kind}\``, "recipe");
|
|
213
|
+
const values = recipeValues(params);
|
|
214
|
+
const spec = substitute(op.http, values);
|
|
215
|
+
const destroy = recipeDestroy(`recipe ${recipe.provider}.${name}`, op, params.destroy);
|
|
216
|
+
// A recipe without an API block (only `url` actions) gives the line no `api` unless it writes one.
|
|
217
|
+
const api = recipe.api ? lineApi(params) : params.api;
|
|
218
|
+
const credential = params.credential !== undefined ? { credential: params.credential } : {};
|
|
219
|
+
return { ...spec, ...(api !== undefined ? { api } : {}), vars: values, ...(destroy !== undefined ? { destroy } : {}), ...credential };
|
|
220
|
+
}
|
|
221
|
+
/** The line's `destroy`, or the op's default; `delete` of an op the provider cannot delete is PARAM_INVALID. */
|
|
222
|
+
function recipeDestroy(where, op, line) {
|
|
223
|
+
if (op.destroy === "never" && line !== undefined && line !== "keep") {
|
|
224
|
+
throw paramError(ADAPTER, `${where}: the provider offers no way to delete what it makes, so it is always left in place: remove \`destroy\` or write \`destroy: keep\``, "destroy");
|
|
225
|
+
}
|
|
226
|
+
return line ?? (op.destroy === undefined ? undefined : "keep");
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* A `providers.http.<api>` block with `recipe:`, resolved: the recipe's API defaults, then the block's own keys
|
|
230
|
+
* over them. Blocks without `recipe:` are returned as they are. The result never names the recipe, so it (and with
|
|
231
|
+
* it the ledger identity) is the same as a hand-written block with the same values.
|
|
232
|
+
*/
|
|
233
|
+
export function resolveRecipeApi(block, where) {
|
|
234
|
+
if (block.recipe === undefined)
|
|
235
|
+
return block;
|
|
236
|
+
const known = recipeNames();
|
|
237
|
+
const { recipe: provider, ...overrides } = block;
|
|
238
|
+
if (typeof provider !== "string" || !known.includes(provider)) {
|
|
239
|
+
throw new SponsonError("PLAN_INVALID", `${ADAPTER}: ${where}.recipe: no recipe \`${String(provider)}\` (known: ${known.join(", ")})`, { adapter: ADAPTER, key: `${where}.recipe` });
|
|
240
|
+
}
|
|
241
|
+
const api = loadRecipe(provider).api;
|
|
242
|
+
if (!api)
|
|
243
|
+
throw new SponsonError("PLAN_INVALID", `${ADAPTER}: ${where}.recipe: recipe \`${provider}\` has no API block (its ops call the app's own URL)`, { adapter: ADAPTER, key: `${where}.recipe` });
|
|
244
|
+
return { ...api, ...overrides };
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,iGAAiG;AACjG,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AA6HlF;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA2B;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC;IAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,IAAc,EAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3I,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC7F,OAAO;QACL,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC3C,GAAG,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;QAChF,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;QACxE,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACnD,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,MAAM,CAAC;AACvB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC,oEAAoE;AACpE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE5C,gDAAgD;AAChD,MAAM,UAAU,WAAW;IACzB,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,KAAK,GAAG,QAAQ;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,MAAM,UAAU,CAAC,OAAO,EAAE,mBAAmB,QAAQ,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC;IACxI,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,WAAW,GAAG,QAAQ,OAAO,EAAE,MAAM,CAAC,CAAW,CAAC;IAC3F,8GAA8G;IAC9G,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACtI,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,GAAG,OAAO,aAAa,QAAQ,oBAAoB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClI,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,QAAQ,CAAC,GAAY;IACnC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9E,MAAM,UAAU,CAAC,OAAO,EAAE,uFAAuF,EAAE,QAAQ,CAAC,CAAC;IAC/H,CAAC;IACD,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE;QAAE,MAAM,UAAU,CAAC,OAAO,EAAE,YAAY,QAAQ,kBAAkB,IAAI,cAAc,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5I,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC9B,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,OAAO,CAAC,MAA+B;IACrD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IACrF,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,yEAAyE;AACzE,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAE/D,4GAA4G;AAC5G,SAAS,UAAU,CAAC,CAAU;IAC5B,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,GAAqD;IACnE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ;IACpC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS;IACtC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7B,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,SAAS,UAAU,CAAC,KAAa,EAAE,IAAY,EAAE,CAAc,EAAE,CAAU;IACzE,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO;IAC1B,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IACxF,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;IACpH,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5H,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;AACrI,CAAC;AAED,wHAAwH;AACxH,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,UAAU,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACjG,IAAI,KAAK;QAAE,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,KAAK,uCAAuC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/H,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ;gBAAE,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,mBAAmB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;YACvG,SAAS;QACX,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0EAA0E;AAC1E,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACzG,CAAC;AAED,uGAAuG;AACvG,SAAS,SAAS,CAAC,CAAU;IAC3B,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAClG,CAAC;AAED;;;;;GAKG;AACH,SAAS,IAAI,CAAC,KAAgB,EAAE,MAA+B;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1D,iHAAiH;IACjH,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,MAA+B;IACtE,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IACpG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/B,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAA+B,EAAE,IAAsB;IAClF,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI;QAAE,MAAM,UAAU,CAAC,OAAO,EAAE,UAAU,MAAM,CAAC,QAAQ,IAAI,IAAI,iBAAiB,EAAE,CAAC,IAAI,0BAA0B,EAAE,CAAC,IAAI,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1J,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAA4B,CAAC;IACpE,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACvF,mGAAmG;IACnG,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC;AACxI,CAAC;AAED,gHAAgH;AAChH,SAAS,aAAa,CAAC,KAAa,EAAE,EAAY,EAAE,IAAa;IAC/D,IAAI,EAAE,CAAC,OAAO,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpE,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,KAAK,oIAAoI,EAAE,SAAS,CAAC,CAAC;IACrL,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA8B,EAAE,KAAa;IAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IACjD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,GAAG,OAAO,KAAK,KAAK,wBAAwB,MAAM,CAAC,QAAQ,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC,CAAC;IACtL,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,GAAG,OAAO,KAAK,KAAK,qBAAqB,QAAQ,sDAAsD,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,SAAS,EAAE,CAAC,CAAC;IACxM,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type SecretSource } from "@sponson/core";
|
|
2
|
+
/** Runs a CLI and returns its stdout. Injected in tests so no real `doppler`/`op`/`aws` is needed. */
|
|
3
|
+
export type Exec = (file: string, args: string[], env: NodeJS.ProcessEnv) => Promise<string>;
|
|
4
|
+
/**
|
|
5
|
+
* Runs the real binary from PATH; rejects with its stderr when it fails. A binary that cannot be started keeps the
|
|
6
|
+
* system error's `code` (`ENOENT`, `EACCES`), so the caller can say what is wrong instead of echoing it.
|
|
7
|
+
*/
|
|
8
|
+
export declare const defaultExec: Exec;
|
|
9
|
+
/** `env://NAME` → process environment. Zero configuration; the CI default. */
|
|
10
|
+
export declare const envSecretSource: SecretSource;
|
|
11
|
+
/** `doppler://project/config/NAME` → `doppler secrets get`. Uses the CLI's login or DOPPLER_TOKEN from the env. */
|
|
12
|
+
export declare function dopplerSecretSource(exec?: Exec): SecretSource;
|
|
13
|
+
/** `op://vault/item/field` → `op read`, which accepts the reference as-is. */
|
|
14
|
+
export declare function opSecretSource(exec?: Exec): SecretSource;
|
|
15
|
+
/**
|
|
16
|
+
* `aws-sm://<secret-id>` → `aws secretsmanager get-secret-value`, through the `aws` CLI so the AWS SDK stays out of
|
|
17
|
+
* the dependency tree. The secret id is a name or an ARN; region, profile and credentials come from the CLI's own
|
|
18
|
+
* conventions (`AWS_REGION`, `AWS_PROFILE`, ...). `aws-sm://<secret-id>#<key>` picks one key of a JSON secret, the
|
|
19
|
+
* shape the AWS console creates for key/value secrets.
|
|
20
|
+
*/
|
|
21
|
+
export declare function awsSecretsManagerSource(exec?: Exec): SecretSource;
|
|
22
|
+
/**
|
|
23
|
+
* `gcp-sm://<project>/<secret>[/<version>]` → `gcloud secrets versions access`, through the `gcloud` CLI so the Google
|
|
24
|
+
* SDK stays out of the dependency tree. The version defaults to `latest`; credentials come from the CLI's own
|
|
25
|
+
* conventions (`gcloud auth`, `CLOUDSDK_*`, `GOOGLE_APPLICATION_CREDENTIALS`). The project is part of the reference
|
|
26
|
+
* so a plan never depends on whichever project the runner's gcloud happens to have configured.
|
|
27
|
+
*/
|
|
28
|
+
export declare function gcpSecretManagerSource(exec?: Exec): SecretSource;
|
|
29
|
+
/**
|
|
30
|
+
* `infisical://<projectId>/<env>/[<folder>/…/]<NAME>` → `infisical secrets get`, through the Infisical CLI
|
|
31
|
+
* (https://infisical.com/docs/cli/commands/secrets). The folders become `--path` (default `/`). Credentials come
|
|
32
|
+
* from the CLI's own conventions: `INFISICAL_TOKEN` (or `INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN`) for a machine
|
|
33
|
+
* identity, else the CLI's login; `INFISICAL_DOMAIN` for EU Cloud or a self-hosted instance. The project id is part of
|
|
34
|
+
* the reference because a machine identity has no `.infisical.json` to take it from.
|
|
35
|
+
*
|
|
36
|
+
* JSON output, not `--plain`: with `--plain` an unknown name prints nothing at all (exit 0), indistinguishable from
|
|
37
|
+
* an empty secret; with `--output json` it prints the entry with the value `*not found*`, which is refused here.
|
|
38
|
+
*/
|
|
39
|
+
export declare function infisicalSecretSource(exec?: Exec): SecretSource;
|
|
40
|
+
/**
|
|
41
|
+
* `azure-kv://<vault>/<name>[/<version>]` → `az keyvault secret show`, through the Azure CLI so neither the Azure SDK
|
|
42
|
+
* nor an Entra ID token flow enters the dependency tree. The CLI rather than `GET {vault}/secrets/{name}` with a token
|
|
43
|
+
* from `az account get-access-token`: one process instead of two, and the CLI already knows the vault DNS suffix of
|
|
44
|
+
* the signed-in cloud (`vault.azure.net`, `vault.azure.cn`, `vault.usgovcloudapi.net`) and every way to sign in
|
|
45
|
+
* (`az login`, a service principal, a managed identity, federated CI credentials).
|
|
46
|
+
* https://learn.microsoft.com/en-us/cli/azure/keyvault/secret#az-keyvault-secret-show
|
|
47
|
+
*/
|
|
48
|
+
export declare function azureKeyVaultSource(exec?: Exec): SecretSource;
|
|
49
|
+
/**
|
|
50
|
+
* `bws://<secret-id>` → `bws secret get`, through the Bitwarden Secrets Manager CLI
|
|
51
|
+
* (https://bitwarden.com/help/secrets-manager-cli/). The machine account's access token comes from
|
|
52
|
+
* `BWS_ACCESS_TOKEN`, a self-hosted server from `BWS_SERVER_URL` (both read by the CLI itself: crates/bws/src/cli.rs
|
|
53
|
+
* in bitwarden/sdk-sm). `--color no`: the CLI colours its JSON whenever it believes the terminal supports colour,
|
|
54
|
+
* which `FORCE_COLOR` in CI makes it believe.
|
|
55
|
+
*/
|
|
56
|
+
export declare function bitwardenSecretsManagerSource(exec?: Exec): SecretSource;
|
|
57
|
+
/**
|
|
58
|
+
* `vault://<mount>/<path>#<key>` → HashiCorp Vault's KV v2 "read secret version", `GET /v1/<mount>/data/<path>`
|
|
59
|
+
* (https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2), over the adapters' HTTP client, no SDK. The
|
|
60
|
+
* address is `VAULT_ADDR`, the token `VAULT_TOKEN` (sent as `X-Vault-Token`), and `VAULT_NAMESPACE`, when set, is
|
|
61
|
+
* sent as `X-Vault-Namespace` (Vault Enterprise, HCP Vault Dedicated: https://developer.hashicorp.com/vault/api-docs).
|
|
62
|
+
* The mount is the first segment; the latest version is read. `#key` picks one key of the secret's map.
|
|
63
|
+
*/
|
|
64
|
+
export declare const vaultSecretSource: SecretSource;
|
|
65
|
+
/**
|
|
66
|
+
* `op-connect://<vault>/<item>/[<section>/]<field>` → a 1Password Connect server's REST API
|
|
67
|
+
* (https://www.1password.dev/connect/api-reference/): `GET /v1/vaults/{vault}/items/{item}`, bearer
|
|
68
|
+
* `OP_CONNECT_TOKEN`, at `OP_CONNECT_HOST` (the variables 1Password's own Connect SDKs and `op` read). Vaults and
|
|
69
|
+
* items are named by id or by name / title (looked up with `GET /v1/vaults?filter=name eq "…"` and
|
|
70
|
+
* `GET /v1/vaults/{vault}/items?filter=title eq "…"`; a name must be unique); fields by id or label.
|
|
71
|
+
*/
|
|
72
|
+
export declare const opConnectSecretSource: SecretSource;
|