@fabrika/provider-zerops 0.9.0-dev.1 → 0.9.0-dev.3
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/package.json +15 -14
- package/src/execution.ts +45 -8
- package/types/src/api/client.d.ts +5 -0
- package/types/src/api/errors.d.ts +24 -0
- package/types/src/api/polling.d.ts +41 -0
- package/types/src/api/readers.d.ts +977 -0
- package/types/src/api/service-env-limit.d.ts +17 -0
- package/types/src/api/service-env-response.d.ts +23 -0
- package/types/src/api/types.d.ts +638 -0
- package/types/src/api.d.ts +6 -0
- package/types/src/authoring.d.ts +9 -0
- package/types/src/cli-args.d.ts +19 -0
- package/types/src/cli.d.ts +10 -0
- package/types/src/collaborators.d.ts +18 -0
- package/types/src/compile.d.ts +91 -0
- package/types/src/control.d.ts +41 -0
- package/types/src/database-budget.d.ts +38 -0
- package/types/src/descriptor.d.ts +28 -0
- package/types/src/execution.d.ts +137 -0
- package/types/src/exposure.d.ts +47 -0
- package/types/src/index.d.ts +31 -0
- package/types/src/installation/admin-options.d.ts +24 -0
- package/types/src/installation/admin.d.ts +35 -0
- package/types/src/installation/checker-release.d.ts +12 -0
- package/types/src/installation/deploy-options.d.ts +37 -0
- package/types/src/installation/deploy.d.ts +96 -0
- package/types/src/installation/generated/platform-console-schema.d.ts +2 -0
- package/types/src/installation/generated/platform-proxy-manifest.d.ts +2 -0
- package/types/src/installation/hosts.d.ts +38 -0
- package/types/src/installation/index.d.ts +9 -0
- package/types/src/installation/init-options.d.ts +38 -0
- package/types/src/installation/init.d.ts +60 -0
- package/types/src/installation/install-collaborators.d.ts +24 -0
- package/types/src/installation/install-environment.d.ts +70 -0
- package/types/src/installation/install-options.d.ts +49 -0
- package/types/src/installation/install-project.d.ts +13 -0
- package/types/src/installation/install-provisioning.d.ts +58 -0
- package/types/src/installation/install-secrets.d.ts +30 -0
- package/types/src/installation/install-token.d.ts +10 -0
- package/types/src/installation/install.d.ts +23 -0
- package/types/src/installation/installation-source.d.ts +8 -0
- package/types/src/installation/log.d.ts +44 -0
- package/types/src/installation/machine-key.d.ts +19 -0
- package/types/src/installation/mcp.d.ts +18 -0
- package/types/src/installation/placement-options.d.ts +11 -0
- package/types/src/installation/platform-archive.d.ts +7 -0
- package/types/src/installation/platform-source.d.ts +8 -0
- package/types/src/installation/platform-upload.d.ts +3 -0
- package/types/src/installation/proxy-manifest.d.ts +105 -0
- package/types/src/installation/secrets.d.ts +17 -0
- package/types/src/installation/sidecar.d.ts +51 -0
- package/types/src/installation/source-options.d.ts +1 -0
- package/types/src/installation/topology/artifacts.d.ts +8 -0
- package/types/src/installation/topology/index.d.ts +5 -0
- package/types/src/installation/topology/installation-schemas.d.ts +2242 -0
- package/types/src/installation/topology/invariants.d.ts +23 -0
- package/types/src/installation/topology/setups.d.ts +58 -0
- package/types/src/installation/topology/topology.d.ts +148 -0
- package/types/src/installation/topology/validate.d.ts +11 -0
- package/types/src/installation/upgrade-options.d.ts +26 -0
- package/types/src/installation/upgrade-output.d.ts +6 -0
- package/types/src/installation/upgrade.d.ts +88 -0
- package/types/src/managed-env.d.ts +57 -0
- package/types/src/manifest.d.ts +206 -0
- package/types/src/namespace/claims.d.ts +3 -0
- package/types/src/namespace/codec.d.ts +334 -0
- package/types/src/namespace/constants.d.ts +25 -0
- package/types/src/namespace/errors.d.ts +15 -0
- package/types/src/namespace/manifest.d.ts +4 -0
- package/types/src/namespace/operator.d.ts +12 -0
- package/types/src/namespace/provisioning.d.ts +4 -0
- package/types/src/namespace/proxy-attempt.d.ts +36 -0
- package/types/src/namespace/proxy-reads.d.ts +33 -0
- package/types/src/namespace/proxy-secrets.d.ts +8 -0
- package/types/src/namespace/proxy-source.d.ts +74 -0
- package/types/src/namespace/topology.d.ts +9 -0
- package/types/src/namespace/types.d.ts +99 -0
- package/types/src/namespace/update.d.ts +6 -0
- package/types/src/namespace/validation.d.ts +12 -0
- package/types/src/namespace.d.ts +9 -0
- package/types/src/plan.d.ts +12 -0
- package/types/src/provider.d.ts +65 -0
- package/types/src/proxy-manifest-carrier.d.ts +16 -0
- package/types/src/schema.generated.d.ts +376 -0
- package/types/src/service-names.d.ts +4 -0
- package/types/src/service-references.d.ts +13 -0
- package/types/src/source/constants.d.ts +6 -0
- package/types/src/source/port.d.ts +60 -0
- package/types/src/source/types.d.ts +4 -0
- package/types/src/source/validation.d.ts +19 -0
- package/types/src/source.d.ts +2 -0
- package/types/src/types.d.ts +121 -0
- package/types/src/version-attempt.d.ts +8 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ZeropsImportDocument } from '../../index';
|
|
2
|
+
export declare const assertZeropsHostnames: (document: ZeropsImportDocument) => void;
|
|
3
|
+
/**
|
|
4
|
+
* ADR-0022: **only the proxy is publicly routed.** App services, the IAM service, the control plane and
|
|
5
|
+
* the databases stay internal and are reached over the project's private network.
|
|
6
|
+
*
|
|
7
|
+
* Zerops makes this the default — a service is not publicly accessible until you opt in — so the failure
|
|
8
|
+
* this guards against is not "we forgot to lock something down" but "someone added
|
|
9
|
+
* `enableSubdomainAccess: true` to debug a service and it shipped". That is a one-word diff and it is
|
|
10
|
+
* exactly the kind of thing review misses.
|
|
11
|
+
*
|
|
12
|
+
* `publicService` may be absent, which asserts that NOTHING in the document is publicly routed — the
|
|
13
|
+
* right assertion for a document whose public entry point lives in another import.
|
|
14
|
+
*/
|
|
15
|
+
export declare const assertOnlyPublicService: (document: ZeropsImportDocument, publicService?: string) => void;
|
|
16
|
+
/**
|
|
17
|
+
* `corePackage` is per-project, upgrade-only, and its upgrade is partially destructive (logs and
|
|
18
|
+
* statistics are lost) — so it is the one field in this document that a later `PUT` cannot fix
|
|
19
|
+
* (ADR-0006). Require it to be stated rather than inherited from the platform default (`LIGHT`).
|
|
20
|
+
*/
|
|
21
|
+
export declare const assertCorePackageIsExplicit: (document: ZeropsImportDocument) => void;
|
|
22
|
+
/** All three, for a document that creates its own project. */
|
|
23
|
+
export declare const assertTopologyInvariants: (document: ZeropsImportDocument, publicService?: string) => void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ZeropsYamlSpec } from '../../index';
|
|
2
|
+
/**
|
|
3
|
+
* The auth enforcement proxy — Caddy for HTTP correctness, a compiled Bun auth service for every
|
|
4
|
+
* authorization decision (ADR-0022: the endpoint table is NEVER compiled into Caddy routes).
|
|
5
|
+
*
|
|
6
|
+
* This is the only setup deployed into BOTH projects, and the only publicly routed service in either.
|
|
7
|
+
*
|
|
8
|
+
* Per-service variables (env API): `FABRIKA_IAM_ISSUER` — `http://iam:3000` in the platform project, the
|
|
9
|
+
* IAM service's PUBLIC origin in an apps project, because there is no private network between projects
|
|
10
|
+
* (ADR-0006). The manifest is not a variable; see below.
|
|
11
|
+
*
|
|
12
|
+
* Secret (`envSecrets`): `FABRIKA_IAM_KEY` — the value IAM knows as `FABRIKA_IAM_PROXY_KEY`.
|
|
13
|
+
*
|
|
14
|
+
* ── How the manifest reaches the build ───────────────────────────────────────────────────────────
|
|
15
|
+
*
|
|
16
|
+
* `proxy.manifest.json` tells the proxy which apps it fronts, at which upstream, under which endpoint table. It
|
|
17
|
+
* is baked into the artifact at BUILD time, which is what `docs/backlog/08` chose ("redeploy") over
|
|
18
|
+
* pushing to Caddy's admin API. It arrives as the one generated data file of the uploaded build archive
|
|
19
|
+
* (ADR-0045), beside the exact public commit, at a path the commit does not hold: Control streams it into a
|
|
20
|
+
* namespace proxy's archive (`republishProxy`, `packages/provider-zerops/src/namespace/proxy-attempt.ts`), and
|
|
21
|
+
* `platform install` / `platform deploy` append it to the platform proxy's (`installation/platform-archive.ts`).
|
|
22
|
+
* It never travels through the service environment, whose values Zerops caps at ~32 KB.
|
|
23
|
+
*
|
|
24
|
+
* Releases before this one lifted `FABRIKA_PROXY_MANIFEST_JSON` from the env API into the build instead.
|
|
25
|
+
* A namespace pinned to such a release keeps that descriptor, and Control keeps writing the variable for it
|
|
26
|
+
* (`zeropsProxyManifestCarrier`): never add the lift back, or a pin of this release would get the variable.
|
|
27
|
+
*
|
|
28
|
+
* What IS structural: a missing or malformed file makes `generate-config.ts` exit non-zero, so the
|
|
29
|
+
* pipeline fails and the previous version keeps serving. A valid empty app list generates only the
|
|
30
|
+
* terminal 404 route, and the auth service denies every forwarded request.
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* The proxy's public listeners.
|
|
34
|
+
*
|
|
35
|
+
* Routing is by HOST — one app owns one hostname, and `assertUniqueHosts` refuses to let two apps share
|
|
36
|
+
* one so that Caddy's route order can never decide which app answers. A production installation gets
|
|
37
|
+
* those hostnames from custom domains bound to the project's balancer, and needs exactly ONE listener:
|
|
38
|
+
* every domain arrives on the same port and the Host header decides.
|
|
39
|
+
*
|
|
40
|
+
* A `zerops-subdomain` installation has no such source of names. Zerops mints one generated hostname per
|
|
41
|
+
* HTTP PORT, so on that path a port IS a hostname — and the number of listeners is the number of
|
|
42
|
+
* distinct public hosts the installation can ever serve. Three are the platform's own (IAM's JWKS and
|
|
43
|
+
* OIDC redirect, the control dashboard, Operations ingest); the rest are a fixed pool of APPLICATION
|
|
44
|
+
* slots, and running out of them is what caps a light-tier installation rather than any resource limit.
|
|
45
|
+
*
|
|
46
|
+
* That ceiling is the honest cost of the subdomain path and the reason it is not the production one.
|
|
47
|
+
* A custom-domain installation ignores all of this: with `enableSubdomainAccess: false` nothing here is
|
|
48
|
+
* published, the extra listeners answer the same host-matched routes, and an unknown Host still falls
|
|
49
|
+
* through to the terminal 404. One setup serves both tiers rather than a second that must be kept in
|
|
50
|
+
* step with this one.
|
|
51
|
+
*
|
|
52
|
+
* 8081 is deliberately absent: it is the health listener, which is never published.
|
|
53
|
+
*/
|
|
54
|
+
export declare const PROXY_PUBLIC_PORTS: number[];
|
|
55
|
+
/** Liveness only, on its own unpublished listener. */
|
|
56
|
+
export declare const PROXY_HEALTH_PORT = 8081;
|
|
57
|
+
/** The repository-root `zerops.yaml`, in the order the setups appear in it. */
|
|
58
|
+
export declare const fabrikaZeropsYaml: ZeropsYamlSpec;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type ZeropsImportDocument, type ZeropsNamespacePostgres, type ZeropsSourceTarget } from '../../index';
|
|
2
|
+
/**
|
|
3
|
+
* How a project's single public entry point is published.
|
|
4
|
+
*
|
|
5
|
+
* `enableSubdomainAccess` is documented as "not suitable for production", so production takes
|
|
6
|
+
* `custom-domain`: nothing in the import is publicly routed, and the domain is bound to the project's L7
|
|
7
|
+
* balancer out of band — the import format has NO field for a custom domain, so that step is manual by
|
|
8
|
+
* construction and not an oversight here. `zerops-subdomain` is the ONLY thing that ever writes
|
|
9
|
+
* `enableSubdomainAccess: true` — on the proxy, and on nothing else.
|
|
10
|
+
*
|
|
11
|
+
* **NEITHER VALUE IS DELIVERED BY THE IMPORT.** Live-verified: the platform accepts
|
|
12
|
+
* `enableSubdomainAccess` on a service the document CREATES and then silently drops it, so the service
|
|
13
|
+
* reads back `subdomainAccess: false` and stays there. The subdomain is established afterwards, by
|
|
14
|
+
* `PUT /service-stack/{id}/enable-subdomain-access` on a service that already publishes an HTTP port —
|
|
15
|
+
* which the namespace lifecycle does for itself (`ensureSubdomainAccess` in `src/namespace/provisioning.ts`)
|
|
16
|
+
* and which an operator applying the generated platform artifacts must do by hand; the artifact's header
|
|
17
|
+
* names the call. So `true` here records the INTENT and feeds ADR-0022's `assertOnlyPublicService`; it
|
|
18
|
+
* does not turn anything on.
|
|
19
|
+
*/
|
|
20
|
+
export type PublicAccess = 'custom-domain' | 'zerops-subdomain';
|
|
21
|
+
/**
|
|
22
|
+
* How much platform an installation pays for.
|
|
23
|
+
*
|
|
24
|
+
* `standard` is the production shape: HA Postgres, a separate database and bucket for Operations, and
|
|
25
|
+
* enough containers that no single one is a point of failure.
|
|
26
|
+
*
|
|
27
|
+
* `light` is one project, one `postgresql:single@18` and one bucket shared by IAM, Operations, control
|
|
28
|
+
* AND the apps deployed alongside them, at one container per service. This tier exists because the standard
|
|
29
|
+
* shape costs ~13 containers before a single application is deployed, which is more platform than a
|
|
30
|
+
* small fleet — or an evaluation — can justify.
|
|
31
|
+
*
|
|
32
|
+
* Sharing is safe rather than merely cheap, and that is a property of the code, not of this comment:
|
|
33
|
+
*
|
|
34
|
+
* • The three services' table names do not intersect (IAM 10, Operations 24, control 16), and
|
|
35
|
+
* ADR-0017 already gives each its own migration ledger and advisory lock, so one database holds
|
|
36
|
+
* all three without coordination.
|
|
37
|
+
* • Their blob keys are prefix-disjoint — control writes `runs/`, Operations writes `events/`,
|
|
38
|
+
* `dead/` and `source-maps/` — so one bucket cannot collide.
|
|
39
|
+
*
|
|
40
|
+
* What `light` genuinely gives up is FAILURE-DOMAIN isolation: Operations' high-volume error history
|
|
41
|
+
* now shares capacity with the identity path, and losing the one database loses all three services.
|
|
42
|
+
* That is the trade, and it is why `standard` remains the default rather than the special case.
|
|
43
|
+
*/
|
|
44
|
+
export type PlatformTier = 'standard' | 'light';
|
|
45
|
+
export interface TopologyOptions {
|
|
46
|
+
/** Environment label handed to `services(ctx)`. Part of the project name, so it lands in the GUI too. */
|
|
47
|
+
env: string;
|
|
48
|
+
/** How the proxy is published. Production is `custom-domain`. */
|
|
49
|
+
publicAccess?: PublicAccess;
|
|
50
|
+
/** How much platform to provision. Defaults to `standard`. */
|
|
51
|
+
tier?: PlatformTier;
|
|
52
|
+
}
|
|
53
|
+
/** One project's topology plus the facts the invariant checks need. */
|
|
54
|
+
export interface ProjectTopology {
|
|
55
|
+
/** Stem of the generated filenames, and how this topology is referred to in prose. */
|
|
56
|
+
id: string;
|
|
57
|
+
/** The source declaration compiled into the generated topology artifacts. */
|
|
58
|
+
target: ZeropsSourceTarget;
|
|
59
|
+
/**
|
|
60
|
+
* The SAME services with no `project` block, for the project `platform install` created or was handed.
|
|
61
|
+
*
|
|
62
|
+
* A document carrying `project:` is only valid at `POST /client/{clientId}/project/import`, which
|
|
63
|
+
* CREATES a project — and Zerops permits duplicate project names, so applying one at an existing
|
|
64
|
+
* installation risks a second project rather than failing. Present on both platform tiers.
|
|
65
|
+
*/
|
|
66
|
+
servicesTarget?: ZeropsSourceTarget;
|
|
67
|
+
/** The one service allowed to be publicly routed (ADR-0022). Always the proxy. */
|
|
68
|
+
publicService: string;
|
|
69
|
+
/** Present on app namespaces so fixtures can prove the selected isolation tier. */
|
|
70
|
+
namespacePreset?: 'cheap' | 'mid' | 'full';
|
|
71
|
+
/** Present only when this namespace is reserved for one app. */
|
|
72
|
+
exclusiveAppId?: string;
|
|
73
|
+
}
|
|
74
|
+
/** The proxy's hostname, in every project. Also the `zerops.yaml` setup name it builds from. */
|
|
75
|
+
export declare const PROXY_HOSTNAME = "proxy";
|
|
76
|
+
/**
|
|
77
|
+
* The **platform** project: fabrika itself.
|
|
78
|
+
*
|
|
79
|
+
* `SERIOUS` is not a comfort choice. This project holds the thing that repairs the other one, so its
|
|
80
|
+
* availability tier is the recovery story; and because `corePackage` cannot be downgraded, starting
|
|
81
|
+
* LIGHT and "upgrading when it matters" costs a partially destructive migration at the worst moment.
|
|
82
|
+
*/
|
|
83
|
+
export declare const platformTopology: (options: TopologyOptions) => ProjectTopology;
|
|
84
|
+
/**
|
|
85
|
+
* An application namespace: one proxy plus the namespace-owned resources selected by its preset.
|
|
86
|
+
*
|
|
87
|
+
* This is only an adapter over the provider-owned namespace compiler. The control plane uses that same
|
|
88
|
+
* compiler for live create/adopt/reconcile operations, so generated bring-up artifacts cannot drift
|
|
89
|
+
* into a second definition of what an application namespace contains.
|
|
90
|
+
*
|
|
91
|
+
* `mid` stays the default for the committed apps-prod artifact: each app imports its own prefixed
|
|
92
|
+
* database. `cheap` adds namespace-owned Postgres. `full` reserves the project for one app, while the
|
|
93
|
+
* app's own import still owns its runtime services and database.
|
|
94
|
+
*/
|
|
95
|
+
export interface AppsTopologyOptions extends TopologyOptions {
|
|
96
|
+
readonly corePackage: 'LIGHT' | 'SERIOUS';
|
|
97
|
+
readonly preset?: 'cheap' | 'mid' | 'full';
|
|
98
|
+
readonly projectName?: string;
|
|
99
|
+
readonly exclusiveAppId?: string;
|
|
100
|
+
readonly postgres?: ZeropsNamespacePostgres;
|
|
101
|
+
}
|
|
102
|
+
export declare const appsTopology: (options: AppsTopologyOptions) => ProjectTopology;
|
|
103
|
+
/** The topologies this repo commits generated documents for. */
|
|
104
|
+
export declare const fabrikaTopologies: () => ProjectTopology[];
|
|
105
|
+
/** One compiled form: the document, and the YAML text an operator applies. */
|
|
106
|
+
export interface CompiledDocument {
|
|
107
|
+
document: ZeropsImportDocument;
|
|
108
|
+
yaml: string;
|
|
109
|
+
}
|
|
110
|
+
/** A compiled topology in every form an operator needs. */
|
|
111
|
+
export interface CompiledTopology {
|
|
112
|
+
topology: ProjectTopology;
|
|
113
|
+
/**
|
|
114
|
+
* First bring-up ONLY: every service `startWithoutCode: true`, so secrets can be written before any
|
|
115
|
+
* deploy. Applying this a second time at a project whose services already carry code activates a new
|
|
116
|
+
* EMPTY app version on each of them — verified live. It is not a reconcile document.
|
|
117
|
+
*/
|
|
118
|
+
provision: CompiledDocument;
|
|
119
|
+
/**
|
|
120
|
+
* Steady state: the same document, re-appliable because every service carries `override: true`.
|
|
121
|
+
*
|
|
122
|
+
* "Re-appliable" is the whole claim, and deliberately not "reconciling". Live-verified: applying
|
|
123
|
+
* this at an existing project creates whatever is missing and leaves everything that exists exactly
|
|
124
|
+
* as it is — a changed `profile`, `minContainers` or `objectStorageSize` in here is accepted by the
|
|
125
|
+
* API and silently ignored. Changing a live service is a separate, field-specific API call.
|
|
126
|
+
*/
|
|
127
|
+
steady: CompiledDocument;
|
|
128
|
+
/**
|
|
129
|
+
* The two forms above with no `project:` block, present only when the topology declares a
|
|
130
|
+
* `servicesTarget`. These are what `POST /project/{projectId}/service-stack/import` takes, so they
|
|
131
|
+
* are the ones a bootstrap applies to a project the operator created.
|
|
132
|
+
*
|
|
133
|
+
* Nothing is lost by dropping the block: `envIsolation` is settable at project CREATION only, so a
|
|
134
|
+
* `project:` here could not correct an existing project even if the endpoint tolerated it, and the
|
|
135
|
+
* per-service `envIsolation: service` the compiler writes overrides the project's value anyway
|
|
136
|
+
* (ADR-0004).
|
|
137
|
+
*/
|
|
138
|
+
servicesProvision?: CompiledDocument;
|
|
139
|
+
servicesSteady?: CompiledDocument;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Compile one topology to both documents, asserting every invariant on each.
|
|
143
|
+
*
|
|
144
|
+
* The provisioning form exists because of the cost ADR-0004 accepted out loud: on Zerops no secret can
|
|
145
|
+
* be set before the service exists, since the env API is addressed BY SERVICE. So bring-up is
|
|
146
|
+
* import-without-code → write secrets → deploy, and `compileProvisioningYaml` is the first of those three.
|
|
147
|
+
*/
|
|
148
|
+
export declare const compileTopology: (topology: ProjectTopology, env: string) => CompiledTopology;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Artifact } from './artifacts';
|
|
2
|
+
export type SchemaKind = 'import' | 'zerops-yaml';
|
|
3
|
+
export interface SchemaViolation {
|
|
4
|
+
path: string;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const parseYaml: (text: string) => unknown;
|
|
8
|
+
export declare const validateDocument: (kind: SchemaKind, document: unknown) => SchemaViolation[];
|
|
9
|
+
export declare const validateYaml: (kind: SchemaKind, text: string) => SchemaViolation[];
|
|
10
|
+
export declare const schemaKindFor: (path: string) => SchemaKind;
|
|
11
|
+
export declare const assertArtifactMatchesSchema: (artifact: Artifact) => void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Where the sidecar repository this command edits is found. */
|
|
2
|
+
export type UpgradeSidecar =
|
|
3
|
+
/** An existing local checkout — the one `platform init` left behind, or any other clone. */
|
|
4
|
+
{
|
|
5
|
+
readonly kind: 'checkout';
|
|
6
|
+
readonly dir: string;
|
|
7
|
+
}
|
|
8
|
+
/** `<owner>/<name>`, cloned into a temporary directory for the length of the run. */
|
|
9
|
+
| {
|
|
10
|
+
readonly kind: 'repo';
|
|
11
|
+
readonly repo: string;
|
|
12
|
+
};
|
|
13
|
+
/** Every input `runUpgrade` takes from the operator. */
|
|
14
|
+
export interface PlatformUpgradeInput {
|
|
15
|
+
/** The published fabrika tag to roll onto, already checked to be one. */
|
|
16
|
+
readonly to: string;
|
|
17
|
+
readonly sidecar: UpgradeSidecar;
|
|
18
|
+
/** The operator's name for this installation, when they gave one. Only ever used in the commit subject. */
|
|
19
|
+
readonly installation?: string;
|
|
20
|
+
/** Read everything, write nothing, push nothing. */
|
|
21
|
+
readonly dryRun: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** The one value-less flag. */
|
|
24
|
+
export declare const UPGRADE_DRY_RUN_FLAG = "--dry-run";
|
|
25
|
+
/** Parse the command's arguments into the one input `runUpgrade` takes. */
|
|
26
|
+
export declare const parsePlatformUpgradeArgs: (argv: readonly string[]) => PlatformUpgradeInput;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type Sleeper } from '../index';
|
|
2
|
+
import { type DeployLog } from './log';
|
|
3
|
+
import type { PlatformUpgradeInput } from './upgrade-options';
|
|
4
|
+
/** The public repository whose tags an installation may be pinned to. */
|
|
5
|
+
export declare const FABRIKA_REPOSITORY = "contember/fabrika-platform";
|
|
6
|
+
/** The workflow `platform init` generates, and the only one a roll may be watching. */
|
|
7
|
+
export declare const SIDECAR_WORKFLOW_FILE = "platform.yml";
|
|
8
|
+
/** The branch the generated workflow triggers on (`push: branches: [main]`). */
|
|
9
|
+
export declare const SIDECAR_BRANCH = "main";
|
|
10
|
+
/**
|
|
11
|
+
* What the public repository answered about a tag.
|
|
12
|
+
*
|
|
13
|
+
* THREE answers, not two. `gh` exits non-zero for a rate limit, an expired token and an unreachable
|
|
14
|
+
* network exactly as it would for a repository that does not exist, and reporting any of those as
|
|
15
|
+
* `missing` would send an operator to check a tag that is in fact already published.
|
|
16
|
+
*/
|
|
17
|
+
export type TagLookup = {
|
|
18
|
+
readonly state: 'published';
|
|
19
|
+
} | {
|
|
20
|
+
readonly state: 'missing';
|
|
21
|
+
} | {
|
|
22
|
+
readonly state: 'unavailable';
|
|
23
|
+
readonly reason: string;
|
|
24
|
+
};
|
|
25
|
+
/** One workflow run, as `gh run list` describes it. */
|
|
26
|
+
export interface UpgradeRun {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly url: string;
|
|
29
|
+
/** `queued`, `in_progress`, `completed` — reported so the operator knows why nothing moves yet. */
|
|
30
|
+
readonly status: string;
|
|
31
|
+
}
|
|
32
|
+
/** Where the sidecar's branch stands relative to what the pipeline actually watches. */
|
|
33
|
+
export interface SidecarBranch {
|
|
34
|
+
/** The checked-out branch, or `HEAD` when detached. */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/** Commits the upstream does not have; `undefined` when the branch tracks nothing. */
|
|
37
|
+
readonly ahead: number | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** Everything `runUpgrade` does outside its own process. Injected so the flow can be driven without git or gh. */
|
|
40
|
+
export interface UpgradeEffects {
|
|
41
|
+
/** Is `gh` installed AND logged in? Every other effect here needs both, so it is asked once, first. */
|
|
42
|
+
hasGh(): Promise<boolean>;
|
|
43
|
+
/** Does the public repository carry this tag? The one thing a local check cannot answer. */
|
|
44
|
+
verifyTag(tag: string): Promise<TagLookup>;
|
|
45
|
+
/** Clone `<owner>/<name>` into a fresh directory and return it. */
|
|
46
|
+
cloneSidecar(repo: string): Promise<string>;
|
|
47
|
+
/** The `<owner>/<name>` this checkout pushes to — also the repository the run is looked for in. */
|
|
48
|
+
describeCheckout(dir: string): Promise<string>;
|
|
49
|
+
/** Does the checkout carry uncommitted changes to TRACKED files? Untracked ones are not staged here. */
|
|
50
|
+
isDirty(dir: string): Promise<boolean>;
|
|
51
|
+
/** Which branch the checkout is on, and how far ahead of its upstream. */
|
|
52
|
+
readBranch(dir: string): Promise<SidecarBranch>;
|
|
53
|
+
/** Stage `files`, commit them with `message`, and return the resulting commit SHA. */
|
|
54
|
+
commit(input: {
|
|
55
|
+
readonly dir: string;
|
|
56
|
+
readonly files: readonly string[];
|
|
57
|
+
readonly message: string;
|
|
58
|
+
}): Promise<string>;
|
|
59
|
+
push(dir: string): Promise<void>;
|
|
60
|
+
/** The run GitHub registered for `sha`, or undefined while it has not appeared yet. */
|
|
61
|
+
findRun(input: {
|
|
62
|
+
readonly repo: string;
|
|
63
|
+
readonly sha: string;
|
|
64
|
+
}): Promise<UpgradeRun | undefined>;
|
|
65
|
+
/** Follow a run to its conclusion. Throws when it ends in anything but success. */
|
|
66
|
+
watchRun(input: {
|
|
67
|
+
readonly repo: string;
|
|
68
|
+
readonly runId: string;
|
|
69
|
+
}): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
export interface UpgradeCollaborators {
|
|
72
|
+
readonly log: DeployLog;
|
|
73
|
+
readonly effects: UpgradeEffects;
|
|
74
|
+
readonly sleep: Sleeper;
|
|
75
|
+
readonly signal: AbortSignal;
|
|
76
|
+
}
|
|
77
|
+
/** The fixed commit subject. Fixed so `git log` in a sidecar reads as the installation's release history. */
|
|
78
|
+
export declare const upgradeCommitMessage: (installation: string, tag: string) => string;
|
|
79
|
+
/**
|
|
80
|
+
* Roll one installation's sidecar onto a published fabrika tag and follow the deploy it triggers.
|
|
81
|
+
*
|
|
82
|
+
* Nothing is written until every refusal has been passed, so a run that stops early leaves the sidecar
|
|
83
|
+
* exactly as it was — and once the push has landed the roll is under way whether or not this process
|
|
84
|
+
* survives, which is why the run URL is printed before anything is watched.
|
|
85
|
+
*/
|
|
86
|
+
export declare const runUpgrade: (input: PlatformUpgradeInput, collaborators: UpgradeCollaborators) => Promise<void>;
|
|
87
|
+
/** The real `git` + `gh`, through the one shell-out module that keeps argv verbatim and errors short. */
|
|
88
|
+
export declare const consoleUpgradeCollaborators: () => UpgradeCollaborators;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type FrameworkVariableName } from '@fabrika/auth-core';
|
|
2
|
+
import { type PreparedZeropsDescriptor } from './descriptor';
|
|
3
|
+
/** The framework-only names Control hands every Zerops deploy; the rest of the list is the provider's own. */
|
|
4
|
+
export type ManagedKey = Extract<FrameworkVariableName, 'FABRIKA_RELEASE' | 'FABRIKA_OPERATIONS_DSN' | 'FABRIKA_IAM_ISSUER' | 'FABRIKA_IAM_APP_ID' | 'FABRIKA_APP_ID' | 'FABRIKA_ENVIRONMENT' | 'FABRIKA_SERVICE_KEY' | 'FABRIKA_PROXY_SECRET' | 'FABRIKA_IAM_RPC_URL' | 'FABRIKA_IAM_RPC_KEY' | 'FABRIKA_APP_ORIGIN' | 'FABRIKA_TOKEN_KEYS'>;
|
|
5
|
+
export declare const MANAGED_KEYS: readonly ManagedKey[];
|
|
6
|
+
/** The managed keys written as service variables; `FABRIKA_RELEASE` travels only in the execution descriptor (ADR-0044). */
|
|
7
|
+
export declare const SERVICE_MANAGED_KEYS: readonly Exclude<ManagedKey, 'FABRIKA_RELEASE'>[];
|
|
8
|
+
/** The managed keys that carry a credential, written sensitive and therefore never compared. */
|
|
9
|
+
export declare const SENSITIVE_MANAGED_KEYS: ReadonlySet<ManagedKey>;
|
|
10
|
+
/**
|
|
11
|
+
* A workload, connect or platform transport key and every mail transport variable are written sensitive; a connect or
|
|
12
|
+
* platform transport URL is an origin.
|
|
13
|
+
*/
|
|
14
|
+
export declare const isSensitiveFamilyVariable: (name: string) => boolean;
|
|
15
|
+
export type ManagedValues = Record<ManagedKey, string | null>;
|
|
16
|
+
export declare function parseManagedValues(value: unknown): ManagedValues;
|
|
17
|
+
/**
|
|
18
|
+
* What Control hands a deploy: the twelve managed keys, the key of each job and webhook of the approved contract, the
|
|
19
|
+
* key and owner origin of each connector import, and the installation's mail transport when a job sends through it.
|
|
20
|
+
*/
|
|
21
|
+
export interface ManagedEnvironment {
|
|
22
|
+
readonly values: ManagedValues;
|
|
23
|
+
/**
|
|
24
|
+
* `FABRIKA_<KIND>_<NAME>_KEY` → the workload's `px_` key, `FABRIKA_CONNECT_<IMPORT>_KEY` / `_URL`, each
|
|
25
|
+
* `FABRIKA_EMAIL_*` of the installation's mail transport, and `FABRIKA_PLATFORM_<RECEIVER>_URL` / `_KEY`.
|
|
26
|
+
*/
|
|
27
|
+
readonly familyVariables: Readonly<Record<string, string>>;
|
|
28
|
+
}
|
|
29
|
+
export declare function parseManagedEnvironment(value: Readonly<Record<string, string | null>>): ManagedEnvironment;
|
|
30
|
+
/**
|
|
31
|
+
* A service variable only the platform writes per workload, import, platform receiver or the installation's mail
|
|
32
|
+
* transport: a stale one is removed when the deploy no longer hands it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isFrameworkFamilyVariable(name: string): boolean;
|
|
35
|
+
/** Refuse every framework-only name (ADR-0043), not only the ones a deploy writes today. */
|
|
36
|
+
export declare function assertAuthoredManagedName(name: string): void;
|
|
37
|
+
type AuthoredDocumentValue = string | number | boolean | null | readonly AuthoredDocumentValue[] | {
|
|
38
|
+
readonly [key: string]: AuthoredDocumentValue;
|
|
39
|
+
};
|
|
40
|
+
/** Refuse a value that references a framework-only variable (`${RUNTIME_FABRIKA_PROXY_SECRET}`), naming only the reference. */
|
|
41
|
+
export declare function assertNoFrameworkReference(text: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Refuse, in any `envVariables`/`envSecrets` mapping at any depth, a managed name as a key and a reference to one in a
|
|
44
|
+
* key or a value: Zerops resolves the reference into a variable the application controls, and lifts it into a build.
|
|
45
|
+
*/
|
|
46
|
+
export declare function assertAuthoredManagedDocument(value: AuthoredDocumentValue): void;
|
|
47
|
+
export declare function assertAuthoredManagedInputs(input: {
|
|
48
|
+
variableNames: readonly string[];
|
|
49
|
+
secretNames: readonly string[];
|
|
50
|
+
}): void;
|
|
51
|
+
/**
|
|
52
|
+
* Render the execution descriptor: the source descriptor with `FABRIKA_RELEASE` written as a literal into
|
|
53
|
+
* the selected setup's `run.envVariables`, so the release travels with the version (ADR-0044). A null
|
|
54
|
+
* release omits the key. The source descriptor's bytes and digest are untouched.
|
|
55
|
+
*/
|
|
56
|
+
export declare function overlayRelease(contents: string, setup: string | undefined, release: string | null): PreparedZeropsDescriptor;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { type AppSchema } from '@fabrika/auth-core';
|
|
2
|
+
import type { JsonValue, ProviderCodec, ProviderDeployInput, ProviderEnvironment } from '@fabrika/provider-contract';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { type ZeropsContractRun, type ZeropsDevExecution, type ZeropsLockedExecution, type ZeropsRuntimePackage } from './execution';
|
|
5
|
+
import type { ZeropsAppConfig, ZeropsNamespaceResourceRequirement, ZeropsProxySpec } from './types';
|
|
6
|
+
export declare const FABRIKA_MANIFEST_VERSION = 3;
|
|
7
|
+
export declare const ZEROPS_SOURCE_DESCRIPTOR_MAX_BYTES: number;
|
|
8
|
+
export declare const ZEROPS_SERVICE_HOSTNAME_PATTERN: RegExp;
|
|
9
|
+
export interface FabrikaImportDocument {
|
|
10
|
+
readonly project?: {
|
|
11
|
+
readonly [key: string]: JsonValue;
|
|
12
|
+
};
|
|
13
|
+
readonly services: ReadonlyArray<{
|
|
14
|
+
readonly [key: string]: JsonValue;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export interface ZeropsArtifactSourceDescriptor {
|
|
18
|
+
readonly path: 'zerops.yaml';
|
|
19
|
+
readonly contents: string;
|
|
20
|
+
readonly sha256: string;
|
|
21
|
+
}
|
|
22
|
+
export interface FabrikaManifest {
|
|
23
|
+
manifestVersion: typeof FABRIKA_MANIFEST_VERSION;
|
|
24
|
+
app: {
|
|
25
|
+
id: string;
|
|
26
|
+
env: string;
|
|
27
|
+
schema?: AppSchema;
|
|
28
|
+
pipeline: {
|
|
29
|
+
secrets: string[];
|
|
30
|
+
vars: string[];
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
target: {
|
|
34
|
+
platform: 'zerops';
|
|
35
|
+
/** The exact repository-root build descriptor used for this artifact. */
|
|
36
|
+
sourceDescriptor: ZeropsArtifactSourceDescriptor;
|
|
37
|
+
/** The canonical document used both for resource claims and the Zerops API payload. */
|
|
38
|
+
importDocument: FabrikaManifestImportDocument;
|
|
39
|
+
deployService: string;
|
|
40
|
+
zeropsSetup?: string;
|
|
41
|
+
proxy?: ZeropsProxySpec;
|
|
42
|
+
namespaceResources?: ZeropsNamespaceResourceRequirement[];
|
|
43
|
+
/** Present for a contract application, whose run section and server build the platform generates. */
|
|
44
|
+
contract?: ZeropsContractRun;
|
|
45
|
+
runtimePackages?: ZeropsRuntimePackage[];
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export interface ManifestExpectation {
|
|
49
|
+
appId?: string;
|
|
50
|
+
env?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare const assertFabrikaManifestCoordinates: (app: Pick<FabrikaManifest["app"], "id" | "env">, expected: ManifestExpectation) => void;
|
|
53
|
+
export declare const zeropsArtifactSourceDescriptorSchema: z.ZodObject<{
|
|
54
|
+
path: z.ZodLiteral<"zerops.yaml">;
|
|
55
|
+
contents: z.ZodEffects<z.ZodString, string, string>;
|
|
56
|
+
sha256: z.ZodString;
|
|
57
|
+
}, "strict", z.ZodTypeAny, {
|
|
58
|
+
sha256: string;
|
|
59
|
+
path: "zerops.yaml";
|
|
60
|
+
contents: string;
|
|
61
|
+
}, {
|
|
62
|
+
sha256: string;
|
|
63
|
+
path: "zerops.yaml";
|
|
64
|
+
contents: string;
|
|
65
|
+
}>;
|
|
66
|
+
declare const importDocumentSchema: z.ZodEffects<z.ZodObject<{
|
|
67
|
+
project: z.ZodOptional<z.ZodEffects<z.ZodIntersection<z.ZodRecord<z.ZodString, z.ZodType<JsonValue, z.ZodTypeDef, unknown>>, z.ZodObject<{
|
|
68
|
+
envIsolation: z.ZodLiteral<"service">;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
envIsolation: "service";
|
|
71
|
+
}, {
|
|
72
|
+
envIsolation: "service";
|
|
73
|
+
}>>, Record<string, JsonValue> & {
|
|
74
|
+
envIsolation: "service";
|
|
75
|
+
}, Record<string, unknown> & {
|
|
76
|
+
envIsolation: "service";
|
|
77
|
+
}>>;
|
|
78
|
+
services: z.ZodArray<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodIntersection<z.ZodRecord<z.ZodString, z.ZodType<JsonValue, z.ZodTypeDef, unknown>>, z.ZodObject<{
|
|
79
|
+
hostname: z.ZodString;
|
|
80
|
+
type: z.ZodString;
|
|
81
|
+
envIsolation: z.ZodLiteral<"service">;
|
|
82
|
+
override: z.ZodLiteral<true>;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
type: string;
|
|
85
|
+
envIsolation: "service";
|
|
86
|
+
override: true;
|
|
87
|
+
hostname: string;
|
|
88
|
+
}, {
|
|
89
|
+
type: string;
|
|
90
|
+
envIsolation: "service";
|
|
91
|
+
override: true;
|
|
92
|
+
hostname: string;
|
|
93
|
+
}>>, Record<string, JsonValue> & {
|
|
94
|
+
type: string;
|
|
95
|
+
envIsolation: "service";
|
|
96
|
+
override: true;
|
|
97
|
+
hostname: string;
|
|
98
|
+
}, Record<string, unknown> & {
|
|
99
|
+
type: string;
|
|
100
|
+
envIsolation: "service";
|
|
101
|
+
override: true;
|
|
102
|
+
hostname: string;
|
|
103
|
+
}>, Record<string, JsonValue> & {
|
|
104
|
+
type: string;
|
|
105
|
+
envIsolation: "service";
|
|
106
|
+
override: true;
|
|
107
|
+
hostname: string;
|
|
108
|
+
}, Record<string, unknown> & {
|
|
109
|
+
type: string;
|
|
110
|
+
envIsolation: "service";
|
|
111
|
+
override: true;
|
|
112
|
+
hostname: string;
|
|
113
|
+
}>, Record<string, JsonValue> & {
|
|
114
|
+
type: string;
|
|
115
|
+
envIsolation: "service";
|
|
116
|
+
override: true;
|
|
117
|
+
hostname: string;
|
|
118
|
+
}, Record<string, unknown> & {
|
|
119
|
+
type: string;
|
|
120
|
+
envIsolation: "service";
|
|
121
|
+
override: true;
|
|
122
|
+
hostname: string;
|
|
123
|
+
}>, "many">;
|
|
124
|
+
}, "strict", z.ZodTypeAny, {
|
|
125
|
+
services: (Record<string, JsonValue> & {
|
|
126
|
+
type: string;
|
|
127
|
+
envIsolation: "service";
|
|
128
|
+
override: true;
|
|
129
|
+
hostname: string;
|
|
130
|
+
})[];
|
|
131
|
+
project?: (Record<string, JsonValue> & {
|
|
132
|
+
envIsolation: "service";
|
|
133
|
+
}) | undefined;
|
|
134
|
+
}, {
|
|
135
|
+
services: (Record<string, unknown> & {
|
|
136
|
+
type: string;
|
|
137
|
+
envIsolation: "service";
|
|
138
|
+
override: true;
|
|
139
|
+
hostname: string;
|
|
140
|
+
})[];
|
|
141
|
+
project?: (Record<string, unknown> & {
|
|
142
|
+
envIsolation: "service";
|
|
143
|
+
}) | undefined;
|
|
144
|
+
}>, {
|
|
145
|
+
services: (Record<string, JsonValue> & {
|
|
146
|
+
type: string;
|
|
147
|
+
envIsolation: "service";
|
|
148
|
+
override: true;
|
|
149
|
+
hostname: string;
|
|
150
|
+
})[];
|
|
151
|
+
project?: (Record<string, JsonValue> & {
|
|
152
|
+
envIsolation: "service";
|
|
153
|
+
}) | undefined;
|
|
154
|
+
}, {
|
|
155
|
+
services: (Record<string, unknown> & {
|
|
156
|
+
type: string;
|
|
157
|
+
envIsolation: "service";
|
|
158
|
+
override: true;
|
|
159
|
+
hostname: string;
|
|
160
|
+
})[];
|
|
161
|
+
project?: (Record<string, unknown> & {
|
|
162
|
+
envIsolation: "service";
|
|
163
|
+
}) | undefined;
|
|
164
|
+
}>;
|
|
165
|
+
/** The import document a manifest carries: every service already holds the ADR-0004 invariants. */
|
|
166
|
+
export type FabrikaManifestImportDocument = z.infer<typeof importDocumentSchema>;
|
|
167
|
+
export declare const createZeropsArtifactSourceDescriptor: (contents: string) => Promise<ZeropsArtifactSourceDescriptor>;
|
|
168
|
+
export declare const verifyZeropsArtifactSourceDescriptor: (descriptor: ZeropsArtifactSourceDescriptor) => Promise<void>;
|
|
169
|
+
/** The PostgreSQL service a contract application uses: its own, or the namespace's shared one. */
|
|
170
|
+
export interface ApplicationDatabaseService {
|
|
171
|
+
readonly hostname: string;
|
|
172
|
+
/** The namespace's `postgres`, which every application of a `cheap` namespace shares and the namespace sizes. */
|
|
173
|
+
readonly shared: boolean;
|
|
174
|
+
}
|
|
175
|
+
/** The PostgreSQL service of the application this manifest deploys, or null when it has none. */
|
|
176
|
+
export declare const applicationDatabaseOf: (manifest: FabrikaManifest) => ApplicationDatabaseService | null;
|
|
177
|
+
/**
|
|
178
|
+
* What the platform renders a contract application's execution descriptor from, or null for any other application.
|
|
179
|
+
* The manifest is the one this release's `fabrika app build` wrote, so its build checks with this release.
|
|
180
|
+
*/
|
|
181
|
+
export declare const lockedExecutionOf: (manifest: FabrikaManifest) => ZeropsLockedExecution | null;
|
|
182
|
+
/**
|
|
183
|
+
* What Control lets a provider publish for one environment (`ProviderEnvironment.access`), and, for an environment of
|
|
184
|
+
* kind `dev`, the commit its bootstrap builds.
|
|
185
|
+
*/
|
|
186
|
+
export type ZeropsAccess = Pick<ProviderEnvironment, 'access'> & {
|
|
187
|
+
readonly dev?: ZeropsDevExecution;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* The execution descriptor's lock-down at deploy (ADR-0050): Control's approved contract decides it, not the artifact,
|
|
191
|
+
* so a configuration cannot drop it. Without an approved contract nothing deploys outside a dry run.
|
|
192
|
+
*/
|
|
193
|
+
export declare function lockedExecutionFor(manifest: FabrikaManifest, granted: ZeropsAccess, dryRun: boolean, artifactUpload?: ProviderDeployInput['artifactUpload']): ZeropsLockedExecution | null;
|
|
194
|
+
/** The IAM schema a deploy, cancel or reconcile applies: the approved contract's. `undefined` reconciles nothing. */
|
|
195
|
+
export declare function approvedSchemaOf(granted: ZeropsAccess): AppSchema | undefined;
|
|
196
|
+
export declare const manifestServiceHostnames: (manifest: FabrikaManifest) => string[];
|
|
197
|
+
export declare const renderFabrikaImportYaml: (manifest: FabrikaManifest) => string;
|
|
198
|
+
/** Render the codeless import used before registration has a deploy-service id. */
|
|
199
|
+
export declare const renderFabrikaProvisioningYaml: (manifest: FabrikaManifest) => string;
|
|
200
|
+
export declare function parseFabrikaManifest(value: unknown, expected?: ManifestExpectation): FabrikaManifest;
|
|
201
|
+
export declare function compileFabrikaManifest(config: ZeropsAppConfig, env: string, sourceDescriptor: ZeropsArtifactSourceDescriptor): FabrikaManifest;
|
|
202
|
+
/** Provider artifact codec. Its envelope version and manifest payload version advance independently. */
|
|
203
|
+
export declare const zeropsArtifactCodec: ProviderCodec<FabrikaManifest>;
|
|
204
|
+
/** Hash the original validated artifact, never an interpolated import or execution overlay. */
|
|
205
|
+
export declare function hashFabrikaManifest(manifest: FabrikaManifest): Promise<string>;
|
|
206
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProviderDeploymentNamespace, ProviderRegistration } from '@fabrika/provider-contract';
|
|
2
|
+
export declare const namespaceResourceClaims: (namespace: ProviderDeploymentNamespace) => string[];
|
|
3
|
+
export declare const registrationResourceClaims: (registration: ProviderRegistration) => string[];
|