@geekmidas/manifest 10.0.0-alpha.5 → 10.0.0-alpha.6
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 +0 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -45
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +17 -45
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,32 +37,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
37
37
|
*/
|
|
38
38
|
const DEFAULT_POSTGRES_VERSION = 18;
|
|
39
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
40
|
* What each kind may derive from.
|
|
67
41
|
*
|
|
68
42
|
* Small enough to state exhaustively, and stating it makes cycles impossible
|
|
@@ -1005,7 +979,6 @@ function flattenManifestField(field) {
|
|
|
1005
979
|
}
|
|
1006
980
|
|
|
1007
981
|
//#endregion
|
|
1008
|
-
exports.DEFAULT_APP_CODE = DEFAULT_APP_CODE;
|
|
1009
982
|
exports.DEFAULT_POSTGRES_VERSION = DEFAULT_POSTGRES_VERSION;
|
|
1010
983
|
exports.DERIVES_FROM = DERIVES_FROM;
|
|
1011
984
|
exports.IllegalDerivation = IllegalDerivation;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["DEFAULT_POSTGRES_VERSION: PostgresVersion","DERIVES_FROM: Readonly<Record<DerivedKind, readonly string[]>>","PUBLIC: {\n\treadonly [K in keyof ProvidesByKind]: readonly (keyof ProvidesByKind[K])[];\n}","input: string","canonical: string","id: string","of: string","available: readonly string[]","kind: string","parentKind: string","allowed: readonly string[]","name: string","id: string","role: string","input: string","value: string","scope: { stage: string; app: string }","scope: readonly string[]","urls: readonly string[]","shared: string[]","kind: DeclarationKind","declaration: Declaration","manifest: ConstructManifest","ordered: string[]","id: string","id: ConstructId","callers: string[]","PUBLIC_PREFIX: Record<SiteDeclaration['variant'], string>","declaration: SiteDeclaration","keys: Record<string, string>","field: ManifestField<T> | undefined"],"sources":["../src/declaration.ts","../src/errors.ts","../../../node_modules/.pnpm/lodash.snakecase@4.1.1/node_modules/lodash.snakecase/index.js","../src/naming.ts","../src/derive.ts","../src/index.ts"],"sourcesContent":["/**\n * The construct manifest — the contract between what an application declares\n * and what a target adapter provisions.\n *\n * Kinds are added here as each one lands, not up front: a declaration for a\n * construct nobody has built yet is a guess that the implementation will\n * contradict. See `docs/design/constructs-paradigm.md`.\n */\n\n/**\n * A construct's canonical id — PascalCase, unique within the manifest.\n *\n * Inputs canonicalise, so `uploads`, `Uploads`, `user_uploads`, and\n * `user-uploads` are the *same* id rather than four that collide. Everything\n * else derives from it: the service key is its `Uncapitalize`, the env prefix\n * its SCREAMING_SNAKE form, the cloud name its kebab form scoped by stage and\n * app.\n */\nexport type ConstructId = string;\n\ntype Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';\n\n/**\n * Constrains a construct name at the point it is written.\n *\n * Resolves to the name itself when valid, and otherwise to a string explaining\n * why — so the compiler reports *\"not assignable to type 'a construct name\n * cannot start with a digit'\"* rather than the unhelpful `never`.\n *\n * Only the cases a template-literal type can see are caught here; `canonicalId`\n * enforces the rest at runtime, which is also what covers JavaScript callers.\n *\n * @example new ObjectStorage('Uploads') // ok\n * @example new ObjectStorage('2fa') // a construct name cannot start with a digit\n */\nexport type ConstructName<S extends string> = S extends ''\n\t? 'a construct name cannot be empty'\n\t: S extends `${Digit}${string}`\n\t\t? 'a construct name cannot start with a digit'\n\t\t: S;\n\n/** Shared by every declaration. */\nexport interface Node {\n\tid: ConstructId;\n\t/**\n\t * Env keys this construct resolves onto anything that depends on it.\n\t * Names only — the values are composed by the adapter from the provisioned\n\t * resource's own attributes.\n\t */\n\tprovides?: readonly string[];\n\t/**\n\t * Env keys this construct needs. Derivable from `dependencies`, so it is an\n\t * assertion rather than an input: the adapter composes env from the edges and\n\t * checks the result against this, which catches app/infra drift at synth.\n\t */\n\trequires?: readonly string[];\n}\n\n/**\n * A dependency edge. Records only *what* is depended on — never permissions.\n * From one edge the framework derives env and the runtime binding; a target\n * adapter separately derives cloud access.\n */\nexport interface Dependency<TTarget extends ConstructId = ConstructId> {\n\t/**\n\t * The {@link ConstructId} of the consumed construct. Left open here because a\n\t * declaration is written before the manifest that contains it; once assembled,\n\t * `IdsOf` narrows it and the build's reference-integrity check enforces it.\n\t */\n\ttarget: TTarget;\n\tkind: DeclarationKind;\n}\n\n/** Anything with a handler. */\nexport interface Fn extends Node {\n\thandler: string;\n\tdependencies: readonly Dependency[];\n}\n\n// ---------------------------------------------------------------------------\n// Kinds\n// ---------------------------------------------------------------------------\n\n/** Blob storage. `--target=aws` provisions a bucket. */\nexport interface ObjectsDeclaration extends Node {\n\tkind: 'objects';\n\tversioned?: boolean;\n}\n\n/**\n * A domain that serves a bucket's objects.\n *\n * Its own construct rather than a flag on the bucket, because three things it\n * has to express are not properties of a bucket: a surface can front several\n * origins, a bucket can have several surfaces over it, and issuing a\n * certificate and writing a DNS record is a domain lifecycle that has no\n * business living inside an `objects` provisioner. It shares its infrastructure\n * with a static site rather than with storage — a site is the same\n * distribution over a build output instead of over live contents.\n *\n * It derives from the bucket by `of`, which costs the one thing the flag gave\n * for free: the bucket alone no longer says whether it is served, and finding\n * out means finding whoever points at it. That is answered the way every other\n * derivation is — the reference check at manifest build, so an unresolvable\n * origin is a build failure and `gkm` can name, for any bucket, the surfaces\n * over it.\n *\n * Private by default. `open` is an exception list, because a bucket where\n * forgetting a flag publishes user uploads is the wrong default — and paths\n * rather than per-object flags, because a path pattern is what the\n * infrastructure actually enforces and a per-object ACL is a thing nobody\n * audits.\n *\n * \"Open\" never means the bucket is world-readable. It means the server serves\n * that path without a signature; the bucket is private in both cases.\n */\nexport interface FileServerDeclaration extends Node {\n\tkind: 'file-server';\n\t/** The bucket whose objects it serves. */\n\tof: ConstructId;\n\t/**\n\t * Paths served without a signature — everything else requires one.\n\t *\n\t * Globs, matched most-literally by the infrastructure: a CDN keys its\n\t * behaviours off path patterns, and a bucket policy names prefixes.\n\t */\n\topen?: readonly string[];\n}\n\n/**\n * Outbound email.\n *\n * Provides one `smtp://` URL and nothing else, because email is delivered over\n * SMTP whatever the provider — Mailpit locally, SES through its SMTP interface,\n * Resend and Postmark through theirs. There is no `provider` field here for the\n * same reason there is no `ses://` scheme: which service delivers the mail\n * differs between dev and prod, so by this design's own test it is stage-varying\n * config rather than a structural fact about the app.\n *\n * What *is* structural is only that the app sends mail at all. The sending\n * domain is not: it is `myapp.test` locally and `example.com` deployed, so it\n * fails the same test the provider does and resolves at deploy alongside every\n * other address.\n */\nexport interface EmailDeclaration extends Node {\n\tkind: 'email';\n}\n\n/**\n * A logical database, its schema, and the roles that reach it.\n *\n * Provides one key — the *runtime* role's URL. The owner URL exists but is\n * deliberately absent from `provides`: it is wired by the adapter straight into\n * the migrator and seeder this construct declares, so no edge in any manifest\n * can name it and nothing else can be granted it by mistake.\n */\n/**\n * The Postgres major versions this toolbox provisions.\n *\n * A union rather than a string, because the two targets that read it are not\n * equally forgiving: locally it becomes a container tag, where a typo yields a\n * confusing pull failure, and on AWS it becomes an engine version, where a\n * wrong value fails partway through a deploy. Both are better as a compile\n * error.\n *\n * The union is what this toolbox knows how to name, not a promise that every\n * target offers every one of them. A deployed stage is limited by the engine\n * catalogue in its region, so check before pinning an unusual version:\n *\n * ```\n * aws rds describe-db-engine-versions --engine postgres \\\n * --query 'DBEngineVersions[].EngineVersion' --output text\n * ```\n *\n * RDS offered 11 through 18 in `eu-west-1` when this was written. 11 and 12 are\n * left out because they are past upstream end-of-life: still provisionable, but\n * not something to make easy to reach for.\n */\nexport type PostgresVersion = 13 | 14 | 15 | 16 | 17 | 18;\n\n/**\n * The version used when a database names none.\n *\n * The point is not which number this is but that there is only one of them.\n * Local ran 18 while Aurora provisioned its own default of 17.7, and nothing in\n * any declaration recorded the difference — a stage could behave differently\n * from a developer's machine for a reason neither could see. Both now read\n * this.\n */\nexport const DEFAULT_POSTGRES_VERSION: PostgresVersion = 18;\n\nexport interface DatabaseDeclaration extends Node {\n\tkind: 'database';\n\tengine?: 'postgres';\n\t/**\n\t * The engine's major version, read by every target that provisions one.\n\t *\n\t * Declared rather than configured per target, because a version set in a\n\t * compose file and a version set in a deploy config are two statements of\n\t * one fact — and they had already drifted apart, silently, by a major.\n\t *\n\t * Defaults to {@link DEFAULT_POSTGRES_VERSION}.\n\t */\n\tversion?: PostgresVersion;\n\t/**\n\t * The schema, pinned on both roles' `search_path`. Names the role the schema\n\t * plays rather than restating the database's own name, so `app` reads\n\t * correctly beside `auth` and `pgboss`.\n\t */\n\tschema?: string;\n\t/**\n\t * Whether to provision the owner/runtime role split. Off falls back to the\n\t * cluster's master credential in both URLs — a deliberate downgrade, not a\n\t * default. See `roles: false` in the design doc.\n\t */\n\troles?: boolean;\n}\n\n/**\n * A read-only endpoint on an existing database or schema.\n *\n * Provisions no cluster of its own — `of` names the parent it reads from.\n * Read-only is enforced by the role's grants rather than by which endpoint it\n * resolves to, so falling back to the writer where no replica exists stays safe.\n */\nexport interface DatabaseReaderDeclaration extends Node {\n\tkind: 'database-reader';\n\tof: ConstructId;\n}\n\n/**\n * A second schema inside an existing database, with its own role(s) and URL.\n *\n * The mechanism behind tenancy: the parent's role holds no grant on these\n * tables at all. pg-boss is an instance of this rather than a special case.\n */\nexport interface DatabaseSchemaDeclaration extends Node {\n\tkind: 'database-schema';\n\tof: ConstructId;\n\tschema: string;\n}\n\n/**\n * A generated secret — a signing key, a token, anything with no address.\n *\n * It provides a value rather than a URL, which is why it is a node of its own\n * instead of a field on whatever needs it: the thing that generates it, the\n * thing that stores it, and the thing that reads it are three different systems\n * deployed, and one derived string locally.\n */\nexport interface SecretDeclaration extends Node {\n\tkind: 'secret';\n}\n\n/**\n * A third-party credential with a shape.\n *\n * Distinct from {@link SecretDeclaration} by *lifecycle*, which is the only\n * distinction worth having two kinds for. A secret is generated and rotated by\n * the platform — `gkm secrets`, `sst secret set` — and is one opaque string\n * whose name is its key. A credential is issued by someone else, arrives with\n * several fields, and is validated on the way in: a Stripe key pair, an OAuth\n * client, a webhook signing secret.\n *\n * It provides one key holding a JSON object, rather than one key per field.\n * That is what a secret manager actually stores, and it is also the only shape\n * that works with an arbitrary StandardSchema — the spec has no introspection\n * API, so enumerating a schema's fields means reaching into one library's\n * internals and being wrong for every other.\n */\nexport interface CredentialDeclaration extends Node {\n\tkind: 'credential';\n}\n\n/**\n * An identity provider somebody else runs.\n *\n * Provisions nothing — the issuer already exists — so a target's whole job is\n * to hand the process an issuer and an audience, and the verifier discovers the\n * rest at runtime.\n *\n * It is a node rather than a field on whatever authenticates through it because\n * two surfaces can name the same provider, and because *which* population a\n * surface admits is a fact worth reading off the graph: an admin console\n * authenticated by the customer auth server is a finding, and it is only\n * visible if both are declarations.\n */\nexport interface OidcDeclaration extends Node {\n\tkind: 'oidc';\n\t/**\n\t * The issuer, when it does not vary by deployment.\n\t *\n\t * Absent means it arrives in the environment instead — a staging tenant, a\n\t * per-customer directory. The audience is never here: it identifies one\n\t * deployment to the provider.\n\t */\n\tissuer?: string;\n}\n\n/**\n * A key/value cache.\n *\n * Provides one URL. What is *in* that URL is the backend's business — Upstash's\n * REST API, a Redis endpoint, or a table in a database — and the scheme is what\n * picks the client, exactly as it does for object storage.\n *\n * Two ways to declare one, and the difference is a real statement rather than a\n * spelling. `new Cache('Sessions')` says *this app caches*, leaving where to the\n * deployment; `orders.cache('Sessions')` says *this app caches in that\n * database*, which is a fact about the application and belongs in its code. The\n * second is the same strengthening `orders.schema('AuthDb')` is over declaring a\n * second database.\n */\nexport interface CacheDeclaration extends Node {\n\tkind: 'cache';\n\t/**\n\t * The database this cache lives in, when it lives in one.\n\t *\n\t * Present only for a cache derived from a database. It removes a guess the\n\t * backend selection otherwise has to make — \"the declared database\" is\n\t * unambiguous with one and arbitrary with two — and it means the table's\n\t * schema and the role that reaches it come from the parent rather than from\n\t * a second convention.\n\t */\n\tof?: ConstructId;\n\t/**\n\t * The table entries are kept in, resolved against the connection's\n\t * `search_path`. Defaults to `cache`.\n\t */\n\ttable?: string;\n}\n\n/**\n * An HTTP surface and the handlers mounted on it.\n *\n * The first kind that is not a resource in the ordinary sense: it owns an\n * address, and the functions it triggers are *nested inside it* rather than\n * listed beside it, because position carries the trigger — a handler here is\n * reached by its method and path and by nothing else.\n *\n * `authorizers` are names. A bare string is resolved by the target (`iam`), while\n * a {@link ConstructId} names a construct that carries its own implementation,\n * its database dependency, and its session typing.\n */\nexport interface RestApiDeclaration extends Node {\n\tkind: 'rest-api';\n\t/**\n\t * Where the process serving it is built from, relative to the workspace\n\t * root — the same thing a `site` says, for the same reason.\n\t *\n\t * A surface is a deploy unit: one of these is one server. Without it the\n\t * deploy had to ask the *config* which apps to build, and a surface could\n\t * never be its own process because it was not in that list. Two surfaces in\n\t * one app then had to share one container, which is how an auth server ended\n\t * up mounted into an API by a hook.\n\t *\n\t * Optional, and its absence is meaningful: a surface with no app of its own\n\t * is served by the surface that named it — an auth server mounted into the\n\t * API that called `.auth()` on it, rather than a second container nobody\n\t * asked for.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * The construct that authenticates this surface.\n\t *\n\t * An edge like any other — so the auth server learns this surface's origin,\n\t * and the two share a cookie domain — but a *named* one, because \"who\n\t * authenticates me\" is a different fact from \"who I happen to call\", and\n\t * only one of them decides what a request is allowed to be.\n\t *\n\t * It is the id rather than the client: what every endpoint consumes is\n\t * `verify(request) → Session | null`, and that is the one thing every\n\t * provider shares. A surface names its authenticator; the target decides\n\t * what verifying means.\n\t */\n\tauth?: ConstructId;\n\t/**\n\t * CORS tunables for this surface.\n\t *\n\t * *Who* may call it is never here — that is derived from the constructs\n\t * declaring an edge to this surface, and arrives as `<ID>_TRUSTED_ORIGINS`.\n\t * A hand-written origin list is the thing this model removes; these are the\n\t * knobs that genuinely cannot be derived from a graph.\n\t *\n\t * Omitted entirely, a surface still gets CORS — with the derived origins and\n\t * sensible defaults. There is nothing to opt into.\n\t */\n\tcors?: {\n\t\t/** Preflight cache lifetime in seconds. Default 86400. */\n\t\tmaxAge?: number;\n\t\t/** Whether the browser may send credentials. Default true. */\n\t\tcredentials?: boolean;\n\t\t/** Extra request headers to allow, beyond content-type and authorization. */\n\t\tallowHeaders?: readonly string[];\n\t\t/** Response headers the browser may read. */\n\t\texposeHeaders?: readonly string[];\n\t};\n\tauthorizers?: readonly string[];\n\t/** The authorizer applied where an endpoint names none. */\n\tdefaultAuthorizer?: string;\n\t/**\n\t * Every route on this surface.\n\t *\n\t * Complete, always — a manifest that says \"the routes are over there, run\n\t * this glob to find them\" is not a manifest, it is a pointer to one. An\n\t * earlier version carried a `routes` glob for an application's own API and\n\t * left this empty, which meant the document *claimed no routes* while five\n\t * existed. Being incomplete is a gap; being wrong is worse.\n\t *\n\t * So a surface takes its endpoints as a list and reads method, path and\n\t * handler off them. That also removes a duplicate: the glob was written once\n\t * in `gkm.config.ts` and again on the construct, two strings that could\n\t * disagree about the same thing.\n\t */\n\tendpoints: readonly RestApiEndpoint[];\n\t/**\n\t * Other surfaces this one calls.\n\t *\n\t * **Not a dependency, and deliberately not spelled like one.** A dependency\n\t * is an injection: `resolveEdges` gives a function exactly the constructs it\n\t * declared and nothing else, which is what makes least privilege fall out of\n\t * the graph instead of out of discipline. A surface-level `dependencies`\n\t * would hand *every route* on this API whatever the surface named — which is\n\t * precisely the over-granting that rule exists to prevent.\n\t *\n\t * What this records is weaker and only flows one way: it puts this API's\n\t * origin on the called surface's trusted-origin list. Nothing links from it,\n\t * nothing is granted by it, and per-route edges stay on the endpoints where\n\t * they belong.\n\t */\n\tcalls?: readonly Dependency[];\n}\n\n/** One glob, or several. Mirrors the CLI's `Routes` without depending on it. */\nexport type Glob = string | readonly string[];\n\n/**\n * How the process serving a declaration is built and run.\n *\n * The half of an application that a graph genuinely cannot derive. *What*\n * exists — a surface, a site, the edges between them — is declared and read\n * back from the manifest. *Where its source lives and which globs find its\n * code* is not derivable from anything: it is a fact about a directory.\n *\n * It lives on the declaration rather than in a config `apps` block because the\n * two were the same list written twice, and the copy in config was the one that\n * could disagree. A site declared `path: 'apps/web'` and an app entry declared\n * `path: 'apps/web'`, and nothing checked them against each other; a surface\n * that config had no entry for simply never deployed.\n *\n * Only the declaration that *is* an app carries one. Two surfaces in one\n * process means one of them has the spec and the other collapses onto it —\n * which is the same rule that decides deploy units, now stated once.\n */\n/**\n * Where an app's code lives when nobody says otherwise.\n *\n * One glob, every kind — the same rule the `constructs` glob follows. A handler\n * in one of these directories is found; anywhere else needs a `code` glob, and\n * saying so is the whole reason the field still exists.\n */\nexport const DEFAULT_APP_CODE =\n\t'./{endpoints,functions,crons,queues,topics,subscribers}/**/*.ts';\n\nexport interface AppSpec {\n\t/**\n\t * Where its source lives, relative to the workspace root.\n\t *\n\t * Optional, and normally omitted: `apps/<kebab-id>` when that directory\n\t * exists, and the workspace root otherwise. An `Api` construct in a\n\t * monorepo means `apps/api`, and in a single-app project it means `.` —\n\t * both of which are answerable by looking, which is why neither was worth\n\t * making someone write down.\n\t *\n\t * Set one only when the layout is genuinely different, e.g.\n\t * `path: 'services/api'`.\n\t */\n\tpath?: string;\n\t/**\n\t * The port it answers on locally.\n\t *\n\t * Optional, and normally omitted: ports are assigned in a stable order so\n\t * that adding a site does not renumber the others. Set one only when\n\t * something outside the workspace has to know it in advance.\n\t */\n\tport?: number;\n\t/**\n\t * One glob that finds everything this app defines, relative to `path`.\n\t *\n\t * Every export of every matching module is inspected, and each kind is\n\t * picked out by whatever recognises it — the same rule the `constructs`\n\t * glob already follows. A glob per kind was the specialness this model\n\t * removes: five patterns that had to be kept in step, where a handler in the\n\t * wrong directory simply never loaded and nothing said so.\n\t *\n\t * The per-kind fields below still work, and still win where both are given,\n\t * because a single-app `defineConfig` has always been written that way.\n\t *\n\t * Optional, and normally omitted: the conventional directories under\n\t * `path`, which is `DEFAULT_APP_CODE`. A glob is worth writing only when\n\t * the code is somewhere else.\n\t */\n\tcode?: Glob;\n\t/** Globs that find one kind of thing. Prefer `code`. */\n\troutes?: Glob;\n\tfunctions?: Glob;\n\tcrons?: Glob;\n\tqueues?: Glob;\n\ttopics?: Glob;\n\tsubscribers?: Glob;\n\t/** `./config/env#envParser` — module, optionally with an export. */\n\tenvParser?: string;\n\tlogger?: string;\n\ttelescope?: string | boolean | Record<string, unknown>;\n\tstudio?: string | boolean | Record<string, unknown>;\n\topenapi?: boolean | Record<string, unknown>;\n\truntime?: 'node' | 'bun';\n\t/** Env files to load, in order. */\n\tenv?: Glob;\n\t/** Entry module for an app the build does not generate. */\n\tentry?: string;\n\t/** Modules to import when sniffing which env vars a frontend reads. */\n\tconfig?: { client?: string; server?: string };\n}\n\n/**\n * A frontend — a construct like any other, which is what removes the last\n * mechanism that ran in parallel to the graph.\n *\n * Its edges are what make it worth declaring. A site depending on an API is the\n * single fact behind four things that are hand-maintained otherwise: the site's\n * build-time `VITE_API_URL`, the API's CORS origins, the auth server's trusted\n * origins, and which generated client lands in which app. None of those are\n * declared anywhere here, because all four are the *same* edge read from one\n * end or the other.\n *\n * `variant` is the framework, because the framework changes the code you write:\n * it selects how the values are delivered (`VITE_`, `NEXT_PUBLIC_`, a\n * `config.json`), never which values there are.\n */\nexport interface SiteDeclaration extends Node {\n\tkind: 'site';\n\tvariant: 'static' | 'next' | 'tanstack';\n\t/**\n\t * How it is built and run, `path` included.\n\t *\n\t * Required, where a surface's is optional: a site is always its own app.\n\t * There is no arrangement in which two sites are one process.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * Whether this is the site the base domain points at.\n\t *\n\t * Structural rather than config: *which* site is primary does not vary by\n\t * stage, even though its hostname does — that is what `app.domain` is for.\n\t *\n\t * Only meaningful when a project has more than one site, and then only when\n\t * none of them is named `web`. The convention still holds first, because it\n\t * is a convention people already rely on.\n\t */\n\troot?: boolean;\n\t/**\n\t * What it calls. On a node rather than on a handler because a site has no\n\t * single entrypoint — the whole app is the consumer.\n\t */\n\tdependencies: readonly Dependency[];\n}\n\n/**\n * A process with no port.\n *\n * The sibling of `RestApiDeclaration`, and the answer to a question the model\n * could not previously state: *what runs this cron?* A cron, a subscriber and a\n * queue consumer all have to run somewhere, and until now the only thing that\n * said where was the directory the file happened to sit in — so a background\n * job was owned by a glob, and a project that was nothing but background jobs\n * had to declare an HTTP surface with no routes on it to be deployable at all.\n *\n * It takes no authorizer. A `RestApi` needs one because an HTTP surface can\n * ship open by omission; nothing calls a worker from outside, so there is no\n * default to get wrong. That difference is the reason these are two constructs\n * rather than one with a flag.\n */\nexport interface WorkerDeclaration extends Node {\n\tkind: 'worker';\n\t/**\n\t * Where its source lives and how it is run. Optional, like every other\n\t * app's: `Worker` means `apps/worker`, which the id already said.\n\t */\n\tapp?: AppSpec;\n\t/** Surfaces and resources it calls, which is what grants it access. */\n\tdependencies?: readonly Dependency[];\n}\n\n/** One route on a surface. */\nexport interface RestApiEndpoint extends Fn {\n\tmethod: string;\n\tpath: string;\n\tauthorizer?: string;\n}\n\n/**\n * A point-to-point queue and the single consumer that drains it.\n *\n * Provides one key, the producer's connection string. The protocol in it picks\n * the transport — `pgboss://` locally, `sqs://` deployed — so a producer names\n * no broker, exactly as a database consumer names no cloud.\n *\n * The consumer side provides nothing: a worker is reached *through* its queue,\n * so there is no second key and nothing can depend on a handler.\n */\nexport interface QueueDeclaration extends Node {\n\tkind: 'queue';\n\t/** FIFO ordering, where the transport offers it. */\n\tfifo?: boolean;\n\t/**\n\t * The single consumer that drains it.\n\t *\n\t * Nested rather than listed beside the queue, because **position carries the\n\t * trigger**: a handler here is reached by messages arriving on this queue and\n\t * by nothing else, so there is no `trigger` field to keep in step with it.\n\t */\n\tworker: Fn;\n}\n\n/**\n * A topic — pub/sub fan-out, one publisher and any number of subscribers.\n *\n * Like a queue it provides only the producer's string; a subscriber is bound to\n * the topic rather than depending on it, so the binding is an edge the deploy\n * target reads, not an env key. Locally both sides meet on the same pg-boss\n * connection, which is why the subscriber needs no key of its own.\n */\nexport interface TopicDeclaration extends Node {\n\tkind: 'topic';\n\t/** The event type names this topic carries. */\n\tevents: readonly string[];\n\t/**\n\t * The handlers bound to it, each with the events it wants.\n\t *\n\t * Nested for the same reason a queue's worker is: position is the trigger. A\n\t * subscriber is *bound* to a topic rather than depending on it, which is why\n\t * it holds no key of its own and cannot be reached except through the topic.\n\t */\n\tsubscribers: readonly (Fn & { events: readonly string[] })[];\n}\n\n/**\n * A function invoked directly, with no surface in front of it.\n *\n * An `Fn` rather than a `Node`, because a function *is* a handler — there is no\n * resource beside it to declare. It provides its own address, so something else\n * can depend on it and be given a way to call it.\n */\nexport interface FunctionDeclaration extends Fn {\n\tkind: 'function';\n}\n\n/**\n * A function on a schedule.\n *\n * The schedule is the trigger and it is structural: *that* something runs\n * nightly is a fact about the application, while which timezone a stage\n * interprets it in is not.\n */\nexport interface CronDeclaration extends Fn {\n\tkind: 'cron';\n\t/** A rate or cron expression, e.g. `rate(1 day)`. */\n\tschedule: string;\n}\n\n/**\n * Every declaration. A discriminated union, so `kind` gives exhaustiveness *and*\n * per-kind fields — there is no separate enum to keep in step, and no shape\n * carrying fields that belong to a different kind.\n */\nexport type Declaration =\n\t| ObjectsDeclaration\n\t| FileServerDeclaration\n\t| EmailDeclaration\n\t| DatabaseDeclaration\n\t| DatabaseReaderDeclaration\n\t| DatabaseSchemaDeclaration\n\t| CacheDeclaration\n\t| SecretDeclaration\n\t| CredentialDeclaration\n\t| RestApiDeclaration\n\t| SiteDeclaration\n\t| WorkerDeclaration\n\t| OidcDeclaration\n\t| QueueDeclaration\n\t| TopicDeclaration\n\t| FunctionDeclaration\n\t| CronDeclaration;\n\n/** A declaration that provisions nothing of its own and names a parent. */\n/**\n * A declaration that names a parent.\n *\n * A union rather than an `Extract`, because one kind is *optionally* derived: a\n * cache lives in a database when it was declared from one and stands alone\n * otherwise, so `of` is optional on it and an `Extract<…, { of: ConstructId }>`\n * would not select it. {@link isDerived} tests the value rather than the kind\n * for exactly that reason.\n */\nexport type DerivedDeclaration =\n\t| Extract<Declaration, { of: ConstructId }>\n\t| CacheDeclaration;\n\nexport type DerivedKind = DerivedDeclaration['kind'];\n\n/**\n * What each kind may derive from.\n *\n * Small enough to state exhaustively, and stating it makes cycles impossible\n * without a graph walk: readers are terminal, so no chain can return to its\n * start. There is no `writer` — the database *is* the writer, which is what\n * keeps a replica from being reached by accident.\n */\nexport const DERIVES_FROM: Readonly<Record<DerivedKind, readonly string[]>> = {\n\t'database-reader': ['database', 'database-schema'],\n\t'database-schema': ['database'],\n\t// A file server derives from what it serves. Unlike the database pair it\n\t// shares the parent's *contents* rather than its credentials, which is why\n\t// it is a construct of its own and only its node is derived.\n\t'file-server': ['objects'],\n\t// A cache in a database is a table in it, reached by the same role — so it\n\t// derives from either a database or a tenant of one, and a tenant's cache\n\t// lands in the tenant's schema without naming it.\n\tcache: ['database', 'database-schema'],\n};\n\nexport type DeclarationKind = Declaration['kind'];\n\n/**\n * The manifest: every construct keyed by its id.\n *\n * Flat rather than grouped, because `Dependency.target` resolves as\n * `m[target]` — a lookup that stays O(1) and identical whether the edge points\n * at a resource, a surface, or another function.\n *\n * Use it as a **constraint, not an annotation**. `gkm build` emits\n * `as const satisfies ConstructManifest`, which checks the shape while keeping\n * every id, kind, and provided key a literal — annotating with this type\n * instead would widen them all to `string` and consumers could no longer select\n * anything:\n *\n * ```ts\n * export const manifest = {\n * Uploads: { kind: 'objects', id: 'Uploads', provides: ['UPLOADS_URL'] },\n * } as const satisfies ConstructManifest;\n *\n * type Ids = IdsOf<typeof manifest>; // 'Uploads'\n * type Env = ProvidedKeys<typeof manifest, 'Uploads'>; // 'UPLOADS_URL'\n * ```\n */\nexport type ConstructManifest = Readonly<Record<ConstructId, Declaration>>;\n\n// ---------------------------------------------------------------------------\n// Selecting from a concrete manifest\n// ---------------------------------------------------------------------------\n\n/** Every id in a manifest. */\nexport type IdsOf<M extends ConstructManifest> = Extract<keyof M, string>;\n\n/** The declaration for one id. */\nexport type DeclarationOf<\n\tM extends ConstructManifest,\n\tK extends IdsOf<M>,\n> = M[K];\n\n/** Every id of a given kind — what an adapter iterates when provisioning. */\nexport type IdsOfKind<\n\tM extends ConstructManifest,\n\tK extends DeclarationKind,\n> = {\n\t[Id in IdsOf<M>]: M[Id]['kind'] extends K ? Id : never;\n}[IdsOf<M>];\n\n/** The env keys one construct provides. */\nexport type ProvidedKeys<\n\tM extends ConstructManifest,\n\tK extends IdsOf<M>,\n> = M[K] extends { provides: readonly (infer P)[] } ? P : never;\n\n/** Every env key any construct in the manifest provides. */\nexport type AllProvidedKeys<M extends ConstructManifest> = {\n\t[Id in IdsOf<M>]: ProvidedKeys<M, Id>;\n}[IdsOf<M>];\n\n// ---------------------------------------------------------------------------\n// The app ↔ infra contract\n// ---------------------------------------------------------------------------\n\n/**\n * What each kind provides, by role rather than by provider syntax.\n *\n * This is the contract between the construct that declares a key and the cloud\n * component that supplies its value — an interface rather than shared code,\n * because a shared codec would have to contain `bucket` and `region`, and\n * provider words in the neutral layer is the problem this design exists to fix.\n *\n * How a value is composed and parsed stays private to each provider pair, so\n * `s3://` and `gs://` never appear here.\n */\nexport interface ProvidesByKind {\n\tobjects: { url: string };\n\t/** Where the served objects answer. Public: a browser is the point of it. */\n\t'file-server': { url: string };\n\t/**\n\t * An `smtp://` URL, credentials included — never shippable — and the\n\t * identity mail is sent from.\n\t *\n\t * The sending address is the one thing about mail that genuinely differs per\n\t * stage (`myapp.test` locally, a verified domain deployed), so it travels\n\t * beside the URL rather than being written into the construct.\n\t */\n\temail: { url: string; from: string };\n\t/**\n\t * One key, the runtime role's. The owner URL is not here by design — see\n\t * {@link DatabaseDeclaration}.\n\t */\n\tdatabase: { url: string };\n\t'database-reader': { url: string };\n\t'database-schema': { url: string };\n\t/** The endpoint and its token, in one string. */\n\tcache: { url: string };\n\t/**\n\t * Where the surface answers, who may call it, and the domain its cookies\n\t * are scoped to.\n\t *\n\t * Only `url` is a fact about the surface itself. The other two are read off\n\t * its *inbound* edges — every construct that depends on it — which is why a\n\t * surface never lists its own callers: nothing enumerates the things that\n\t * point at it, the graph already does.\n\t *\n\t * `trustedOrigins` and `cookieDomain` are one key each rather than a list\n\t * and a structure, because both cross a process boundary as environment.\n\t */\n\t'rest-api': {\n\t\turl: string;\n\t\t/** Comma-separated. Empty when nothing declares an edge to this surface. */\n\t\ttrustedOrigins: string;\n\t\t/**\n\t\t * The parent domain shared by the surface and its callers, leading dot\n\t\t * included — `.example.com`. Absent where there is nothing to share:\n\t\t * one host locally, unrelated hosts deployed.\n\t\t */\n\t\tcookieDomain: string;\n\t};\n\t/** The value itself. A secret has no address to hand out instead. */\n\tsecret: { value: string };\n\t/**\n\t * The credential as one JSON object, parsed and validated by the construct\n\t * that declared the schema.\n\t */\n\tcredential: { credential: string };\n\t/**\n\t * The producer's connection string. One key, not two: the consumer is\n\t * reached through the queue rather than by an address of its own.\n\t */\n\tqueue: { publisherConnectionString: string };\n\ttopic: { publisherConnectionString: string };\n\t/** Where to invoke it — what lets something else depend on a function. */\n\tfunction: { url: string };\n\t/** A cron is reached by its schedule and by nothing else, so it provides none. */\n\tcron: Record<never, never>;\n\t/** Where the site is served. Public for the same reason an API's is. */\n\tsite: { url: string };\n\t/**\n\t * Where tokens come from and which audience they must carry.\n\t *\n\t * Two keys because the halves have different lifetimes: the issuer may be a\n\t * fact about the product, the audience is always a fact about one\n\t * deployment.\n\t */\n\toidc: { issuer: string; audience: string };\n}\n\nexport type Provides<K extends keyof ProvidesByKind> = ProvidesByKind[K];\n\n/**\n * Which provided values may be shipped to a browser.\n *\n * Drives client-side prefixing (`VITE_`, `NEXT_PUBLIC_`) and nothing else — it\n * is not a restriction on what may be depended on, since a server-side consumer\n * can legitimately use any of them. A bucket's `url` presigns and stays private.\n */\nexport const PUBLIC: {\n\treadonly [K in keyof ProvidesByKind]: readonly (keyof ProvidesByKind[K])[];\n} = {\n\tobjects: [],\n\t// The address a browser fetches an image from. The bucket's own URL is not\n\t// here and must not be: it presigns, and a presigner in a bundle is a\n\t// credential in a bundle.\n\t'file-server': ['url'],\n\t// Carries the SMTP credentials in its userinfo.\n\temail: [],\n\t// A connection string is never shippable, whichever role it carries.\n\tdatabase: [],\n\t'database-reader': [],\n\t'database-schema': [],\n\t// Carries its token, and a cache a browser can write is a cache it can\n\t// poison.\n\tcache: [],\n\t// The whole point of one.\n\tsecret: [],\n\t// A credential a browser can read is a credential anyone can read. A\n\t// publishable key belongs in the site's own config, not in this.\n\tcredential: [],\n\t// A URL a browser calls is a URL a browser may hold. The other two are not\n\t// secret either — they are simply server-side facts, and prefixing a value\n\t// into a bundle that nothing there reads is how a bundle grows keys nobody\n\t// can account for.\n\t'rest-api': ['url'],\n\t// Carries broker credentials, and a browser that can publish to a queue can\n\t// forge any job the worker trusts.\n\tqueue: [],\n\ttopic: [],\n\t// A browser doing the sign-in flow needs both, and neither is secret: an\n\t// issuer is a public URL and an audience is a client id, which is the half\n\t// of an OAuth client that is meant to be seen.\n\toidc: ['issuer', 'audience'],\n\t// An invocation address is not a public one: reaching it is IAM's business,\n\t// not a browser's.\n\tfunction: [],\n\tcron: [],\n\t// Its own address, which it needs in order to build absolute links to\n\t// itself — and which an email templating a link to it needs too.\n\tsite: ['url'],\n\t// Nothing calls a worker, so there is no address to hand anyone. It reaches\n\t// out — to a queue, a schedule, a topic — and is reached by none of them.\n\tworker: [],\n};\n","/**\n * Manifest errors.\n *\n * Messages state the rule, which is constant; the offending value is a field.\n * An interpolated message cannot be matched on, reads differently every time it\n * is thrown, and carries user input into every log line that touches it.\n */\n\n/** A construct id that cannot survive the names derived from it. */\nexport class InvalidConstructId extends Error {\n\t/** What was passed in. */\n\treadonly input: string;\n\t/** What canonicalising it produced, which is what failed the rule. */\n\treadonly canonical: string;\n\n\tconstructor(input: string, canonical: string) {\n\t\tsuper(\n\t\t\t'A construct id must start with a letter and contain only letters and digits',\n\t\t);\n\t\tthis.name = 'InvalidConstructId';\n\t\tthis.input = input;\n\t\tthis.canonical = canonical;\n\t}\n}\n\n/** A derived construct naming a parent the manifest does not contain. */\nexport class UnknownParent extends Error {\n\t/** The derived construct. */\n\treadonly id: string;\n\t/** The parent it named. */\n\treadonly of: string;\n\t/** Ids the manifest does contain, for the caller to match against. */\n\treadonly available: readonly string[];\n\n\tconstructor(id: string, of: string, available: readonly string[]) {\n\t\tsuper('A derived construct must name a parent present in the manifest');\n\t\tthis.name = 'UnknownParent';\n\t\tthis.id = id;\n\t\tthis.of = of;\n\t\tthis.available = available;\n\t}\n}\n\n/**\n * A derived construct naming a parent that may not vend it — a reader of a\n * reader, a schema of a schema.\n */\nexport class IllegalDerivation extends Error {\n\treadonly id: string;\n\treadonly kind: string;\n\t/** The kind of the parent it named. */\n\treadonly parentKind: string;\n\t/** The parent kinds that may vend this one. */\n\treadonly allowed: readonly string[];\n\n\tconstructor(\n\t\tid: string,\n\t\tkind: string,\n\t\tparentKind: string,\n\t\tallowed: readonly string[],\n\t) {\n\t\tsuper('A derived construct must name a parent whose kind may vend it');\n\t\tthis.name = 'IllegalDerivation';\n\t\tthis.id = id;\n\t\tthis.kind = kind;\n\t\tthis.parentKind = parentKind;\n\t\tthis.allowed = allowed;\n\t}\n}\n","/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match words composed of alphanumeric characters. */\nvar reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n/** Used to match Latin Unicode letters (excluding mathematical operators). */\nvar reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe23',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20f0',\n rsDingbatRange = '\\\\u2700-\\\\u27bf',\n rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n rsPunctuationRange = '\\\\u2000-\\\\u206f',\n 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',\n rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n rsVarRange = '\\\\ufe0e\\\\ufe0f',\n rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n/** Used to compose unicode capture groups. */\nvar rsApos = \"['\\u2019]\",\n rsBreak = '[' + rsBreakRange + ']',\n rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',\n rsDigits = '\\\\d+',\n rsDingbat = '[' + rsDingbatRange + ']',\n rsLower = '[' + rsLowerRange + ']',\n rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsUpper = '[' + rsUpperRange + ']',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',\n rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',\n rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;\n\n/** Used to match apostrophes. */\nvar reApos = RegExp(rsApos, 'g');\n\n/**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\nvar reComboMark = RegExp(rsCombo, 'g');\n\n/** Used to match complex or compound words. */\nvar reUnicodeWord = RegExp([\n rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',\n rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,\n rsUpper + '+' + rsOptUpperContr,\n rsDigits,\n rsEmoji\n].join('|'), 'g');\n\n/** Used to detect strings that need a more robust regexp to match words. */\nvar reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n/** Used to map Latin Unicode letters to basic Latin letters. */\nvar deburredLetters = {\n // Latin-1 Supplement block.\n '\\xc0': 'A', '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n '\\xe0': 'a', '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n '\\xc7': 'C', '\\xe7': 'c',\n '\\xd0': 'D', '\\xf0': 'd',\n '\\xc8': 'E', '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n '\\xe8': 'e', '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n '\\xcc': 'I', '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n '\\xec': 'i', '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n '\\xd1': 'N', '\\xf1': 'n',\n '\\xd2': 'O', '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n '\\xf2': 'o', '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n '\\xd9': 'U', '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n '\\xf9': 'u', '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n '\\xdd': 'Y', '\\xfd': 'y', '\\xff': 'y',\n '\\xc6': 'Ae', '\\xe6': 'ae',\n '\\xde': 'Th', '\\xfe': 'th',\n '\\xdf': 'ss',\n // Latin Extended-A block.\n '\\u0100': 'A', '\\u0102': 'A', '\\u0104': 'A',\n '\\u0101': 'a', '\\u0103': 'a', '\\u0105': 'a',\n '\\u0106': 'C', '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n '\\u0107': 'c', '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n '\\u010e': 'D', '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n '\\u0112': 'E', '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n '\\u0113': 'e', '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n '\\u011c': 'G', '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n '\\u011d': 'g', '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n '\\u0124': 'H', '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n '\\u0128': 'I', '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n '\\u0129': 'i', '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n '\\u0134': 'J', '\\u0135': 'j',\n '\\u0136': 'K', '\\u0137': 'k', '\\u0138': 'k',\n '\\u0139': 'L', '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n '\\u013a': 'l', '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n '\\u0143': 'N', '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n '\\u0144': 'n', '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n '\\u014c': 'O', '\\u014e': 'O', '\\u0150': 'O',\n '\\u014d': 'o', '\\u014f': 'o', '\\u0151': 'o',\n '\\u0154': 'R', '\\u0156': 'R', '\\u0158': 'R',\n '\\u0155': 'r', '\\u0157': 'r', '\\u0159': 'r',\n '\\u015a': 'S', '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n '\\u015b': 's', '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n '\\u0162': 'T', '\\u0164': 'T', '\\u0166': 'T',\n '\\u0163': 't', '\\u0165': 't', '\\u0167': 't',\n '\\u0168': 'U', '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n '\\u0169': 'u', '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n '\\u0174': 'W', '\\u0175': 'w',\n '\\u0176': 'Y', '\\u0177': 'y', '\\u0178': 'Y',\n '\\u0179': 'Z', '\\u017b': 'Z', '\\u017d': 'Z',\n '\\u017a': 'z', '\\u017c': 'z', '\\u017e': 'z',\n '\\u0132': 'IJ', '\\u0133': 'ij',\n '\\u0152': 'Oe', '\\u0153': 'oe',\n '\\u0149': \"'n\", '\\u017f': 'ss'\n};\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction asciiWords(string) {\n return string.match(reAsciiWord) || [];\n}\n\n/**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyOf(object) {\n return function(key) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\nvar deburrLetter = basePropertyOf(deburredLetters);\n\n/**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\nfunction hasUnicodeWord(string) {\n return reHasUnicodeWord.test(string);\n}\n\n/**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction unicodeWords(string) {\n return string.match(reUnicodeWord) || [];\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\n/**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\nfunction createCompounder(callback) {\n return function(string) {\n return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n };\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\n/**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('déjà vu');\n * // => 'deja vu'\n */\nfunction deburr(string) {\n string = toString(string);\n return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n}\n\n/**\n * Converts `string` to\n * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the snake cased string.\n * @example\n *\n * _.snakeCase('Foo Bar');\n * // => 'foo_bar'\n *\n * _.snakeCase('fooBar');\n * // => 'foo_bar'\n *\n * _.snakeCase('--FOO-BAR--');\n * // => 'foo_bar'\n */\nvar snakeCase = createCompounder(function(result, word, index) {\n return result + (index ? '_' : '') + word.toLowerCase();\n});\n\n/**\n * Splits `string` into an array of its words.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {RegExp|string} [pattern] The pattern to match words.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the words of `string`.\n * @example\n *\n * _.words('fred, barney, & pebbles');\n * // => ['fred', 'barney', 'pebbles']\n *\n * _.words('fred, barney, & pebbles', /[^, ]+/g);\n * // => ['fred', 'barney', '&', 'pebbles']\n */\nfunction words(string, pattern, guard) {\n string = toString(string);\n pattern = guard ? undefined : pattern;\n\n if (pattern === undefined) {\n return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n }\n return string.match(pattern) || [];\n}\n\nmodule.exports = snakeCase;\n","/**\n * Name derivation — the single source for turning a construct's id into the\n * names that appear elsewhere.\n *\n * These live here rather than in each consumer because `@geekmidas/constructs`\n * derives a key when it declares, and `@geekmidas/cloud` derives the same key\n * when it supplies the value. Two implementations of the same rule is precisely\n * the drift this design exists to remove.\n */\n\nimport snakecase from 'lodash.snakecase';\nimport type { DeclarationKind } from './declaration';\n\nimport { InvalidConstructId } from './errors';\n\n/**\n * `UPPER_SNAKE_CASE`, with numbers kept against the word they follow.\n *\n * Matches `environmentCase` in `@geekmidas/envkit`, which reads the values these\n * names key. The two must agree exactly, so this is the implementation and that\n * one should defer to it.\n *\n * @example environmentCase('sendEmail') // 'SEND_EMAIL'\n * @example environmentCase('api2') // 'API2' (digit joins its word)\n */\nexport function environmentCase(name: string): string {\n\treturn snakecase(name)\n\t\t.toUpperCase()\n\t\t.replace(/_\\d+/g, (r) => r.replace('_', ''));\n}\n\n/**\n * The env key a construct provides for one of its roles.\n *\n * @example provideKey('Uploads', 'url') // 'UPLOADS_URL'\n * @example provideKey('Uploads', 'cdnUrl') // 'UPLOADS_CDN_URL'\n */\nexport function provideKey(id: string, role: string): string {\n\treturn environmentCase(`${id}_${role}`);\n}\n\n/**\n * A construct's canonical id — PascalCase.\n *\n * `uploads`, `Uploads`, `user_uploads`, and `user-uploads` all canonicalise to\n * the same id, so declaring two of them is a duplicate rather than a collision\n * to detect.\n *\n * Runtime only. Writing the id in PascalCase is what keeps the *type* usable:\n * the service key is `Uncapitalize<TName>`, a TypeScript intrinsic, so no\n * type-level transform is needed and none has to be kept in step with this one.\n *\n * @example canonicalId('user-uploads') // 'UserUploads'\n */\nexport function canonicalId(input: string): string {\n\t// `upperFirst(camelCase(x))` by another route — snakecase is already a\n\t// dependency, and adding lodash.camelcase for the same result is not worth it.\n\tconst id = snakecase(input)\n\t\t.split('_')\n\t\t.filter(Boolean)\n\t\t.map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n\t\t.join('');\n\n\tif (!VALID_ID.test(id)) throw new InvalidConstructId(input, id);\n\treturn id;\n}\n\n/**\n * A canonical id: PascalCase, letters and digits only.\n *\n * Narrower than a JavaScript identifier — `_id` and `$ref` are legal JavaScript\n * and rejected here — because the id also has to survive `environmentCase` into\n * an env key and `cloudName` into a DNS-safe resource name.\n */\nconst VALID_ID = /^[A-Z][A-Za-z0-9]*$/;\n\n/**\n * The key a construct is reached under in the service record.\n *\n * The runtime twin of `Uncapitalize<TName>`, which types it — they must agree,\n * so they live next to each other rather than being re-derived by each\n * construct.\n *\n * @example serviceKey('UserUploads') // 'userUploads' → services.userUploads\n */\nexport function serviceKey(id: string): string {\n\treturn id.charAt(0).toLowerCase() + id.slice(1);\n}\n\n/**\n * The table a cache keeps its entries in, when nobody named one.\n *\n * Derived from the cache's own id rather than fixed at `cache`, because a\n * database may hold more than one and two caches sharing a table share a\n * keyspace — `orders.cache('Sessions')` and `orders.cache('Rates')` would\n * silently read each other's entries and evict each other's keys.\n *\n * Prefixed rather than suffixed so every cache sorts together in `\\dt`, and\n * prefixed at all so a cache named for a thing the application also stores —\n * `orders.cache('Users')` — cannot collide with the table holding that thing.\n *\n * Read by whoever composes the URL and by whoever creates the table, so both\n * default the same way.\n *\n * @example cacheTable('Sessions') // 'cache_sessions'\n */\nexport function cacheTable(id: string): string {\n\treturn `cache_${id.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase()}`;\n}\n\n/**\n * Kebab-cases an identifier, acronym- and digit-aware.\n *\n * `userName` → `user-name`, `APIKey` → `api-key`, `S3Bucket` → `s3-bucket`.\n *\n * The last of those is why this is here rather than `snakecase(id)` with the\n * underscores swapped: lodash splits a digit from the letter beside it, so\n * `S3Bucket` became `s-3-bucket` on one provider and `s3-bucket` on the other.\n * Two implementations of one rule, agreeing on every id anybody had tried.\n *\n * `environmentCase` already corrected for the same thing in the other\n * direction — `api2` keeps its digit — so the two spellings of \"kebab this id\"\n * in this file did not even agree with each other.\n */\nexport function kebabCase(value: string): string {\n\treturn value\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n\t\t.replace(/[\\s_]+/g, '-')\n\t\t.toLowerCase();\n}\n\n/**\n * The physical name a target provisions a construct under — lowercase kebab,\n * scoped so two stages or apps sharing an account cannot collide.\n *\n * **One rule, every provider.** A construct is named the same thing on AWS and\n * on Dokploy, which is what lets a name be read across them: `Database` in the\n * `production` stage of `kitchen-sink` is `production-kitchen-sink-database`\n * wherever it lands. The SST target's `prefixedName` is this function under\n * another signature and defers to it.\n *\n * Idempotent in its prefix: an id that already carries the scope is not given a\n * second one, so composing names cannot double up.\n *\n * @example cloudName({ stage: 'prod', app: 'myapp' }, 'UserUploads')\n * // 'prod-myapp-user-uploads'\n */\nexport function cloudName(\n\tscope: { stage: string; app: string },\n\tid: string,\n): string {\n\treturn scopedName([scope.stage, scope.app], id);\n}\n\n/**\n * {@link cloudName} for a caller that holds its scope as a list.\n *\n * The SST target's stacks add a segment of their own, so the prefix is not\n * always two parts — which is the only reason this signature exists.\n */\nexport function scopedName(scope: readonly string[], id: string): string {\n\tconst prefix = scope.join('-').toLowerCase();\n\tconst name = kebabCase(id);\n\n\treturn name.startsWith(prefix) ? name : `${prefix}-${name}`;\n}\n\n/**\n * The domain a cookie must be scoped to so a surface and its callers share it.\n *\n * Derived from the addresses rather than configured, for the same reason the\n * origins are: the set of things that talk to a surface is already in the graph,\n * and the domain they have in common is a fact about that set. Returned with the\n * leading dot a `Domain` attribute wants.\n *\n * Returns `undefined` when there is nothing to scope, which is the common case\n * and not a failure:\n *\n * - **One host.** Locally everything is `localhost` on different ports, and\n * cookies ignore the port — so a `Domain` would add nothing and `.localhost`\n * is not a domain a browser will accept.\n * - **Nothing in common.** Unrelated hosts cannot share a cookie at all, and\n * emitting the longest common suffix anyway would be a value that silently\n * fails to set.\n *\n * **The public-suffix limit, stated rather than discovered.** Two apps on\n * `a.vercel.app` and `b.vercel.app` share `.vercel.app`, which every browser\n * rejects because it is a registrable suffix rather than a registrable domain.\n * Resolving that correctly needs the Public Suffix List, which is a downloaded,\n * expiring dataset — so this requires at least two labels and otherwise trusts\n * the addresses, and the value stays overridable for the case it gets wrong.\n */\nexport function cookieDomain(urls: readonly string[]): string | undefined {\n\tconst hosts = new Set<string>();\n\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst { hostname } = new URL(url);\n\t\t\t// An IP address has no parent to share: `.0.0.1` is not a domain.\n\t\t\tif (/^\\d+(\\.\\d+){3}$/.test(hostname) || hostname.includes(':')) return;\n\t\t\thosts.add(hostname.toLowerCase());\n\t\t} catch {\n\t\t\t// Not an address. Nothing to derive from, and guessing is worse than\n\t\t\t// leaving the attribute off.\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (hosts.size === 0) return;\n\t// One host already shares its cookies with itself, whatever the port.\n\tif (hosts.size === 1) return;\n\n\tconst [first = [], ...rest] = [...hosts].map((host) =>\n\t\thost.split('.').reverse(),\n\t);\n\tconst shared: string[] = [];\n\n\tfor (const [index, label] of first.entries()) {\n\t\tif (!rest.every((labels) => labels[index] === label)) break;\n\t\tshared.push(label);\n\t}\n\n\t// One shared label is a TLD — `.com` is not a cookie domain.\n\tif (shared.length < 2) return;\n\n\treturn `.${shared.reverse().join('.')}`;\n}\n\n/**\n * The env key a construct's provided role actually becomes.\n *\n * Almost always `provideKey(id, role)` — and `secret` is the exception, because\n * a secret's *name* is its key: `Auth` signs with `AUTH_SECRET`, which is also\n * what better-auth's own tooling looks for, and qualifying it by role would\n * produce `AUTH_SECRET_VALUE`.\n *\n * It lives here rather than in each target because two targets deriving the\n * same key separately is exactly the drift the app/infra contract check exists\n * to catch — and a check deriving the key differently from the thing it checks\n * cannot catch anything.\n */\nexport function providedKeyFor(\n\tid: string,\n\tkind: DeclarationKind,\n\trole: string,\n): string {\n\treturn kind === 'secret' ? environmentCase(id) : provideKey(id, role);\n}\n","/**\n * Derived constructs — the ones that provision nothing of their own.\n *\n * A reader is an endpoint on an existing cluster; a schema tenant is a schema\n * inside an existing database. Both name their parent through `of`, and both\n * stay top-level entries so that `dependencies[].target` keeps resolving as\n * `m[target]` and every id remains a key in the map.\n *\n * The rules here are pure and manifest-only: they hold for any target adapter,\n * so an app is wrong before a deploy is attempted rather than during one.\n */\n\nimport type {\n\tConstructId,\n\tConstructManifest,\n\tDeclaration,\n\tDependency,\n\tDerivedDeclaration,\n\tSiteDeclaration,\n} from './declaration';\nimport { DERIVES_FROM, PUBLIC } from './declaration';\nimport { IllegalDerivation, UnknownParent } from './errors';\nimport { provideKey } from './naming';\n\n/** Whether a declaration names a parent. */\nexport function isDerived(\n\tdeclaration: Declaration,\n): declaration is DerivedDeclaration & { of: ConstructId } {\n\t// Both halves, because one kind is *optionally* derived: a cache declared\n\t// from a database names it, and a cache declared on its own names nothing.\n\t// Testing only the kind would make every standalone cache look like a\n\t// derivation with a missing parent.\n\treturn (\n\t\tdeclaration.kind in DERIVES_FROM &&\n\t\t'of' in declaration &&\n\t\ttypeof declaration.of === 'string'\n\t);\n}\n\n/**\n * Check every derived construct against its parent.\n *\n * Two rules: the parent exists, and its kind may vend this one. Together they\n * make cycles unreachable — a reader is terminal, so no chain of `of` can\n * return to where it started, and no walk is needed to prove it.\n */\nexport function assertDerivations(manifest: ConstructManifest): void {\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tif (!isDerived(declaration)) continue;\n\n\t\tconst parent = manifest[declaration.of];\n\t\tif (!parent) {\n\t\t\tthrow new UnknownParent(id, declaration.of, Object.keys(manifest));\n\t\t}\n\n\t\tconst allowed = DERIVES_FROM[declaration.kind];\n\t\tif (!allowed.includes(parent.kind)) {\n\t\t\tthrow new IllegalDerivation(id, declaration.kind, parent.kind, allowed);\n\t\t}\n\t}\n}\n\n/**\n * The order constructs must be provisioned in: every parent before its children.\n *\n * Resources are leaves and so come first in any order; only derived nodes\n * constrain the sequence, and they form a shallow forest rather than a general\n * graph. This walks each node's ancestors on demand instead of running a full\n * topological sort, which is the same result at this depth and reads as what it\n * is.\n *\n * Assumes {@link assertDerivations} has passed — a missing parent would\n * otherwise be a silent omission here rather than an error.\n */\nexport function provisionOrder(manifest: ConstructManifest): string[] {\n\tconst ordered: string[] = [];\n\tconst placed = new Set<string>();\n\n\tconst place = (id: string): void => {\n\t\tif (placed.has(id)) return;\n\t\tconst declaration = manifest[id];\n\t\tif (!declaration) return;\n\n\t\t// Mark before recursing: `assertDerivations` rules cycles out, and marking\n\t\t// first means a manifest that skipped that check terminates anyway.\n\t\tplaced.add(id);\n\t\tif (isDerived(declaration)) place(declaration.of);\n\t\tordered.push(id);\n\t};\n\n\tfor (const id of Object.keys(manifest)) place(id);\n\n\treturn ordered;\n}\n\n/**\n * Every edge a declaration carries, wherever the kind happens to keep them.\n *\n * Dependencies live in two places by design: on a node when the whole construct\n * is the consumer (a site), and on each nested handler when the construct is a\n * surface (a `rest-api`, whose routes each depend on their own things and\n * nothing more). Flattening that difference here is what lets every consumer of\n * the graph — reverse lookups, filtering, reference checks — ask one question.\n */\nexport function dependenciesOf(\n\tdeclaration: Declaration,\n): readonly Dependency[] {\n\tconst own =\n\t\t'dependencies' in declaration ? (declaration.dependencies ?? []) : [];\n\n\t// A surface's `calls` is a caller relationship rather than an injection, so\n\t// it is read here — reverse lookups want it — and is never a dependency\n\t// anything links from. See `RestApiDeclaration.calls`.\n\tconst calls = 'calls' in declaration ? (declaration.calls ?? []) : [];\n\n\tconst nested =\n\t\tdeclaration.kind === 'rest-api'\n\t\t\t? declaration.endpoints.flatMap((endpoint) => endpoint.dependencies)\n\t\t\t: [];\n\n\treturn [...own, ...calls, ...nested];\n}\n\n/**\n * The ids that depend on one construct — the graph read backwards.\n *\n * This is the whole mechanism behind CORS origins and trusted origins. Both are\n * lists of *callers*, and a caller is exactly an inbound edge, so neither is\n * ever written down: a surface that listed its own callers would have to be\n * edited every time something new called it, which is the hand-maintained list\n * this replaces.\n *\n * Sorted, because it feeds a comma-separated env value that would otherwise\n * change whenever the manifest's key order did — and a value that churns is a\n * container that redeploys for no reason.\n */\nexport function dependentsOf(\n\tmanifest: ConstructManifest,\n\tid: ConstructId,\n): string[] {\n\tconst callers: string[] = [];\n\n\tfor (const [callerId, declaration] of Object.entries(manifest)) {\n\t\tif (callerId === id) continue;\n\t\tif (dependenciesOf(declaration).some((edge) => edge.target === id)) {\n\t\t\tcallers.push(callerId);\n\t\t}\n\t}\n\n\treturn callers.sort();\n}\n\n/**\n * How each site variant names a value it ships to the browser.\n *\n * The prefix *is* the framework's contract — `VITE_`, `NEXT_PUBLIC_` and\n * `EXPO_PUBLIC_` all mean \"inline this into the bundle\" — so it is the one thing\n * a variant changes, and it changes nothing else.\n */\nexport const PUBLIC_PREFIX: Record<SiteDeclaration['variant'], string> = {\n\tstatic: 'VITE_',\n\ttanstack: 'VITE_',\n\tnext: 'NEXT_PUBLIC_',\n};\n\n/**\n * The keys a site's bundle needs, mapped to the key each value comes from —\n * `{ VITE_API_URL: 'API_URL' }`.\n *\n * A rename, not a second derivation: `API_URL` is resolved once, by whatever\n * resolved it for the server, and the site reads the same value under the name\n * its bundler will inline. That is what keeps a site and its API from coming to\n * disagree about where the API is.\n *\n * Filtered by `PUBLIC` rather than by what the site asked for. A site may\n * legitimately depend on anything — its server half, where it has one, reads env\n * exactly as a function does — so this is not a restriction on edges. It decides\n * one thing: which values may be prefixed into a bundle, which is what keeps\n * `ORDERS_URL` and its password out of a JavaScript file served to the public.\n *\n * Shared by every target for the same reason `providedKeyFor` is: a site built\n * locally and the same site built by a deploy must inline the same names.\n */\nexport function publicEnvFor(\n\tdeclaration: SiteDeclaration,\n\tmanifest: ConstructManifest,\n): Record<string, string> {\n\tconst prefix = PUBLIC_PREFIX[declaration.variant];\n\tconst keys: Record<string, string> = {};\n\n\tfor (const edge of declaration.dependencies) {\n\t\tconst target = manifest[edge.target];\n\t\tif (!target) continue;\n\n\t\tfor (const role of PUBLIC[target.kind] ?? []) {\n\t\t\tconst key = provideKey(edge.target, role as string);\n\t\t\tkeys[`${prefix}${key}`] = key;\n\t\t}\n\t}\n\n\treturn keys;\n}\n","/**\n * Deployment manifest types — the build output of `gkm build` that enumerates a\n * project's deployable units (routes, functions, crons, subscribers, queues)\n * with the metadata an infrastructure layer needs to provision them.\n *\n * `gkm build` writes a single TypeScript module per provider\n * (`<out>/manifest/aws.ts`) of the form:\n *\n * ```ts\n * export const manifest = { routes: [...], functions: [...], ... } as const;\n * export type Route = (typeof manifest.routes)[number];\n * // ...derived types\n * ```\n *\n * This is the dependency-free data contract shared between the producer\n * (`@geekmidas/cli`) and consumers (e.g. `@geekmidas/cloud/sst`'s `fromManifest`\n * integrators).\n *\n * The types below describe the **per-kind** manifest. The construct manifest\n * that replaces it — every construct keyed by id, with dependency edges — lives\n * in `./declaration`; both are exported while the migration runs.\n */\n\nexport type {\n\tAllProvidedKeys,\n\tAppSpec,\n\tCacheDeclaration,\n\tConstructId,\n\tConstructManifest,\n\tConstructName,\n\tCredentialDeclaration,\n\tCronDeclaration,\n\tDatabaseDeclaration,\n\tDatabaseReaderDeclaration,\n\tDatabaseSchemaDeclaration,\n\tDeclaration,\n\tDeclarationKind,\n\tDeclarationOf,\n\tDependency,\n\tDerivedDeclaration,\n\tDerivedKind,\n\tEmailDeclaration,\n\tFileServerDeclaration,\n\tFn,\n\tFunctionDeclaration,\n\tGlob,\n\tIdsOf,\n\tIdsOfKind,\n\tNode,\n\tObjectsDeclaration,\n\tOidcDeclaration,\n\tPostgresVersion,\n\tProvidedKeys,\n\tProvides,\n\tProvidesByKind,\n\tQueueDeclaration,\n\tRestApiDeclaration,\n\tRestApiEndpoint,\n\tSecretDeclaration,\n\tSiteDeclaration,\n\tTopicDeclaration,\n\tWorkerDeclaration,\n} from './declaration';\nexport {\n\tDEFAULT_APP_CODE,\n\tDEFAULT_POSTGRES_VERSION,\n\tDERIVES_FROM,\n\tPUBLIC,\n} from './declaration';\nexport {\n\tassertDerivations,\n\tdependenciesOf,\n\tdependentsOf,\n\tisDerived,\n\tPUBLIC_PREFIX,\n\tprovisionOrder,\n\tpublicEnvFor,\n} from './derive';\nexport {\n\tIllegalDerivation,\n\tInvalidConstructId,\n\tUnknownParent,\n} from './errors';\nexport {\n\tcacheTable,\n\tcanonicalId,\n\tcloudName,\n\tcookieDomain,\n\tenvironmentCase,\n\tkebabCase,\n\tprovidedKeyFor,\n\tprovideKey,\n\tscopedName,\n\tserviceKey,\n} from './naming';\n\n/**\n * A manifest field is either a flat list or, when the build is partitioned\n * (e.g. by authorizer), an object keyed by partition name. Readonly-tolerant so\n * the `as const` generated manifest assigns cleanly.\n */\nexport type ManifestField<T> =\n\t| readonly T[]\n\t| Readonly<Record<string, readonly T[]>>;\n\n/** Flatten a manifest field (array or partitioned) into a plain array. */\nexport function flattenManifestField<T>(\n\tfield: ManifestField<T> | undefined,\n): T[] {\n\tif (!field) return [];\n\treturn Array.isArray(field)\n\t\t? [...field]\n\t\t: Object.values(field as Record<string, readonly T[]>).flat();\n}\n\n/** A single HTTP route. */\nexport interface RouteInfo {\n\t/** Route path, e.g. `/users/{id}`. */\n\tpath: string;\n\t/** HTTP method, e.g. `GET`. */\n\tmethod: string;\n\t/** Bundled handler entrypoint. */\n\thandler: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\t/** Required environment variables (a trailing `?` marks an optional var). */\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n\t/** Authorizer name: `none`, `iam`, or a declared authorizer. */\n\tauthorizer: string;\n}\n\n/** A standalone Lambda function. */\nexport interface FunctionInfo {\n\tname: string;\n\thandler: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/** A scheduled (cron) function. */\nexport interface CronInfo {\n\tname: string;\n\thandler: string;\n\t/** Schedule expression, e.g. `rate(1 day)` or `cron(0 12 * * ? *)`. */\n\tschedule: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/** An event subscriber function (topic/queue resolved by `transport`). */\nexport interface SubscriberInfo {\n\tname: string;\n\thandler: string;\n\tsubscribedEvents: readonly string[];\n\t/** Delivery transport — `topic` (SNS fan-out) or `queue` (SQS). */\n\ttransport?: 'topic' | 'queue';\n\t/** The {@link TopicInfo.name} this subscriber binds to (via `s.topic(topic)`). */\n\ttopic?: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/**\n * A pub/sub topic — fan-out. A *resource* (no handler): it declares the event\n * contract; producers publish via the derived publisher and {@link SubscriberInfo}s\n * bind to it. Infra provisions an SNS topic.\n */\nexport interface TopicInfo {\n\tname: string;\n\t/** The event type names this topic carries. */\n\tevents: readonly string[];\n\t/** Whether the topic is FIFO. */\n\tfifo?: boolean;\n}\n\n/** A queue worker — a queue and its single consumer. */\nexport interface QueueInfo {\n\tname: string;\n\thandler: string;\n\t/** SQS event-source batch size. */\n\tbatchSize?: number;\n\t/** Whether the queue is FIFO. */\n\tfifo?: boolean;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs the worker declared an edge to, by id.\n\t *\n\t * See {@link RouteInfo.dependencies} — same field, same reason.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/**\n * The full deployment manifest — the shape of `export const manifest` in a\n * generated `manifest/<provider>.ts`. Each field is a {@link ManifestField}\n * (flat or partitioned).\n */\nexport interface Manifest {\n\troutes: ManifestField<RouteInfo>;\n\tfunctions?: ManifestField<FunctionInfo>;\n\tcrons?: ManifestField<CronInfo>;\n\tsubscribers?: ManifestField<SubscriberInfo>;\n\tqueues?: ManifestField<QueueInfo>;\n\ttopics?: ManifestField<TopicInfo>;\n}\n"],"x_google_ignoreList":[2],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DEFAULT_POSTGRES_VERSION: PostgresVersion","DERIVES_FROM: Readonly<Record<DerivedKind, readonly string[]>>","PUBLIC: {\n\treadonly [K in keyof ProvidesByKind]: readonly (keyof ProvidesByKind[K])[];\n}","input: string","canonical: string","id: string","of: string","available: readonly string[]","kind: string","parentKind: string","allowed: readonly string[]","name: string","id: string","role: string","input: string","value: string","scope: { stage: string; app: string }","scope: readonly string[]","urls: readonly string[]","shared: string[]","kind: DeclarationKind","declaration: Declaration","manifest: ConstructManifest","ordered: string[]","id: string","id: ConstructId","callers: string[]","PUBLIC_PREFIX: Record<SiteDeclaration['variant'], string>","declaration: SiteDeclaration","keys: Record<string, string>","field: ManifestField<T> | undefined"],"sources":["../src/declaration.ts","../src/errors.ts","../../../node_modules/.pnpm/lodash.snakecase@4.1.1/node_modules/lodash.snakecase/index.js","../src/naming.ts","../src/derive.ts","../src/index.ts"],"sourcesContent":["/**\n * The construct manifest — the contract between what an application declares\n * and what a target adapter provisions.\n *\n * Kinds are added here as each one lands, not up front: a declaration for a\n * construct nobody has built yet is a guess that the implementation will\n * contradict. See `docs/design/constructs-paradigm.md`.\n */\n\n/**\n * A construct's canonical id — PascalCase, unique within the manifest.\n *\n * Inputs canonicalise, so `uploads`, `Uploads`, `user_uploads`, and\n * `user-uploads` are the *same* id rather than four that collide. Everything\n * else derives from it: the service key is its `Uncapitalize`, the env prefix\n * its SCREAMING_SNAKE form, the cloud name its kebab form scoped by stage and\n * app.\n */\nexport type ConstructId = string;\n\ntype Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';\n\n/**\n * Constrains a construct name at the point it is written.\n *\n * Resolves to the name itself when valid, and otherwise to a string explaining\n * why — so the compiler reports *\"not assignable to type 'a construct name\n * cannot start with a digit'\"* rather than the unhelpful `never`.\n *\n * Only the cases a template-literal type can see are caught here; `canonicalId`\n * enforces the rest at runtime, which is also what covers JavaScript callers.\n *\n * @example new ObjectStorage('Uploads') // ok\n * @example new ObjectStorage('2fa') // a construct name cannot start with a digit\n */\nexport type ConstructName<S extends string> = S extends ''\n\t? 'a construct name cannot be empty'\n\t: S extends `${Digit}${string}`\n\t\t? 'a construct name cannot start with a digit'\n\t\t: S;\n\n/** Shared by every declaration. */\nexport interface Node {\n\tid: ConstructId;\n\t/**\n\t * Env keys this construct resolves onto anything that depends on it.\n\t * Names only — the values are composed by the adapter from the provisioned\n\t * resource's own attributes.\n\t */\n\tprovides?: readonly string[];\n\t/**\n\t * Env keys this construct needs. Derivable from `dependencies`, so it is an\n\t * assertion rather than an input: the adapter composes env from the edges and\n\t * checks the result against this, which catches app/infra drift at synth.\n\t */\n\trequires?: readonly string[];\n}\n\n/**\n * A dependency edge. Records only *what* is depended on — never permissions.\n * From one edge the framework derives env and the runtime binding; a target\n * adapter separately derives cloud access.\n */\nexport interface Dependency<TTarget extends ConstructId = ConstructId> {\n\t/**\n\t * The {@link ConstructId} of the consumed construct. Left open here because a\n\t * declaration is written before the manifest that contains it; once assembled,\n\t * `IdsOf` narrows it and the build's reference-integrity check enforces it.\n\t */\n\ttarget: TTarget;\n\tkind: DeclarationKind;\n}\n\n/** Anything with a handler. */\nexport interface Fn extends Node {\n\thandler: string;\n\tdependencies: readonly Dependency[];\n}\n\n// ---------------------------------------------------------------------------\n// Kinds\n// ---------------------------------------------------------------------------\n\n/** Blob storage. `--target=aws` provisions a bucket. */\nexport interface ObjectsDeclaration extends Node {\n\tkind: 'objects';\n\tversioned?: boolean;\n}\n\n/**\n * A domain that serves a bucket's objects.\n *\n * Its own construct rather than a flag on the bucket, because three things it\n * has to express are not properties of a bucket: a surface can front several\n * origins, a bucket can have several surfaces over it, and issuing a\n * certificate and writing a DNS record is a domain lifecycle that has no\n * business living inside an `objects` provisioner. It shares its infrastructure\n * with a static site rather than with storage — a site is the same\n * distribution over a build output instead of over live contents.\n *\n * It derives from the bucket by `of`, which costs the one thing the flag gave\n * for free: the bucket alone no longer says whether it is served, and finding\n * out means finding whoever points at it. That is answered the way every other\n * derivation is — the reference check at manifest build, so an unresolvable\n * origin is a build failure and `gkm` can name, for any bucket, the surfaces\n * over it.\n *\n * Private by default. `open` is an exception list, because a bucket where\n * forgetting a flag publishes user uploads is the wrong default — and paths\n * rather than per-object flags, because a path pattern is what the\n * infrastructure actually enforces and a per-object ACL is a thing nobody\n * audits.\n *\n * \"Open\" never means the bucket is world-readable. It means the server serves\n * that path without a signature; the bucket is private in both cases.\n */\nexport interface FileServerDeclaration extends Node {\n\tkind: 'file-server';\n\t/** The bucket whose objects it serves. */\n\tof: ConstructId;\n\t/**\n\t * Paths served without a signature — everything else requires one.\n\t *\n\t * Globs, matched most-literally by the infrastructure: a CDN keys its\n\t * behaviours off path patterns, and a bucket policy names prefixes.\n\t */\n\topen?: readonly string[];\n}\n\n/**\n * Outbound email.\n *\n * Provides one `smtp://` URL and nothing else, because email is delivered over\n * SMTP whatever the provider — Mailpit locally, SES through its SMTP interface,\n * Resend and Postmark through theirs. There is no `provider` field here for the\n * same reason there is no `ses://` scheme: which service delivers the mail\n * differs between dev and prod, so by this design's own test it is stage-varying\n * config rather than a structural fact about the app.\n *\n * What *is* structural is only that the app sends mail at all. The sending\n * domain is not: it is `myapp.test` locally and `example.com` deployed, so it\n * fails the same test the provider does and resolves at deploy alongside every\n * other address.\n */\nexport interface EmailDeclaration extends Node {\n\tkind: 'email';\n}\n\n/**\n * A logical database, its schema, and the roles that reach it.\n *\n * Provides one key — the *runtime* role's URL. The owner URL exists but is\n * deliberately absent from `provides`: it is wired by the adapter straight into\n * the migrator and seeder this construct declares, so no edge in any manifest\n * can name it and nothing else can be granted it by mistake.\n */\n/**\n * The Postgres major versions this toolbox provisions.\n *\n * A union rather than a string, because the two targets that read it are not\n * equally forgiving: locally it becomes a container tag, where a typo yields a\n * confusing pull failure, and on AWS it becomes an engine version, where a\n * wrong value fails partway through a deploy. Both are better as a compile\n * error.\n *\n * The union is what this toolbox knows how to name, not a promise that every\n * target offers every one of them. A deployed stage is limited by the engine\n * catalogue in its region, so check before pinning an unusual version:\n *\n * ```\n * aws rds describe-db-engine-versions --engine postgres \\\n * --query 'DBEngineVersions[].EngineVersion' --output text\n * ```\n *\n * RDS offered 11 through 18 in `eu-west-1` when this was written. 11 and 12 are\n * left out because they are past upstream end-of-life: still provisionable, but\n * not something to make easy to reach for.\n */\nexport type PostgresVersion = 13 | 14 | 15 | 16 | 17 | 18;\n\n/**\n * The version used when a database names none.\n *\n * The point is not which number this is but that there is only one of them.\n * Local ran 18 while Aurora provisioned its own default of 17.7, and nothing in\n * any declaration recorded the difference — a stage could behave differently\n * from a developer's machine for a reason neither could see. Both now read\n * this.\n */\nexport const DEFAULT_POSTGRES_VERSION: PostgresVersion = 18;\n\nexport interface DatabaseDeclaration extends Node {\n\tkind: 'database';\n\tengine?: 'postgres';\n\t/**\n\t * The engine's major version, read by every target that provisions one.\n\t *\n\t * Declared rather than configured per target, because a version set in a\n\t * compose file and a version set in a deploy config are two statements of\n\t * one fact — and they had already drifted apart, silently, by a major.\n\t *\n\t * Defaults to {@link DEFAULT_POSTGRES_VERSION}.\n\t */\n\tversion?: PostgresVersion;\n\t/**\n\t * The schema, pinned on both roles' `search_path`. Names the role the schema\n\t * plays rather than restating the database's own name, so `app` reads\n\t * correctly beside `auth` and `pgboss`.\n\t */\n\tschema?: string;\n\t/**\n\t * Whether to provision the owner/runtime role split. Off falls back to the\n\t * cluster's master credential in both URLs — a deliberate downgrade, not a\n\t * default. See `roles: false` in the design doc.\n\t */\n\troles?: boolean;\n}\n\n/**\n * A read-only endpoint on an existing database or schema.\n *\n * Provisions no cluster of its own — `of` names the parent it reads from.\n * Read-only is enforced by the role's grants rather than by which endpoint it\n * resolves to, so falling back to the writer where no replica exists stays safe.\n */\nexport interface DatabaseReaderDeclaration extends Node {\n\tkind: 'database-reader';\n\tof: ConstructId;\n}\n\n/**\n * A second schema inside an existing database, with its own role(s) and URL.\n *\n * The mechanism behind tenancy: the parent's role holds no grant on these\n * tables at all. pg-boss is an instance of this rather than a special case.\n */\nexport interface DatabaseSchemaDeclaration extends Node {\n\tkind: 'database-schema';\n\tof: ConstructId;\n\tschema: string;\n}\n\n/**\n * A generated secret — a signing key, a token, anything with no address.\n *\n * It provides a value rather than a URL, which is why it is a node of its own\n * instead of a field on whatever needs it: the thing that generates it, the\n * thing that stores it, and the thing that reads it are three different systems\n * deployed, and one derived string locally.\n */\nexport interface SecretDeclaration extends Node {\n\tkind: 'secret';\n}\n\n/**\n * A third-party credential with a shape.\n *\n * Distinct from {@link SecretDeclaration} by *lifecycle*, which is the only\n * distinction worth having two kinds for. A secret is generated and rotated by\n * the platform — `gkm secrets`, `sst secret set` — and is one opaque string\n * whose name is its key. A credential is issued by someone else, arrives with\n * several fields, and is validated on the way in: a Stripe key pair, an OAuth\n * client, a webhook signing secret.\n *\n * It provides one key holding a JSON object, rather than one key per field.\n * That is what a secret manager actually stores, and it is also the only shape\n * that works with an arbitrary StandardSchema — the spec has no introspection\n * API, so enumerating a schema's fields means reaching into one library's\n * internals and being wrong for every other.\n */\nexport interface CredentialDeclaration extends Node {\n\tkind: 'credential';\n}\n\n/**\n * An identity provider somebody else runs.\n *\n * Provisions nothing — the issuer already exists — so a target's whole job is\n * to hand the process an issuer and an audience, and the verifier discovers the\n * rest at runtime.\n *\n * It is a node rather than a field on whatever authenticates through it because\n * two surfaces can name the same provider, and because *which* population a\n * surface admits is a fact worth reading off the graph: an admin console\n * authenticated by the customer auth server is a finding, and it is only\n * visible if both are declarations.\n */\nexport interface OidcDeclaration extends Node {\n\tkind: 'oidc';\n\t/**\n\t * The issuer, when it does not vary by deployment.\n\t *\n\t * Absent means it arrives in the environment instead — a staging tenant, a\n\t * per-customer directory. The audience is never here: it identifies one\n\t * deployment to the provider.\n\t */\n\tissuer?: string;\n}\n\n/**\n * A key/value cache.\n *\n * Provides one URL. What is *in* that URL is the backend's business — Upstash's\n * REST API, a Redis endpoint, or a table in a database — and the scheme is what\n * picks the client, exactly as it does for object storage.\n *\n * Two ways to declare one, and the difference is a real statement rather than a\n * spelling. `new Cache('Sessions')` says *this app caches*, leaving where to the\n * deployment; `orders.cache('Sessions')` says *this app caches in that\n * database*, which is a fact about the application and belongs in its code. The\n * second is the same strengthening `orders.schema('AuthDb')` is over declaring a\n * second database.\n */\nexport interface CacheDeclaration extends Node {\n\tkind: 'cache';\n\t/**\n\t * The database this cache lives in, when it lives in one.\n\t *\n\t * Present only for a cache derived from a database. It removes a guess the\n\t * backend selection otherwise has to make — \"the declared database\" is\n\t * unambiguous with one and arbitrary with two — and it means the table's\n\t * schema and the role that reaches it come from the parent rather than from\n\t * a second convention.\n\t */\n\tof?: ConstructId;\n\t/**\n\t * The table entries are kept in, resolved against the connection's\n\t * `search_path`. Defaults to `cache`.\n\t */\n\ttable?: string;\n}\n\n/**\n * An HTTP surface and the handlers mounted on it.\n *\n * The first kind that is not a resource in the ordinary sense: it owns an\n * address, and the functions it triggers are *nested inside it* rather than\n * listed beside it, because position carries the trigger — a handler here is\n * reached by its method and path and by nothing else.\n *\n * `authorizers` are names. A bare string is resolved by the target (`iam`), while\n * a {@link ConstructId} names a construct that carries its own implementation,\n * its database dependency, and its session typing.\n */\nexport interface RestApiDeclaration extends Node {\n\tkind: 'rest-api';\n\t/**\n\t * Where the process serving it is built from, relative to the workspace\n\t * root — the same thing a `site` says, for the same reason.\n\t *\n\t * A surface is a deploy unit: one of these is one server. Without it the\n\t * deploy had to ask the *config* which apps to build, and a surface could\n\t * never be its own process because it was not in that list. Two surfaces in\n\t * one app then had to share one container, which is how an auth server ended\n\t * up mounted into an API by a hook.\n\t *\n\t * Optional, and its absence is meaningful: a surface with no app of its own\n\t * is served by the surface that named it — an auth server mounted into the\n\t * API that called `.auth()` on it, rather than a second container nobody\n\t * asked for.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * The construct that authenticates this surface.\n\t *\n\t * An edge like any other — so the auth server learns this surface's origin,\n\t * and the two share a cookie domain — but a *named* one, because \"who\n\t * authenticates me\" is a different fact from \"who I happen to call\", and\n\t * only one of them decides what a request is allowed to be.\n\t *\n\t * It is the id rather than the client: what every endpoint consumes is\n\t * `verify(request) → Session | null`, and that is the one thing every\n\t * provider shares. A surface names its authenticator; the target decides\n\t * what verifying means.\n\t */\n\tauth?: ConstructId;\n\t/**\n\t * CORS tunables for this surface.\n\t *\n\t * *Who* may call it is never here — that is derived from the constructs\n\t * declaring an edge to this surface, and arrives as `<ID>_TRUSTED_ORIGINS`.\n\t * A hand-written origin list is the thing this model removes; these are the\n\t * knobs that genuinely cannot be derived from a graph.\n\t *\n\t * Omitted entirely, a surface still gets CORS — with the derived origins and\n\t * sensible defaults. There is nothing to opt into.\n\t */\n\tcors?: {\n\t\t/** Preflight cache lifetime in seconds. Default 86400. */\n\t\tmaxAge?: number;\n\t\t/** Whether the browser may send credentials. Default true. */\n\t\tcredentials?: boolean;\n\t\t/** Extra request headers to allow, beyond content-type and authorization. */\n\t\tallowHeaders?: readonly string[];\n\t\t/** Response headers the browser may read. */\n\t\texposeHeaders?: readonly string[];\n\t};\n\tauthorizers?: readonly string[];\n\t/** The authorizer applied where an endpoint names none. */\n\tdefaultAuthorizer?: string;\n\t/**\n\t * Every route on this surface.\n\t *\n\t * Complete, always — a manifest that says \"the routes are over there, run\n\t * this glob to find them\" is not a manifest, it is a pointer to one. An\n\t * earlier version carried a `routes` glob for an application's own API and\n\t * left this empty, which meant the document *claimed no routes* while five\n\t * existed. Being incomplete is a gap; being wrong is worse.\n\t *\n\t * So a surface takes its endpoints as a list and reads method, path and\n\t * handler off them. That also removes a duplicate: the glob was written once\n\t * in `gkm.config.ts` and again on the construct, two strings that could\n\t * disagree about the same thing.\n\t */\n\tendpoints: readonly RestApiEndpoint[];\n\t/**\n\t * Other surfaces this one calls.\n\t *\n\t * **Not a dependency, and deliberately not spelled like one.** A dependency\n\t * is an injection: `resolveEdges` gives a function exactly the constructs it\n\t * declared and nothing else, which is what makes least privilege fall out of\n\t * the graph instead of out of discipline. A surface-level `dependencies`\n\t * would hand *every route* on this API whatever the surface named — which is\n\t * precisely the over-granting that rule exists to prevent.\n\t *\n\t * What this records is weaker and only flows one way: it puts this API's\n\t * origin on the called surface's trusted-origin list. Nothing links from it,\n\t * nothing is granted by it, and per-route edges stay on the endpoints where\n\t * they belong.\n\t */\n\tcalls?: readonly Dependency[];\n}\n\n/** One glob, or several. Mirrors the CLI's `Routes` without depending on it. */\nexport type Glob = string | readonly string[];\n\n/**\n * How the process serving a declaration is built and run.\n *\n * The half of an application that a graph genuinely cannot derive. *What*\n * exists — a surface, a site, the edges between them — is declared and read\n * back from the manifest. *Where its source lives and which globs find its\n * code* is not derivable from anything: it is a fact about a directory.\n *\n * It lives on the declaration rather than in a config `apps` block because the\n * two were the same list written twice, and the copy in config was the one that\n * could disagree. A site declared `path: 'apps/web'` and an app entry declared\n * `path: 'apps/web'`, and nothing checked them against each other; a surface\n * that config had no entry for simply never deployed.\n *\n * Only the declaration that *is* an app carries one. Two surfaces in one\n * process means one of them has the spec and the other collapses onto it —\n * which is the same rule that decides deploy units, now stated once.\n */\nexport interface AppSpec {\n\t/**\n\t * Where its source lives, relative to the workspace root.\n\t *\n\t * Optional, and normally omitted: `apps/<kebab-id>` when that directory\n\t * exists, and the workspace root otherwise. An `Api` construct in a monorepo\n\t * means `apps/api`, and in a single-app project it means `.` — both of which\n\t * are answerable by looking.\n\t *\n\t * Set one only when the layout is genuinely different, e.g.\n\t * `path: 'services/api'`.\n\t */\n\tpath?: string;\n\t/**\n\t * The port it answers on locally.\n\t *\n\t * Optional, and normally omitted: ports are assigned in a stable order so\n\t * that adding a site does not renumber the others.\n\t */\n\tport?: number;\n\ttelescope?: string | boolean | Record<string, unknown>;\n\tstudio?: string | boolean | Record<string, unknown>;\n\topenapi?: boolean | Record<string, unknown>;\n\truntime?: 'node' | 'bun';\n\t/** Env files to load, in order. */\n\tenv?: Glob;\n\t/** Entry module for an app the build does not generate. */\n\tentry?: string;\n\t/** Modules to import when sniffing which env vars a frontend reads. */\n\tconfig?: { client?: string; server?: string };\n}\n\n/**\n * A frontend — a construct like any other, which is what removes the last\n * mechanism that ran in parallel to the graph.\n *\n * Its edges are what make it worth declaring. A site depending on an API is the\n * single fact behind four things that are hand-maintained otherwise: the site's\n * build-time `VITE_API_URL`, the API's CORS origins, the auth server's trusted\n * origins, and which generated client lands in which app. None of those are\n * declared anywhere here, because all four are the *same* edge read from one\n * end or the other.\n *\n * `variant` is the framework, because the framework changes the code you write:\n * it selects how the values are delivered (`VITE_`, `NEXT_PUBLIC_`, a\n * `config.json`), never which values there are.\n */\nexport interface SiteDeclaration extends Node {\n\tkind: 'site';\n\tvariant: 'static' | 'next' | 'tanstack';\n\t/**\n\t * How it is built and run, `path` included.\n\t *\n\t * Required, where a surface's is optional: a site is always its own app.\n\t * There is no arrangement in which two sites are one process.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * Whether this is the site the base domain points at.\n\t *\n\t * Structural rather than config: *which* site is primary does not vary by\n\t * stage, even though its hostname does — that is what `app.domain` is for.\n\t *\n\t * Only meaningful when a project has more than one site, and then only when\n\t * none of them is named `web`. The convention still holds first, because it\n\t * is a convention people already rely on.\n\t */\n\troot?: boolean;\n\t/**\n\t * What it calls. On a node rather than on a handler because a site has no\n\t * single entrypoint — the whole app is the consumer.\n\t */\n\tdependencies: readonly Dependency[];\n}\n\n/**\n * A process with no port.\n *\n * The sibling of `RestApiDeclaration`, and the answer to a question the model\n * could not previously state: *what runs this cron?* A cron, a subscriber and a\n * queue consumer all have to run somewhere, and until now the only thing that\n * said where was the directory the file happened to sit in — so a background\n * job was owned by a glob, and a project that was nothing but background jobs\n * had to declare an HTTP surface with no routes on it to be deployable at all.\n *\n * It takes no authorizer. A `RestApi` needs one because an HTTP surface can\n * ship open by omission; nothing calls a worker from outside, so there is no\n * default to get wrong. That difference is the reason these are two constructs\n * rather than one with a flag.\n */\nexport interface WorkerDeclaration extends Node {\n\tkind: 'worker';\n\t/**\n\t * A worker declares no app, because it is not one.\n\t *\n\t * It names the process that runs a cron, a subscriber or a queue consumer —\n\t * and that process is the app's server, the same one the endpoints run in,\n\t * without an HTTP surface of its own. Giving it a path made it a second\n\t * container to build, deploy and keep alive for work that was already going\n\t * to run somewhere.\n\t */\n\t/** Surfaces and resources it calls, which is what grants it access. */\n\tdependencies?: readonly Dependency[];\n}\n\n/** One route on a surface. */\nexport interface RestApiEndpoint extends Fn {\n\tmethod: string;\n\tpath: string;\n\tauthorizer?: string;\n}\n\n/**\n * A point-to-point queue and the single consumer that drains it.\n *\n * Provides one key, the producer's connection string. The protocol in it picks\n * the transport — `pgboss://` locally, `sqs://` deployed — so a producer names\n * no broker, exactly as a database consumer names no cloud.\n *\n * The consumer side provides nothing: a worker is reached *through* its queue,\n * so there is no second key and nothing can depend on a handler.\n */\nexport interface QueueDeclaration extends Node {\n\tkind: 'queue';\n\t/** FIFO ordering, where the transport offers it. */\n\tfifo?: boolean;\n\t/**\n\t * The single consumer that drains it.\n\t *\n\t * Nested rather than listed beside the queue, because **position carries the\n\t * trigger**: a handler here is reached by messages arriving on this queue and\n\t * by nothing else, so there is no `trigger` field to keep in step with it.\n\t */\n\tworker: Fn;\n}\n\n/**\n * A topic — pub/sub fan-out, one publisher and any number of subscribers.\n *\n * Like a queue it provides only the producer's string; a subscriber is bound to\n * the topic rather than depending on it, so the binding is an edge the deploy\n * target reads, not an env key. Locally both sides meet on the same pg-boss\n * connection, which is why the subscriber needs no key of its own.\n */\nexport interface TopicDeclaration extends Node {\n\tkind: 'topic';\n\t/** The event type names this topic carries. */\n\tevents: readonly string[];\n\t/**\n\t * The handlers bound to it, each with the events it wants.\n\t *\n\t * Nested for the same reason a queue's worker is: position is the trigger. A\n\t * subscriber is *bound* to a topic rather than depending on it, which is why\n\t * it holds no key of its own and cannot be reached except through the topic.\n\t */\n\tsubscribers: readonly (Fn & { events: readonly string[] })[];\n}\n\n/**\n * A function invoked directly, with no surface in front of it.\n *\n * An `Fn` rather than a `Node`, because a function *is* a handler — there is no\n * resource beside it to declare. It provides its own address, so something else\n * can depend on it and be given a way to call it.\n */\nexport interface FunctionDeclaration extends Fn {\n\tkind: 'function';\n}\n\n/**\n * A function on a schedule.\n *\n * The schedule is the trigger and it is structural: *that* something runs\n * nightly is a fact about the application, while which timezone a stage\n * interprets it in is not.\n */\nexport interface CronDeclaration extends Fn {\n\tkind: 'cron';\n\t/** A rate or cron expression, e.g. `rate(1 day)`. */\n\tschedule: string;\n}\n\n/**\n * Every declaration. A discriminated union, so `kind` gives exhaustiveness *and*\n * per-kind fields — there is no separate enum to keep in step, and no shape\n * carrying fields that belong to a different kind.\n */\nexport type Declaration =\n\t| ObjectsDeclaration\n\t| FileServerDeclaration\n\t| EmailDeclaration\n\t| DatabaseDeclaration\n\t| DatabaseReaderDeclaration\n\t| DatabaseSchemaDeclaration\n\t| CacheDeclaration\n\t| SecretDeclaration\n\t| CredentialDeclaration\n\t| RestApiDeclaration\n\t| SiteDeclaration\n\t| WorkerDeclaration\n\t| OidcDeclaration\n\t| QueueDeclaration\n\t| TopicDeclaration\n\t| FunctionDeclaration\n\t| CronDeclaration;\n\n/** A declaration that provisions nothing of its own and names a parent. */\n/**\n * A declaration that names a parent.\n *\n * A union rather than an `Extract`, because one kind is *optionally* derived: a\n * cache lives in a database when it was declared from one and stands alone\n * otherwise, so `of` is optional on it and an `Extract<…, { of: ConstructId }>`\n * would not select it. {@link isDerived} tests the value rather than the kind\n * for exactly that reason.\n */\nexport type DerivedDeclaration =\n\t| Extract<Declaration, { of: ConstructId }>\n\t| CacheDeclaration;\n\nexport type DerivedKind = DerivedDeclaration['kind'];\n\n/**\n * What each kind may derive from.\n *\n * Small enough to state exhaustively, and stating it makes cycles impossible\n * without a graph walk: readers are terminal, so no chain can return to its\n * start. There is no `writer` — the database *is* the writer, which is what\n * keeps a replica from being reached by accident.\n */\nexport const DERIVES_FROM: Readonly<Record<DerivedKind, readonly string[]>> = {\n\t'database-reader': ['database', 'database-schema'],\n\t'database-schema': ['database'],\n\t// A file server derives from what it serves. Unlike the database pair it\n\t// shares the parent's *contents* rather than its credentials, which is why\n\t// it is a construct of its own and only its node is derived.\n\t'file-server': ['objects'],\n\t// A cache in a database is a table in it, reached by the same role — so it\n\t// derives from either a database or a tenant of one, and a tenant's cache\n\t// lands in the tenant's schema without naming it.\n\tcache: ['database', 'database-schema'],\n};\n\nexport type DeclarationKind = Declaration['kind'];\n\n/**\n * The manifest: every construct keyed by its id.\n *\n * Flat rather than grouped, because `Dependency.target` resolves as\n * `m[target]` — a lookup that stays O(1) and identical whether the edge points\n * at a resource, a surface, or another function.\n *\n * Use it as a **constraint, not an annotation**. `gkm build` emits\n * `as const satisfies ConstructManifest`, which checks the shape while keeping\n * every id, kind, and provided key a literal — annotating with this type\n * instead would widen them all to `string` and consumers could no longer select\n * anything:\n *\n * ```ts\n * export const manifest = {\n * Uploads: { kind: 'objects', id: 'Uploads', provides: ['UPLOADS_URL'] },\n * } as const satisfies ConstructManifest;\n *\n * type Ids = IdsOf<typeof manifest>; // 'Uploads'\n * type Env = ProvidedKeys<typeof manifest, 'Uploads'>; // 'UPLOADS_URL'\n * ```\n */\nexport type ConstructManifest = Readonly<Record<ConstructId, Declaration>>;\n\n// ---------------------------------------------------------------------------\n// Selecting from a concrete manifest\n// ---------------------------------------------------------------------------\n\n/** Every id in a manifest. */\nexport type IdsOf<M extends ConstructManifest> = Extract<keyof M, string>;\n\n/** The declaration for one id. */\nexport type DeclarationOf<\n\tM extends ConstructManifest,\n\tK extends IdsOf<M>,\n> = M[K];\n\n/** Every id of a given kind — what an adapter iterates when provisioning. */\nexport type IdsOfKind<\n\tM extends ConstructManifest,\n\tK extends DeclarationKind,\n> = {\n\t[Id in IdsOf<M>]: M[Id]['kind'] extends K ? Id : never;\n}[IdsOf<M>];\n\n/** The env keys one construct provides. */\nexport type ProvidedKeys<\n\tM extends ConstructManifest,\n\tK extends IdsOf<M>,\n> = M[K] extends { provides: readonly (infer P)[] } ? P : never;\n\n/** Every env key any construct in the manifest provides. */\nexport type AllProvidedKeys<M extends ConstructManifest> = {\n\t[Id in IdsOf<M>]: ProvidedKeys<M, Id>;\n}[IdsOf<M>];\n\n// ---------------------------------------------------------------------------\n// The app ↔ infra contract\n// ---------------------------------------------------------------------------\n\n/**\n * What each kind provides, by role rather than by provider syntax.\n *\n * This is the contract between the construct that declares a key and the cloud\n * component that supplies its value — an interface rather than shared code,\n * because a shared codec would have to contain `bucket` and `region`, and\n * provider words in the neutral layer is the problem this design exists to fix.\n *\n * How a value is composed and parsed stays private to each provider pair, so\n * `s3://` and `gs://` never appear here.\n */\nexport interface ProvidesByKind {\n\tobjects: { url: string };\n\t/** Where the served objects answer. Public: a browser is the point of it. */\n\t'file-server': { url: string };\n\t/**\n\t * An `smtp://` URL, credentials included — never shippable — and the\n\t * identity mail is sent from.\n\t *\n\t * The sending address is the one thing about mail that genuinely differs per\n\t * stage (`myapp.test` locally, a verified domain deployed), so it travels\n\t * beside the URL rather than being written into the construct.\n\t */\n\temail: { url: string; from: string };\n\t/**\n\t * One key, the runtime role's. The owner URL is not here by design — see\n\t * {@link DatabaseDeclaration}.\n\t */\n\tdatabase: { url: string };\n\t'database-reader': { url: string };\n\t'database-schema': { url: string };\n\t/** The endpoint and its token, in one string. */\n\tcache: { url: string };\n\t/**\n\t * Where the surface answers, who may call it, and the domain its cookies\n\t * are scoped to.\n\t *\n\t * Only `url` is a fact about the surface itself. The other two are read off\n\t * its *inbound* edges — every construct that depends on it — which is why a\n\t * surface never lists its own callers: nothing enumerates the things that\n\t * point at it, the graph already does.\n\t *\n\t * `trustedOrigins` and `cookieDomain` are one key each rather than a list\n\t * and a structure, because both cross a process boundary as environment.\n\t */\n\t'rest-api': {\n\t\turl: string;\n\t\t/** Comma-separated. Empty when nothing declares an edge to this surface. */\n\t\ttrustedOrigins: string;\n\t\t/**\n\t\t * The parent domain shared by the surface and its callers, leading dot\n\t\t * included — `.example.com`. Absent where there is nothing to share:\n\t\t * one host locally, unrelated hosts deployed.\n\t\t */\n\t\tcookieDomain: string;\n\t};\n\t/** The value itself. A secret has no address to hand out instead. */\n\tsecret: { value: string };\n\t/**\n\t * The credential as one JSON object, parsed and validated by the construct\n\t * that declared the schema.\n\t */\n\tcredential: { credential: string };\n\t/**\n\t * The producer's connection string. One key, not two: the consumer is\n\t * reached through the queue rather than by an address of its own.\n\t */\n\tqueue: { publisherConnectionString: string };\n\ttopic: { publisherConnectionString: string };\n\t/** Where to invoke it — what lets something else depend on a function. */\n\tfunction: { url: string };\n\t/** A cron is reached by its schedule and by nothing else, so it provides none. */\n\tcron: Record<never, never>;\n\t/** Where the site is served. Public for the same reason an API's is. */\n\tsite: { url: string };\n\t/**\n\t * Where tokens come from and which audience they must carry.\n\t *\n\t * Two keys because the halves have different lifetimes: the issuer may be a\n\t * fact about the product, the audience is always a fact about one\n\t * deployment.\n\t */\n\toidc: { issuer: string; audience: string };\n\t/**\n\t * A worker is reached by nothing — it reaches out, to a queue, a schedule,\n\t * a topic. So it publishes no address, the way a cron does not.\n\t */\n\tworker: Record<never, never>;\n}\n\nexport type Provides<K extends keyof ProvidesByKind> = ProvidesByKind[K];\n\n/**\n * Which provided values may be shipped to a browser.\n *\n * Drives client-side prefixing (`VITE_`, `NEXT_PUBLIC_`) and nothing else — it\n * is not a restriction on what may be depended on, since a server-side consumer\n * can legitimately use any of them. A bucket's `url` presigns and stays private.\n */\nexport const PUBLIC: {\n\treadonly [K in keyof ProvidesByKind]: readonly (keyof ProvidesByKind[K])[];\n} = {\n\tobjects: [],\n\t// The address a browser fetches an image from. The bucket's own URL is not\n\t// here and must not be: it presigns, and a presigner in a bundle is a\n\t// credential in a bundle.\n\t'file-server': ['url'],\n\t// Carries the SMTP credentials in its userinfo.\n\temail: [],\n\t// A connection string is never shippable, whichever role it carries.\n\tdatabase: [],\n\t'database-reader': [],\n\t'database-schema': [],\n\t// Carries its token, and a cache a browser can write is a cache it can\n\t// poison.\n\tcache: [],\n\t// The whole point of one.\n\tsecret: [],\n\t// A credential a browser can read is a credential anyone can read. A\n\t// publishable key belongs in the site's own config, not in this.\n\tcredential: [],\n\t// A URL a browser calls is a URL a browser may hold. The other two are not\n\t// secret either — they are simply server-side facts, and prefixing a value\n\t// into a bundle that nothing there reads is how a bundle grows keys nobody\n\t// can account for.\n\t'rest-api': ['url'],\n\t// Carries broker credentials, and a browser that can publish to a queue can\n\t// forge any job the worker trusts.\n\tqueue: [],\n\ttopic: [],\n\t// A browser doing the sign-in flow needs both, and neither is secret: an\n\t// issuer is a public URL and an audience is a client id, which is the half\n\t// of an OAuth client that is meant to be seen.\n\toidc: ['issuer', 'audience'],\n\t// An invocation address is not a public one: reaching it is IAM's business,\n\t// not a browser's.\n\tfunction: [],\n\tcron: [],\n\t// Its own address, which it needs in order to build absolute links to\n\t// itself — and which an email templating a link to it needs too.\n\tsite: ['url'],\n\t// Nothing calls a worker, so there is no address to hand anyone. It reaches\n\t// out — to a queue, a schedule, a topic — and is reached by none of them.\n\tworker: [],\n};\n","/**\n * Manifest errors.\n *\n * Messages state the rule, which is constant; the offending value is a field.\n * An interpolated message cannot be matched on, reads differently every time it\n * is thrown, and carries user input into every log line that touches it.\n */\n\n/** A construct id that cannot survive the names derived from it. */\nexport class InvalidConstructId extends Error {\n\t/** What was passed in. */\n\treadonly input: string;\n\t/** What canonicalising it produced, which is what failed the rule. */\n\treadonly canonical: string;\n\n\tconstructor(input: string, canonical: string) {\n\t\tsuper(\n\t\t\t'A construct id must start with a letter and contain only letters and digits',\n\t\t);\n\t\tthis.name = 'InvalidConstructId';\n\t\tthis.input = input;\n\t\tthis.canonical = canonical;\n\t}\n}\n\n/** A derived construct naming a parent the manifest does not contain. */\nexport class UnknownParent extends Error {\n\t/** The derived construct. */\n\treadonly id: string;\n\t/** The parent it named. */\n\treadonly of: string;\n\t/** Ids the manifest does contain, for the caller to match against. */\n\treadonly available: readonly string[];\n\n\tconstructor(id: string, of: string, available: readonly string[]) {\n\t\tsuper('A derived construct must name a parent present in the manifest');\n\t\tthis.name = 'UnknownParent';\n\t\tthis.id = id;\n\t\tthis.of = of;\n\t\tthis.available = available;\n\t}\n}\n\n/**\n * A derived construct naming a parent that may not vend it — a reader of a\n * reader, a schema of a schema.\n */\nexport class IllegalDerivation extends Error {\n\treadonly id: string;\n\treadonly kind: string;\n\t/** The kind of the parent it named. */\n\treadonly parentKind: string;\n\t/** The parent kinds that may vend this one. */\n\treadonly allowed: readonly string[];\n\n\tconstructor(\n\t\tid: string,\n\t\tkind: string,\n\t\tparentKind: string,\n\t\tallowed: readonly string[],\n\t) {\n\t\tsuper('A derived construct must name a parent whose kind may vend it');\n\t\tthis.name = 'IllegalDerivation';\n\t\tthis.id = id;\n\t\tthis.kind = kind;\n\t\tthis.parentKind = parentKind;\n\t\tthis.allowed = allowed;\n\t}\n}\n","/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match words composed of alphanumeric characters. */\nvar reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n/** Used to match Latin Unicode letters (excluding mathematical operators). */\nvar reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe23',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20f0',\n rsDingbatRange = '\\\\u2700-\\\\u27bf',\n rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n rsPunctuationRange = '\\\\u2000-\\\\u206f',\n 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',\n rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n rsVarRange = '\\\\ufe0e\\\\ufe0f',\n rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n/** Used to compose unicode capture groups. */\nvar rsApos = \"['\\u2019]\",\n rsBreak = '[' + rsBreakRange + ']',\n rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',\n rsDigits = '\\\\d+',\n rsDingbat = '[' + rsDingbatRange + ']',\n rsLower = '[' + rsLowerRange + ']',\n rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsUpper = '[' + rsUpperRange + ']',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',\n rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',\n rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;\n\n/** Used to match apostrophes. */\nvar reApos = RegExp(rsApos, 'g');\n\n/**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\nvar reComboMark = RegExp(rsCombo, 'g');\n\n/** Used to match complex or compound words. */\nvar reUnicodeWord = RegExp([\n rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',\n rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,\n rsUpper + '+' + rsOptUpperContr,\n rsDigits,\n rsEmoji\n].join('|'), 'g');\n\n/** Used to detect strings that need a more robust regexp to match words. */\nvar reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n/** Used to map Latin Unicode letters to basic Latin letters. */\nvar deburredLetters = {\n // Latin-1 Supplement block.\n '\\xc0': 'A', '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n '\\xe0': 'a', '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n '\\xc7': 'C', '\\xe7': 'c',\n '\\xd0': 'D', '\\xf0': 'd',\n '\\xc8': 'E', '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n '\\xe8': 'e', '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n '\\xcc': 'I', '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n '\\xec': 'i', '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n '\\xd1': 'N', '\\xf1': 'n',\n '\\xd2': 'O', '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n '\\xf2': 'o', '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n '\\xd9': 'U', '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n '\\xf9': 'u', '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n '\\xdd': 'Y', '\\xfd': 'y', '\\xff': 'y',\n '\\xc6': 'Ae', '\\xe6': 'ae',\n '\\xde': 'Th', '\\xfe': 'th',\n '\\xdf': 'ss',\n // Latin Extended-A block.\n '\\u0100': 'A', '\\u0102': 'A', '\\u0104': 'A',\n '\\u0101': 'a', '\\u0103': 'a', '\\u0105': 'a',\n '\\u0106': 'C', '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n '\\u0107': 'c', '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n '\\u010e': 'D', '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n '\\u0112': 'E', '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n '\\u0113': 'e', '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n '\\u011c': 'G', '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n '\\u011d': 'g', '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n '\\u0124': 'H', '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n '\\u0128': 'I', '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n '\\u0129': 'i', '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n '\\u0134': 'J', '\\u0135': 'j',\n '\\u0136': 'K', '\\u0137': 'k', '\\u0138': 'k',\n '\\u0139': 'L', '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n '\\u013a': 'l', '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n '\\u0143': 'N', '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n '\\u0144': 'n', '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n '\\u014c': 'O', '\\u014e': 'O', '\\u0150': 'O',\n '\\u014d': 'o', '\\u014f': 'o', '\\u0151': 'o',\n '\\u0154': 'R', '\\u0156': 'R', '\\u0158': 'R',\n '\\u0155': 'r', '\\u0157': 'r', '\\u0159': 'r',\n '\\u015a': 'S', '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n '\\u015b': 's', '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n '\\u0162': 'T', '\\u0164': 'T', '\\u0166': 'T',\n '\\u0163': 't', '\\u0165': 't', '\\u0167': 't',\n '\\u0168': 'U', '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n '\\u0169': 'u', '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n '\\u0174': 'W', '\\u0175': 'w',\n '\\u0176': 'Y', '\\u0177': 'y', '\\u0178': 'Y',\n '\\u0179': 'Z', '\\u017b': 'Z', '\\u017d': 'Z',\n '\\u017a': 'z', '\\u017c': 'z', '\\u017e': 'z',\n '\\u0132': 'IJ', '\\u0133': 'ij',\n '\\u0152': 'Oe', '\\u0153': 'oe',\n '\\u0149': \"'n\", '\\u017f': 'ss'\n};\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction asciiWords(string) {\n return string.match(reAsciiWord) || [];\n}\n\n/**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyOf(object) {\n return function(key) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\nvar deburrLetter = basePropertyOf(deburredLetters);\n\n/**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\nfunction hasUnicodeWord(string) {\n return reHasUnicodeWord.test(string);\n}\n\n/**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\nfunction unicodeWords(string) {\n return string.match(reUnicodeWord) || [];\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\n/**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\nfunction createCompounder(callback) {\n return function(string) {\n return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n };\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\n/**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('déjà vu');\n * // => 'deja vu'\n */\nfunction deburr(string) {\n string = toString(string);\n return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n}\n\n/**\n * Converts `string` to\n * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the snake cased string.\n * @example\n *\n * _.snakeCase('Foo Bar');\n * // => 'foo_bar'\n *\n * _.snakeCase('fooBar');\n * // => 'foo_bar'\n *\n * _.snakeCase('--FOO-BAR--');\n * // => 'foo_bar'\n */\nvar snakeCase = createCompounder(function(result, word, index) {\n return result + (index ? '_' : '') + word.toLowerCase();\n});\n\n/**\n * Splits `string` into an array of its words.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {RegExp|string} [pattern] The pattern to match words.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the words of `string`.\n * @example\n *\n * _.words('fred, barney, & pebbles');\n * // => ['fred', 'barney', 'pebbles']\n *\n * _.words('fred, barney, & pebbles', /[^, ]+/g);\n * // => ['fred', 'barney', '&', 'pebbles']\n */\nfunction words(string, pattern, guard) {\n string = toString(string);\n pattern = guard ? undefined : pattern;\n\n if (pattern === undefined) {\n return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n }\n return string.match(pattern) || [];\n}\n\nmodule.exports = snakeCase;\n","/**\n * Name derivation — the single source for turning a construct's id into the\n * names that appear elsewhere.\n *\n * These live here rather than in each consumer because `@geekmidas/constructs`\n * derives a key when it declares, and `@geekmidas/cloud` derives the same key\n * when it supplies the value. Two implementations of the same rule is precisely\n * the drift this design exists to remove.\n */\n\nimport snakecase from 'lodash.snakecase';\nimport type { DeclarationKind } from './declaration';\n\nimport { InvalidConstructId } from './errors';\n\n/**\n * `UPPER_SNAKE_CASE`, with numbers kept against the word they follow.\n *\n * Matches `environmentCase` in `@geekmidas/envkit`, which reads the values these\n * names key. The two must agree exactly, so this is the implementation and that\n * one should defer to it.\n *\n * @example environmentCase('sendEmail') // 'SEND_EMAIL'\n * @example environmentCase('api2') // 'API2' (digit joins its word)\n */\nexport function environmentCase(name: string): string {\n\treturn snakecase(name)\n\t\t.toUpperCase()\n\t\t.replace(/_\\d+/g, (r) => r.replace('_', ''));\n}\n\n/**\n * The env key a construct provides for one of its roles.\n *\n * @example provideKey('Uploads', 'url') // 'UPLOADS_URL'\n * @example provideKey('Uploads', 'cdnUrl') // 'UPLOADS_CDN_URL'\n */\nexport function provideKey(id: string, role: string): string {\n\treturn environmentCase(`${id}_${role}`);\n}\n\n/**\n * A construct's canonical id — PascalCase.\n *\n * `uploads`, `Uploads`, `user_uploads`, and `user-uploads` all canonicalise to\n * the same id, so declaring two of them is a duplicate rather than a collision\n * to detect.\n *\n * Runtime only. Writing the id in PascalCase is what keeps the *type* usable:\n * the service key is `Uncapitalize<TName>`, a TypeScript intrinsic, so no\n * type-level transform is needed and none has to be kept in step with this one.\n *\n * @example canonicalId('user-uploads') // 'UserUploads'\n */\nexport function canonicalId(input: string): string {\n\t// `upperFirst(camelCase(x))` by another route — snakecase is already a\n\t// dependency, and adding lodash.camelcase for the same result is not worth it.\n\tconst id = snakecase(input)\n\t\t.split('_')\n\t\t.filter(Boolean)\n\t\t.map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n\t\t.join('');\n\n\tif (!VALID_ID.test(id)) throw new InvalidConstructId(input, id);\n\treturn id;\n}\n\n/**\n * A canonical id: PascalCase, letters and digits only.\n *\n * Narrower than a JavaScript identifier — `_id` and `$ref` are legal JavaScript\n * and rejected here — because the id also has to survive `environmentCase` into\n * an env key and `cloudName` into a DNS-safe resource name.\n */\nconst VALID_ID = /^[A-Z][A-Za-z0-9]*$/;\n\n/**\n * The key a construct is reached under in the service record.\n *\n * The runtime twin of `Uncapitalize<TName>`, which types it — they must agree,\n * so they live next to each other rather than being re-derived by each\n * construct.\n *\n * @example serviceKey('UserUploads') // 'userUploads' → services.userUploads\n */\nexport function serviceKey(id: string): string {\n\treturn id.charAt(0).toLowerCase() + id.slice(1);\n}\n\n/**\n * The table a cache keeps its entries in, when nobody named one.\n *\n * Derived from the cache's own id rather than fixed at `cache`, because a\n * database may hold more than one and two caches sharing a table share a\n * keyspace — `orders.cache('Sessions')` and `orders.cache('Rates')` would\n * silently read each other's entries and evict each other's keys.\n *\n * Prefixed rather than suffixed so every cache sorts together in `\\dt`, and\n * prefixed at all so a cache named for a thing the application also stores —\n * `orders.cache('Users')` — cannot collide with the table holding that thing.\n *\n * Read by whoever composes the URL and by whoever creates the table, so both\n * default the same way.\n *\n * @example cacheTable('Sessions') // 'cache_sessions'\n */\nexport function cacheTable(id: string): string {\n\treturn `cache_${id.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase()}`;\n}\n\n/**\n * Kebab-cases an identifier, acronym- and digit-aware.\n *\n * `userName` → `user-name`, `APIKey` → `api-key`, `S3Bucket` → `s3-bucket`.\n *\n * The last of those is why this is here rather than `snakecase(id)` with the\n * underscores swapped: lodash splits a digit from the letter beside it, so\n * `S3Bucket` became `s-3-bucket` on one provider and `s3-bucket` on the other.\n * Two implementations of one rule, agreeing on every id anybody had tried.\n *\n * `environmentCase` already corrected for the same thing in the other\n * direction — `api2` keeps its digit — so the two spellings of \"kebab this id\"\n * in this file did not even agree with each other.\n */\nexport function kebabCase(value: string): string {\n\treturn value\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n\t\t.replace(/[\\s_]+/g, '-')\n\t\t.toLowerCase();\n}\n\n/**\n * The physical name a target provisions a construct under — lowercase kebab,\n * scoped so two stages or apps sharing an account cannot collide.\n *\n * **One rule, every provider.** A construct is named the same thing on AWS and\n * on Dokploy, which is what lets a name be read across them: `Database` in the\n * `production` stage of `kitchen-sink` is `production-kitchen-sink-database`\n * wherever it lands. The SST target's `prefixedName` is this function under\n * another signature and defers to it.\n *\n * Idempotent in its prefix: an id that already carries the scope is not given a\n * second one, so composing names cannot double up.\n *\n * @example cloudName({ stage: 'prod', app: 'myapp' }, 'UserUploads')\n * // 'prod-myapp-user-uploads'\n */\nexport function cloudName(\n\tscope: { stage: string; app: string },\n\tid: string,\n): string {\n\treturn scopedName([scope.stage, scope.app], id);\n}\n\n/**\n * {@link cloudName} for a caller that holds its scope as a list.\n *\n * The SST target's stacks add a segment of their own, so the prefix is not\n * always two parts — which is the only reason this signature exists.\n */\nexport function scopedName(scope: readonly string[], id: string): string {\n\tconst prefix = scope.join('-').toLowerCase();\n\tconst name = kebabCase(id);\n\n\treturn name.startsWith(prefix) ? name : `${prefix}-${name}`;\n}\n\n/**\n * The domain a cookie must be scoped to so a surface and its callers share it.\n *\n * Derived from the addresses rather than configured, for the same reason the\n * origins are: the set of things that talk to a surface is already in the graph,\n * and the domain they have in common is a fact about that set. Returned with the\n * leading dot a `Domain` attribute wants.\n *\n * Returns `undefined` when there is nothing to scope, which is the common case\n * and not a failure:\n *\n * - **One host.** Locally everything is `localhost` on different ports, and\n * cookies ignore the port — so a `Domain` would add nothing and `.localhost`\n * is not a domain a browser will accept.\n * - **Nothing in common.** Unrelated hosts cannot share a cookie at all, and\n * emitting the longest common suffix anyway would be a value that silently\n * fails to set.\n *\n * **The public-suffix limit, stated rather than discovered.** Two apps on\n * `a.vercel.app` and `b.vercel.app` share `.vercel.app`, which every browser\n * rejects because it is a registrable suffix rather than a registrable domain.\n * Resolving that correctly needs the Public Suffix List, which is a downloaded,\n * expiring dataset — so this requires at least two labels and otherwise trusts\n * the addresses, and the value stays overridable for the case it gets wrong.\n */\nexport function cookieDomain(urls: readonly string[]): string | undefined {\n\tconst hosts = new Set<string>();\n\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst { hostname } = new URL(url);\n\t\t\t// An IP address has no parent to share: `.0.0.1` is not a domain.\n\t\t\tif (/^\\d+(\\.\\d+){3}$/.test(hostname) || hostname.includes(':')) return;\n\t\t\thosts.add(hostname.toLowerCase());\n\t\t} catch {\n\t\t\t// Not an address. Nothing to derive from, and guessing is worse than\n\t\t\t// leaving the attribute off.\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (hosts.size === 0) return;\n\t// One host already shares its cookies with itself, whatever the port.\n\tif (hosts.size === 1) return;\n\n\tconst [first = [], ...rest] = [...hosts].map((host) =>\n\t\thost.split('.').reverse(),\n\t);\n\tconst shared: string[] = [];\n\n\tfor (const [index, label] of first.entries()) {\n\t\tif (!rest.every((labels) => labels[index] === label)) break;\n\t\tshared.push(label);\n\t}\n\n\t// One shared label is a TLD — `.com` is not a cookie domain.\n\tif (shared.length < 2) return;\n\n\treturn `.${shared.reverse().join('.')}`;\n}\n\n/**\n * The env key a construct's provided role actually becomes.\n *\n * Almost always `provideKey(id, role)` — and `secret` is the exception, because\n * a secret's *name* is its key: `Auth` signs with `AUTH_SECRET`, which is also\n * what better-auth's own tooling looks for, and qualifying it by role would\n * produce `AUTH_SECRET_VALUE`.\n *\n * It lives here rather than in each target because two targets deriving the\n * same key separately is exactly the drift the app/infra contract check exists\n * to catch — and a check deriving the key differently from the thing it checks\n * cannot catch anything.\n */\nexport function providedKeyFor(\n\tid: string,\n\tkind: DeclarationKind,\n\trole: string,\n): string {\n\treturn kind === 'secret' ? environmentCase(id) : provideKey(id, role);\n}\n","/**\n * Derived constructs — the ones that provision nothing of their own.\n *\n * A reader is an endpoint on an existing cluster; a schema tenant is a schema\n * inside an existing database. Both name their parent through `of`, and both\n * stay top-level entries so that `dependencies[].target` keeps resolving as\n * `m[target]` and every id remains a key in the map.\n *\n * The rules here are pure and manifest-only: they hold for any target adapter,\n * so an app is wrong before a deploy is attempted rather than during one.\n */\n\nimport type {\n\tConstructId,\n\tConstructManifest,\n\tDeclaration,\n\tDependency,\n\tDerivedDeclaration,\n\tSiteDeclaration,\n} from './declaration';\nimport { DERIVES_FROM, PUBLIC } from './declaration';\nimport { IllegalDerivation, UnknownParent } from './errors';\nimport { provideKey } from './naming';\n\n/** Whether a declaration names a parent. */\nexport function isDerived(\n\tdeclaration: Declaration,\n): declaration is DerivedDeclaration & { of: ConstructId } {\n\t// Both halves, because one kind is *optionally* derived: a cache declared\n\t// from a database names it, and a cache declared on its own names nothing.\n\t// Testing only the kind would make every standalone cache look like a\n\t// derivation with a missing parent.\n\treturn (\n\t\tdeclaration.kind in DERIVES_FROM &&\n\t\t'of' in declaration &&\n\t\ttypeof declaration.of === 'string'\n\t);\n}\n\n/**\n * Check every derived construct against its parent.\n *\n * Two rules: the parent exists, and its kind may vend this one. Together they\n * make cycles unreachable — a reader is terminal, so no chain of `of` can\n * return to where it started, and no walk is needed to prove it.\n */\nexport function assertDerivations(manifest: ConstructManifest): void {\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tif (!isDerived(declaration)) continue;\n\n\t\tconst parent = manifest[declaration.of];\n\t\tif (!parent) {\n\t\t\tthrow new UnknownParent(id, declaration.of, Object.keys(manifest));\n\t\t}\n\n\t\tconst allowed = DERIVES_FROM[declaration.kind];\n\t\tif (!allowed.includes(parent.kind)) {\n\t\t\tthrow new IllegalDerivation(id, declaration.kind, parent.kind, allowed);\n\t\t}\n\t}\n}\n\n/**\n * The order constructs must be provisioned in: every parent before its children.\n *\n * Resources are leaves and so come first in any order; only derived nodes\n * constrain the sequence, and they form a shallow forest rather than a general\n * graph. This walks each node's ancestors on demand instead of running a full\n * topological sort, which is the same result at this depth and reads as what it\n * is.\n *\n * Assumes {@link assertDerivations} has passed — a missing parent would\n * otherwise be a silent omission here rather than an error.\n */\nexport function provisionOrder(manifest: ConstructManifest): string[] {\n\tconst ordered: string[] = [];\n\tconst placed = new Set<string>();\n\n\tconst place = (id: string): void => {\n\t\tif (placed.has(id)) return;\n\t\tconst declaration = manifest[id];\n\t\tif (!declaration) return;\n\n\t\t// Mark before recursing: `assertDerivations` rules cycles out, and marking\n\t\t// first means a manifest that skipped that check terminates anyway.\n\t\tplaced.add(id);\n\t\tif (isDerived(declaration)) place(declaration.of);\n\t\tordered.push(id);\n\t};\n\n\tfor (const id of Object.keys(manifest)) place(id);\n\n\treturn ordered;\n}\n\n/**\n * Every edge a declaration carries, wherever the kind happens to keep them.\n *\n * Dependencies live in two places by design: on a node when the whole construct\n * is the consumer (a site), and on each nested handler when the construct is a\n * surface (a `rest-api`, whose routes each depend on their own things and\n * nothing more). Flattening that difference here is what lets every consumer of\n * the graph — reverse lookups, filtering, reference checks — ask one question.\n */\nexport function dependenciesOf(\n\tdeclaration: Declaration,\n): readonly Dependency[] {\n\tconst own =\n\t\t'dependencies' in declaration ? (declaration.dependencies ?? []) : [];\n\n\t// A surface's `calls` is a caller relationship rather than an injection, so\n\t// it is read here — reverse lookups want it — and is never a dependency\n\t// anything links from. See `RestApiDeclaration.calls`.\n\tconst calls = 'calls' in declaration ? (declaration.calls ?? []) : [];\n\n\tconst nested =\n\t\tdeclaration.kind === 'rest-api'\n\t\t\t? declaration.endpoints.flatMap((endpoint) => endpoint.dependencies)\n\t\t\t: [];\n\n\treturn [...own, ...calls, ...nested];\n}\n\n/**\n * The ids that depend on one construct — the graph read backwards.\n *\n * This is the whole mechanism behind CORS origins and trusted origins. Both are\n * lists of *callers*, and a caller is exactly an inbound edge, so neither is\n * ever written down: a surface that listed its own callers would have to be\n * edited every time something new called it, which is the hand-maintained list\n * this replaces.\n *\n * Sorted, because it feeds a comma-separated env value that would otherwise\n * change whenever the manifest's key order did — and a value that churns is a\n * container that redeploys for no reason.\n */\nexport function dependentsOf(\n\tmanifest: ConstructManifest,\n\tid: ConstructId,\n): string[] {\n\tconst callers: string[] = [];\n\n\tfor (const [callerId, declaration] of Object.entries(manifest)) {\n\t\tif (callerId === id) continue;\n\t\tif (dependenciesOf(declaration).some((edge) => edge.target === id)) {\n\t\t\tcallers.push(callerId);\n\t\t}\n\t}\n\n\treturn callers.sort();\n}\n\n/**\n * How each site variant names a value it ships to the browser.\n *\n * The prefix *is* the framework's contract — `VITE_`, `NEXT_PUBLIC_` and\n * `EXPO_PUBLIC_` all mean \"inline this into the bundle\" — so it is the one thing\n * a variant changes, and it changes nothing else.\n */\nexport const PUBLIC_PREFIX: Record<SiteDeclaration['variant'], string> = {\n\tstatic: 'VITE_',\n\ttanstack: 'VITE_',\n\tnext: 'NEXT_PUBLIC_',\n};\n\n/**\n * The keys a site's bundle needs, mapped to the key each value comes from —\n * `{ VITE_API_URL: 'API_URL' }`.\n *\n * A rename, not a second derivation: `API_URL` is resolved once, by whatever\n * resolved it for the server, and the site reads the same value under the name\n * its bundler will inline. That is what keeps a site and its API from coming to\n * disagree about where the API is.\n *\n * Filtered by `PUBLIC` rather than by what the site asked for. A site may\n * legitimately depend on anything — its server half, where it has one, reads env\n * exactly as a function does — so this is not a restriction on edges. It decides\n * one thing: which values may be prefixed into a bundle, which is what keeps\n * `ORDERS_URL` and its password out of a JavaScript file served to the public.\n *\n * Shared by every target for the same reason `providedKeyFor` is: a site built\n * locally and the same site built by a deploy must inline the same names.\n */\nexport function publicEnvFor(\n\tdeclaration: SiteDeclaration,\n\tmanifest: ConstructManifest,\n): Record<string, string> {\n\tconst prefix = PUBLIC_PREFIX[declaration.variant];\n\tconst keys: Record<string, string> = {};\n\n\tfor (const edge of declaration.dependencies) {\n\t\tconst target = manifest[edge.target];\n\t\tif (!target) continue;\n\n\t\tfor (const role of PUBLIC[target.kind] ?? []) {\n\t\t\tconst key = provideKey(edge.target, role as string);\n\t\t\tkeys[`${prefix}${key}`] = key;\n\t\t}\n\t}\n\n\treturn keys;\n}\n","/**\n * Deployment manifest types — the build output of `gkm build` that enumerates a\n * project's deployable units (routes, functions, crons, subscribers, queues)\n * with the metadata an infrastructure layer needs to provision them.\n *\n * `gkm build` writes a single TypeScript module per provider\n * (`<out>/manifest/aws.ts`) of the form:\n *\n * ```ts\n * export const manifest = { routes: [...], functions: [...], ... } as const;\n * export type Route = (typeof manifest.routes)[number];\n * // ...derived types\n * ```\n *\n * This is the dependency-free data contract shared between the producer\n * (`@geekmidas/cli`) and consumers (e.g. `@geekmidas/cloud/sst`'s `fromManifest`\n * integrators).\n *\n * The types below describe the **per-kind** manifest. The construct manifest\n * that replaces it — every construct keyed by id, with dependency edges — lives\n * in `./declaration`; both are exported while the migration runs.\n */\n\nexport type {\n\tAllProvidedKeys,\n\tAppSpec,\n\tCacheDeclaration,\n\tConstructId,\n\tConstructManifest,\n\tConstructName,\n\tCredentialDeclaration,\n\tCronDeclaration,\n\tDatabaseDeclaration,\n\tDatabaseReaderDeclaration,\n\tDatabaseSchemaDeclaration,\n\tDeclaration,\n\tDeclarationKind,\n\tDeclarationOf,\n\tDependency,\n\tDerivedDeclaration,\n\tDerivedKind,\n\tEmailDeclaration,\n\tFileServerDeclaration,\n\tFn,\n\tFunctionDeclaration,\n\tGlob,\n\tIdsOf,\n\tIdsOfKind,\n\tNode,\n\tObjectsDeclaration,\n\tOidcDeclaration,\n\tPostgresVersion,\n\tProvidedKeys,\n\tProvides,\n\tProvidesByKind,\n\tQueueDeclaration,\n\tRestApiDeclaration,\n\tRestApiEndpoint,\n\tSecretDeclaration,\n\tSiteDeclaration,\n\tTopicDeclaration,\n\tWorkerDeclaration,\n} from './declaration';\nexport {\n\tDEFAULT_POSTGRES_VERSION,\n\tDERIVES_FROM,\n\tPUBLIC,\n} from './declaration';\nexport {\n\tassertDerivations,\n\tdependenciesOf,\n\tdependentsOf,\n\tisDerived,\n\tPUBLIC_PREFIX,\n\tprovisionOrder,\n\tpublicEnvFor,\n} from './derive';\nexport {\n\tIllegalDerivation,\n\tInvalidConstructId,\n\tUnknownParent,\n} from './errors';\nexport {\n\tcacheTable,\n\tcanonicalId,\n\tcloudName,\n\tcookieDomain,\n\tenvironmentCase,\n\tkebabCase,\n\tprovidedKeyFor,\n\tprovideKey,\n\tscopedName,\n\tserviceKey,\n} from './naming';\n\n/**\n * A manifest field is either a flat list or, when the build is partitioned\n * (e.g. by authorizer), an object keyed by partition name. Readonly-tolerant so\n * the `as const` generated manifest assigns cleanly.\n */\nexport type ManifestField<T> =\n\t| readonly T[]\n\t| Readonly<Record<string, readonly T[]>>;\n\n/** Flatten a manifest field (array or partitioned) into a plain array. */\nexport function flattenManifestField<T>(\n\tfield: ManifestField<T> | undefined,\n): T[] {\n\tif (!field) return [];\n\treturn Array.isArray(field)\n\t\t? [...field]\n\t\t: Object.values(field as Record<string, readonly T[]>).flat();\n}\n\n/** A single HTTP route. */\nexport interface RouteInfo {\n\t/** Route path, e.g. `/users/{id}`. */\n\tpath: string;\n\t/** HTTP method, e.g. `GET`. */\n\tmethod: string;\n\t/** Bundled handler entrypoint. */\n\thandler: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\t/** Required environment variables (a trailing `?` marks an optional var). */\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n\t/** Authorizer name: `none`, `iam`, or a declared authorizer. */\n\tauthorizer: string;\n}\n\n/** A standalone Lambda function. */\nexport interface FunctionInfo {\n\tname: string;\n\thandler: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/** A scheduled (cron) function. */\nexport interface CronInfo {\n\tname: string;\n\thandler: string;\n\t/** Schedule expression, e.g. `rate(1 day)` or `cron(0 12 * * ? *)`. */\n\tschedule: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/** An event subscriber function (topic/queue resolved by `transport`). */\nexport interface SubscriberInfo {\n\tname: string;\n\thandler: string;\n\tsubscribedEvents: readonly string[];\n\t/** Delivery transport — `topic` (SNS fan-out) or `queue` (SQS). */\n\ttransport?: 'topic' | 'queue';\n\t/** The {@link TopicInfo.name} this subscriber binds to (via `s.topic(topic)`). */\n\ttopic?: string;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs this handler declared an edge to, by id.\n\t *\n\t * What `.dependsOn()` was given, carried through the build so the manifest\n\t * records the edge rather than only its shadow. `environment` is that shadow —\n\t * the keys the handler reads — and it cannot be turned back into edges, which\n\t * is why both exist and only this one grants anything.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/**\n * A pub/sub topic — fan-out. A *resource* (no handler): it declares the event\n * contract; producers publish via the derived publisher and {@link SubscriberInfo}s\n * bind to it. Infra provisions an SNS topic.\n */\nexport interface TopicInfo {\n\tname: string;\n\t/** The event type names this topic carries. */\n\tevents: readonly string[];\n\t/** Whether the topic is FIFO. */\n\tfifo?: boolean;\n}\n\n/** A queue worker — a queue and its single consumer. */\nexport interface QueueInfo {\n\tname: string;\n\thandler: string;\n\t/** SQS event-source batch size. */\n\tbatchSize?: number;\n\t/** Whether the queue is FIFO. */\n\tfifo?: boolean;\n\ttimeout?: number;\n\tmemorySize?: number;\n\tenvironment?: readonly string[];\n\t/**\n\t * The constructs the worker declared an edge to, by id.\n\t *\n\t * See {@link RouteInfo.dependencies} — same field, same reason.\n\t */\n\tdependencies?: readonly string[];\n}\n\n/**\n * The full deployment manifest — the shape of `export const manifest` in a\n * generated `manifest/<provider>.ts`. Each field is a {@link ManifestField}\n * (flat or partitioned).\n */\nexport interface Manifest {\n\troutes: ManifestField<RouteInfo>;\n\tfunctions?: ManifestField<FunctionInfo>;\n\tcrons?: ManifestField<CronInfo>;\n\tsubscribers?: ManifestField<SubscriberInfo>;\n\tqueues?: ManifestField<QueueInfo>;\n\ttopics?: ManifestField<TopicInfo>;\n}\n"],"x_google_ignoreList":[2],"mappings":"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"}
|