@relkit/deploy 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/diff-utils.d.ts +15 -0
  4. package/dist/diff-utils.d.ts.map +1 -0
  5. package/dist/diff-utils.js +71 -0
  6. package/dist/diff-utils.js.map +1 -0
  7. package/dist/diff.d.ts +46 -0
  8. package/dist/diff.d.ts.map +1 -0
  9. package/dist/diff.js +103 -0
  10. package/dist/diff.js.map +1 -0
  11. package/dist/from-graph-aws.d.ts +8 -0
  12. package/dist/from-graph-aws.d.ts.map +1 -0
  13. package/dist/from-graph-aws.js +52 -0
  14. package/dist/from-graph-aws.js.map +1 -0
  15. package/dist/from-graph-boundary.d.ts +2 -0
  16. package/dist/from-graph-boundary.d.ts.map +1 -0
  17. package/dist/from-graph-boundary.js +23 -0
  18. package/dist/from-graph-boundary.js.map +1 -0
  19. package/dist/from-graph-context.d.ts +11 -0
  20. package/dist/from-graph-context.d.ts.map +1 -0
  21. package/dist/from-graph-context.js +14 -0
  22. package/dist/from-graph-context.js.map +1 -0
  23. package/dist/from-graph-plan.d.ts +5 -0
  24. package/dist/from-graph-plan.d.ts.map +1 -0
  25. package/dist/from-graph-plan.js +118 -0
  26. package/dist/from-graph-plan.js.map +1 -0
  27. package/dist/from-graph-resources.d.ts +63 -0
  28. package/dist/from-graph-resources.d.ts.map +1 -0
  29. package/dist/from-graph-resources.js +77 -0
  30. package/dist/from-graph-resources.js.map +1 -0
  31. package/dist/from-graph-validation.d.ts +39 -0
  32. package/dist/from-graph-validation.d.ts.map +1 -0
  33. package/dist/from-graph-validation.js +104 -0
  34. package/dist/from-graph-validation.js.map +1 -0
  35. package/dist/from-graph.d.ts +6 -0
  36. package/dist/from-graph.d.ts.map +1 -0
  37. package/dist/from-graph.js +28 -0
  38. package/dist/from-graph.js.map +1 -0
  39. package/dist/iam.d.ts +5 -0
  40. package/dist/iam.d.ts.map +1 -0
  41. package/dist/iam.js +96 -0
  42. package/dist/iam.js.map +1 -0
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +4 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/plan.d.ts +143 -0
  48. package/dist/plan.d.ts.map +1 -0
  49. package/dist/plan.js +5 -0
  50. package/dist/plan.js.map +1 -0
  51. package/package.json +40 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rel-kit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @relkit/deploy
2
+
3
+ Unsupported internal RELKIT deployment contracts; use @relkit/cli.
4
+
5
+ See [@relkit/app](https://github.com/rel-kit/relkit) for supported application APIs.
@@ -0,0 +1,15 @@
1
+ import { type JsonValue } from "@relkit/contracts";
2
+ import type { DeploymentOperation } from "./diff.js";
3
+ import type { DeploymentPlan } from "./plan.js";
4
+ export interface Resource {
5
+ readonly id: string;
6
+ readonly stableId: string;
7
+ readonly kind: string;
8
+ readonly logicalName: string;
9
+ readonly value: JsonValue;
10
+ }
11
+ export declare function resources(plan: DeploymentPlan): readonly Resource[];
12
+ export declare function changedFields(before: JsonValue, after: JsonValue): readonly string[];
13
+ export declare function keys(value: JsonValue): readonly string[];
14
+ export declare function isSecuritySensitive(kind: string, operation: DeploymentOperation, fields: readonly string[], before: JsonValue | undefined, after: JsonValue | undefined): boolean;
15
+ //# sourceMappingURL=diff-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-utils.d.ts","sourceRoot":"","sources":["../src/diff-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,QAAQ,EAAE,CA0BnE;AAmBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,MAAM,EAAE,CAKpF;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,MAAM,EAAE,CAExD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,SAAS,GAAG,SAAS,EAC7B,KAAK,EAAE,SAAS,GAAG,SAAS,GAC3B,OAAO,CAaT"}
@@ -0,0 +1,71 @@
1
+ import { canonicalJson } from "@relkit/contracts";
2
+ export function resources(plan) {
3
+ const result = [
4
+ resource("application", plan.application.id, plan.application.id, {
5
+ ...plan.application,
6
+ contractVersion: plan.contractVersion,
7
+ graphHash: plan.graphHash,
8
+ }),
9
+ resource("http", plan.http.logicalName, plan.http.logicalName, plan.http),
10
+ ...(plan.observability === undefined
11
+ ? []
12
+ : [
13
+ resource("observability", plan.observability.logicalName, plan.observability.logicalName, plan.observability),
14
+ ]),
15
+ ...entries("job", plan.jobs),
16
+ ...entries("schedule", plan.schedules),
17
+ ...entries("event", plan.events),
18
+ ...entries("event-trigger", plan.eventTriggers),
19
+ ...entries("bucket", plan.buckets),
20
+ ...entries("cache", plan.caches),
21
+ ];
22
+ return result.sort((left, right) => left.stableId.localeCompare(right.stableId));
23
+ }
24
+ function entries(kind, values) {
25
+ return values.map((value) => resource(kind, value.id, value.logicalName, value));
26
+ }
27
+ function resource(kind, id, logicalName, value) {
28
+ return {
29
+ id,
30
+ stableId: `${kind}:${id}`,
31
+ kind,
32
+ logicalName,
33
+ value: value,
34
+ };
35
+ }
36
+ export function changedFields(before, after) {
37
+ if (!isRecord(before) || !isRecord(after))
38
+ return ["value"];
39
+ return [...new Set([...Object.keys(before), ...Object.keys(after)])]
40
+ .filter((key) => canonicalJson(before[key]) !== canonicalJson(after[key]))
41
+ .sort();
42
+ }
43
+ export function keys(value) {
44
+ return isRecord(value) ? Object.keys(value).sort() : ["value"];
45
+ }
46
+ export function isSecuritySensitive(kind, operation, fields, before, after) {
47
+ const changed = operation === "create" || operation === "delete" ? [] : fields;
48
+ if (changed.some((field) => /configurationNames|environmentNames|provider|profile/i.test(field)))
49
+ return true;
50
+ if (changed.includes("visibility") && [before, after].some((value) => hasPublicVisibility(value)))
51
+ return true;
52
+ if (changed.includes("metadata") && [before, after].some((value) => hasSecurityMetadata(value)))
53
+ return true;
54
+ if (operation === "create" || operation === "delete")
55
+ return [before, after].some((value) => hasSecurityMetadata(value) || hasPublicVisibility(value));
56
+ return false;
57
+ }
58
+ function hasPublicVisibility(value) {
59
+ return isRecord(value) && value.visibility === "public";
60
+ }
61
+ function hasSecurityMetadata(value) {
62
+ if (!isRecord(value))
63
+ return false;
64
+ return Object.entries(value).some(([key, child]) => /iam|permission|policy|credential|secret|token|role|security/i.test(key)
65
+ ? true
66
+ : hasSecurityMetadata(child));
67
+ }
68
+ function isRecord(value) {
69
+ return value !== null && typeof value === "object" && !Array.isArray(value);
70
+ }
71
+ //# sourceMappingURL=diff-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-utils.js","sourceRoot":"","sources":["../src/diff-utils.ts"],"names":[],"mappings":"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"}
package/dist/diff.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { DeploymentPlan } from "./plan.js";
2
+ export declare const DEPLOYMENT_OPERATIONS: readonly ["create", "update", "delete", "replace"];
3
+ export type DeploymentOperation = (typeof DEPLOYMENT_OPERATIONS)[number];
4
+ export declare const DEPLOYMENT_RISKS: readonly ["low", "medium", "high", "critical"];
5
+ export type DeploymentRisk = (typeof DEPLOYMENT_RISKS)[number];
6
+ export type ConfirmationReason = "destructive" | "security-sensitive";
7
+ export type ConfirmationClassification = "none" | "destructive" | "security-sensitive" | "destructive-and-security-sensitive";
8
+ export interface DeploymentResourceChange {
9
+ /** The descriptor or logical resource ID; it never contains a source path. */
10
+ readonly id: string;
11
+ /** Kind-qualified ID used to order and match resources without array positions. */
12
+ readonly stableId: string;
13
+ readonly kind: string;
14
+ readonly logicalName: string;
15
+ readonly operation: DeploymentOperation;
16
+ readonly risk: DeploymentRisk;
17
+ readonly securitySensitive: boolean;
18
+ readonly confirmation: "none" | "required";
19
+ readonly confirmationClassification: ConfirmationClassification;
20
+ readonly confirmationReasons: readonly ConfirmationReason[];
21
+ readonly fields: readonly string[];
22
+ }
23
+ export interface DeploymentRiskSummary {
24
+ readonly create: number;
25
+ readonly update: number;
26
+ readonly delete: number;
27
+ readonly replace: number;
28
+ readonly securitySensitive: number;
29
+ readonly destructive: number;
30
+ readonly requiresConfirmation: boolean;
31
+ readonly confirmation: "none" | "required";
32
+ readonly highestRisk?: DeploymentRisk;
33
+ }
34
+ export interface DeploymentDiff {
35
+ readonly changes: readonly DeploymentResourceChange[];
36
+ readonly summary: DeploymentRiskSummary;
37
+ readonly hasDestructiveChanges: boolean;
38
+ readonly requiresConfirmation: boolean;
39
+ }
40
+ /** Compares deployment resources; this is intentionally separate from graph contract diffing. */
41
+ export declare function diffDeploymentPlans(before: DeploymentPlan, after: DeploymentPlan): DeploymentDiff;
42
+ export declare const diffDeploymentPlan: typeof diffDeploymentPlans;
43
+ export declare const diffDeployment: typeof diffDeploymentPlans;
44
+ /** Aggregates stable deployment changes for confirmation and human/machine reports. */
45
+ export declare function summarizeDeploymentChanges(changes: readonly DeploymentResourceChange[]): DeploymentRiskSummary;
46
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAShD,eAAO,MAAM,qBAAqB,oDAAqD,CAAC;AACxF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,eAAO,MAAM,gBAAgB,gDAAiD,CAAC;AAC/E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,oBAAoB,CAAC;AACtE,MAAM,MAAM,0BAA0B,GACpC,MAAM,GAAG,aAAa,GAAG,oBAAoB,GAAG,oCAAoC,CAAC;AAEvF,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3C,QAAQ,CAAC,0BAA0B,EAAE,0BAA0B,CAAC;IAChE,QAAQ,CAAC,mBAAmB,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC;AAED,iGAAiG;AACjG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,CAejG;AAED,eAAO,MAAM,kBAAkB,4BAAsB,CAAC;AACtD,eAAO,MAAM,cAAc,4BAAsB,CAAC;AAElD,uFAAuF;AACvF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,SAAS,wBAAwB,EAAE,GAC3C,qBAAqB,CAmBvB"}
package/dist/diff.js ADDED
@@ -0,0 +1,103 @@
1
+ import { canonicalJson, deepFreeze } from "@relkit/contracts";
2
+ import { changedFields, isSecuritySensitive, keys, resources, } from "./diff-utils.js";
3
+ export const DEPLOYMENT_OPERATIONS = ["create", "update", "delete", "replace"];
4
+ export const DEPLOYMENT_RISKS = ["low", "medium", "high", "critical"];
5
+ /** Compares deployment resources; this is intentionally separate from graph contract diffing. */
6
+ export function diffDeploymentPlans(before, after) {
7
+ const left = resources(before);
8
+ const right = resources(after);
9
+ const beforeById = new Map(left.map((resource) => [resource.stableId, resource]));
10
+ const afterById = new Map(right.map((resource) => [resource.stableId, resource]));
11
+ const changes = [...new Set([...beforeById.keys(), ...afterById.keys()])]
12
+ .sort()
13
+ .flatMap((stableId) => change(beforeById.get(stableId), afterById.get(stableId)));
14
+ const summary = summarizeDeploymentChanges(changes);
15
+ return deepFreeze({
16
+ changes,
17
+ summary,
18
+ hasDestructiveChanges: summary.destructive > 0,
19
+ requiresConfirmation: summary.requiresConfirmation,
20
+ });
21
+ }
22
+ export const diffDeploymentPlan = diffDeploymentPlans;
23
+ export const diffDeployment = diffDeploymentPlans;
24
+ /** Aggregates stable deployment changes for confirmation and human/machine reports. */
25
+ export function summarizeDeploymentChanges(changes) {
26
+ const counts = { create: 0, update: 0, delete: 0, replace: 0 };
27
+ for (const change of changes)
28
+ counts[change.operation] += 1;
29
+ const securitySensitive = changes.filter((change) => change.securitySensitive).length;
30
+ const destructive = counts.delete + counts.replace;
31
+ const requiresConfirmation = changes.some((change) => change.confirmation === "required");
32
+ const highestRisk = changes.reduce((current, change) => current === undefined || rank(change.risk) > rank(current) ? change.risk : current, undefined);
33
+ return deepFreeze({
34
+ ...counts,
35
+ securitySensitive,
36
+ destructive,
37
+ requiresConfirmation,
38
+ confirmation: requiresConfirmation ? "required" : "none",
39
+ ...(highestRisk === undefined ? {} : { highestRisk }),
40
+ });
41
+ }
42
+ function change(before, after) {
43
+ if (before === undefined && after === undefined)
44
+ return [];
45
+ const resource = after ?? before;
46
+ if (before !== undefined &&
47
+ after !== undefined &&
48
+ canonicalJson(before.value) === canonicalJson(after.value))
49
+ return [];
50
+ const operation = before === undefined
51
+ ? "create"
52
+ : after === undefined
53
+ ? "delete"
54
+ : before.logicalName !== after.logicalName
55
+ ? "replace"
56
+ : "update";
57
+ const fields = before === undefined
58
+ ? keys(resource.value)
59
+ : after === undefined
60
+ ? keys(resource.value)
61
+ : changedFields(before.value, after.value);
62
+ const securitySensitive = isSecuritySensitive(resource.kind, operation, fields, before?.value, after?.value);
63
+ const reasons = [];
64
+ if (operation === "delete" || operation === "replace")
65
+ reasons.push("destructive");
66
+ if (securitySensitive)
67
+ reasons.push("security-sensitive");
68
+ const confirmationClassification = reasons.includes("destructive")
69
+ ? reasons.includes("security-sensitive")
70
+ ? "destructive-and-security-sensitive"
71
+ : "destructive"
72
+ : reasons.includes("security-sensitive")
73
+ ? "security-sensitive"
74
+ : "none";
75
+ return [
76
+ {
77
+ id: resource.id,
78
+ stableId: resource.stableId,
79
+ kind: resource.kind,
80
+ logicalName: resource.logicalName,
81
+ operation,
82
+ risk: risk(operation, securitySensitive),
83
+ securitySensitive,
84
+ confirmation: confirmationClassification === "none" ? "none" : "required",
85
+ confirmationClassification,
86
+ confirmationReasons: reasons,
87
+ fields,
88
+ },
89
+ ];
90
+ }
91
+ function risk(operation, securitySensitive) {
92
+ if (operation === "replace")
93
+ return "critical";
94
+ if (operation === "delete")
95
+ return securitySensitive ? "critical" : "high";
96
+ if (securitySensitive)
97
+ return "high";
98
+ return operation === "update" ? "medium" : "low";
99
+ }
100
+ function rank(value) {
101
+ return DEPLOYMENT_RISKS.indexOf(value);
102
+ }
103
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ApplicationGraph, GraphNode } from "@relkit/graph";
2
+ import type { Capability } from "./from-graph-validation.js";
3
+ export declare function iam(name: Capability, id: string, edges: ApplicationGraph["edges"]): string[];
4
+ export declare function usedCapabilities(nodes: readonly GraphNode[], edges: ApplicationGraph["edges"]): readonly {
5
+ readonly capability: Capability;
6
+ readonly profile: string;
7
+ }[];
8
+ //# sourceMappingURL=from-graph-aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-aws.d.ts","sourceRoot":"","sources":["../src/from-graph-aws.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,wBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAc5F;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAC/B,SAAS;IAAE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CA8B1E"}
@@ -0,0 +1,52 @@
1
+ export function iam(name, id, edges) {
2
+ const linked = (kind) => edges.some((edge) => edge.kind === kind && edge.to === id);
3
+ if (name === "buckets" && linked("uses-bucket"))
4
+ return ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"];
5
+ if (name === "jobs")
6
+ return [
7
+ "sqs:ReceiveMessage",
8
+ "sqs:DeleteMessage",
9
+ "sqs:ChangeMessageVisibility",
10
+ ...(linked("enqueues-job") ? ["sqs:SendMessage"] : []),
11
+ ];
12
+ if (name === "events" && linked("publishes-event"))
13
+ return ["events:PutEvents"];
14
+ if (name === "cache" && linked("uses-cache"))
15
+ return ["elasticache:Connect"];
16
+ return [];
17
+ }
18
+ export function usedCapabilities(nodes, edges) {
19
+ const used = new Map();
20
+ const add = (capability, profile = "default") => {
21
+ used.set(`${capability}\0${profile}`, { capability, profile });
22
+ };
23
+ for (const node of nodes) {
24
+ if (node.kind === "job")
25
+ add("jobs", node.profile);
26
+ if (node.kind === "bucket")
27
+ add("buckets", node.profile);
28
+ if (node.kind === "cache")
29
+ add("cache", node.profile);
30
+ if (node.kind === "event")
31
+ add("events");
32
+ if (node.kind === "agent")
33
+ add("models");
34
+ if (node.kind === "trigger" && node.triggerType === "event") {
35
+ const profile = node.config !== null &&
36
+ typeof node.config === "object" &&
37
+ !Array.isArray(node.config) &&
38
+ typeof node.config.profile === "string"
39
+ ? node.config.profile
40
+ : "default";
41
+ add("events", profile);
42
+ }
43
+ if (node.kind === "trigger" &&
44
+ (node.triggerType === "queue" || node.triggerType === "schedule"))
45
+ add("jobs");
46
+ }
47
+ for (const edge of edges)
48
+ if (edge.kind === "publishes-event" || edge.kind === "listens-to-event")
49
+ add("events");
50
+ return [...used.values()];
51
+ }
52
+ //# sourceMappingURL=from-graph-aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-aws.js","sourceRoot":"","sources":["../src/from-graph-aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function validateBoundary(value: unknown): void;
2
+ //# sourceMappingURL=from-graph-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-boundary.d.ts","sourceRoot":"","sources":["../src/from-graph-boundary.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAUrD"}
@@ -0,0 +1,23 @@
1
+ import { canonicalJson } from "@relkit/contracts";
2
+ import { fail, secretName } from "./from-graph-validation.js";
3
+ export function validateBoundary(value) {
4
+ try {
5
+ canonicalJson(value);
6
+ }
7
+ catch (error) {
8
+ fail("RELKIT_DEPLOY_GRAPH_INVALID", error instanceof Error ? error.message : "Boundary is not JSON-safe.");
9
+ }
10
+ scan(value);
11
+ }
12
+ function scan(value) {
13
+ if (value === null || typeof value !== "object")
14
+ return;
15
+ for (const [key, child] of Object.entries(value)) {
16
+ if (/^(pulumi|client|live(client|object)?|resource)$/i.test(key))
17
+ fail("RELKIT_DEPLOY_LIVE_OBJECT_UNSUPPORTED", "Live deployment objects cannot cross the graph boundary.");
18
+ if (secretName(key) && (child === null || typeof child !== "object") && child !== true)
19
+ fail("RELKIT_DEPLOY_SECRET_UNSUPPORTED", "Secret values cannot cross the graph boundary.");
20
+ scan(child);
21
+ }
22
+ }
23
+ //# sourceMappingURL=from-graph-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-boundary.js","sourceRoot":"","sources":["../src/from-graph-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC;QACH,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CACF,6BAA6B,EAC7B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,CAAC;AACd,CAAC;AAED,SAAS,IAAI,CAAC,KAAc;IAC1B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO;IACxD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,kDAAkD,CAAC,IAAI,CAAC,GAAG,CAAC;YAC9D,IAAI,CACF,uCAAuC,EACvC,0DAA0D,CAC3D,CAAC;QACJ,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,IAAI,KAAK,KAAK,IAAI;YACpF,IAAI,CAAC,kCAAkC,EAAE,gDAAgD,CAAC,CAAC;QAC7F,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ApplicationGraph, ProviderProfileNode } from "@relkit/graph";
2
+ import type { DeploymentCapabilityPlan } from "./plan.js";
3
+ import type { Capability } from "./from-graph-validation.js";
4
+ export interface PlanContext {
5
+ readonly appId: string;
6
+ readonly graphHash: string;
7
+ readonly graph: ApplicationGraph;
8
+ readonly providers: Map<string, ProviderProfileNode>;
9
+ }
10
+ export declare function base(context: PlanContext, id: string, kind: string, name: Capability, profile: string, actions?: readonly string[]): DeploymentCapabilityPlan;
11
+ //# sourceMappingURL=from-graph-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-context.d.ts","sourceRoot":"","sources":["../src/from-graph-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACtD;AAED,wBAAgB,IAAI,CAClB,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,SAAS,MAAM,EAAO,GAC9B,wBAAwB,CAW1B"}
@@ -0,0 +1,14 @@
1
+ import { configNames, logicalName, providerId } from "./from-graph-validation.js";
2
+ export function base(context, id, kind, name, profile, actions = []) {
3
+ return {
4
+ id,
5
+ logicalName: logicalName(context.appId, kind, id),
6
+ bindingId: providerId(name, profile),
7
+ profile,
8
+ configurationNames: configNames(context.providers, name, profile),
9
+ capabilities: [name],
10
+ tags: { app: context.appId, graphHash: context.graphHash, "managed-by": "relkit" },
11
+ ...(actions.length === 0 ? {} : { metadata: { iamCapabilities: actions } }),
12
+ };
13
+ }
14
+ //# sourceMappingURL=from-graph-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-context.js","sourceRoot":"","sources":["../src/from-graph-context.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AASlF,MAAM,UAAU,IAAI,CAClB,OAAoB,EACpB,EAAU,EACV,IAAY,EACZ,IAAgB,EAChB,OAAe,EACf,UAA6B,EAAE;IAE/B,OAAO;QACL,EAAE;QACF,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QACjD,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;QACpC,OAAO;QACP,kBAAkB,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;QACjE,YAAY,EAAE,CAAC,IAAI,CAAC;QACpB,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE;QAClF,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,CAAC;KAC5E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ApplicationGraph, ProviderProfileNode } from "@relkit/graph";
2
+ import { type DeploymentPlan } from "./plan.js";
3
+ import type { FromGraphOptions } from "./from-graph-validation.js";
4
+ export declare function buildPlan(graph: ApplicationGraph, appId: string, graphHash: string, options: FromGraphOptions, providers: Map<string, ProviderProfileNode>): DeploymentPlan;
5
+ //# sourceMappingURL=from-graph-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-plan.d.ts","sourceRoot":"","sources":["../src/from-graph-plan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAoD,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAOnE,wBAAgB,SAAS,CACvB,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAC1C,cAAc,CAqChB"}
@@ -0,0 +1,118 @@
1
+ import { deepFreeze } from "@relkit/contracts";
2
+ import { DEPLOYMENT_PLAN_VERSION } from "./plan.js";
3
+ import { byLogical, envNames, isManaged, logicalName, nodes } from "./from-graph-validation.js";
4
+ import { iam } from "./from-graph-aws.js";
5
+ import { base } from "./from-graph-context.js";
6
+ import { createIamPlan } from "./iam.js";
7
+ import { buckets, caches, eventTriggers, events, routes } from "./from-graph-resources.js";
8
+ export function buildPlan(graph, appId, graphHash, options, providers) {
9
+ const context = { appId, graphHash, graph, providers };
10
+ const image = options.image ?? defaultImage(appId, options.httpPort ?? 3000);
11
+ validateImage(image);
12
+ const environmentNames = envNames(graph.nodes);
13
+ return deepFreeze({
14
+ contractVersion: DEPLOYMENT_PLAN_VERSION,
15
+ graphHash,
16
+ application: { id: appId, image, environmentNames },
17
+ providerBindings: [...providers.values()]
18
+ .filter((provider) => provider.ownership === "managed")
19
+ .map((provider) => ({
20
+ id: provider.id,
21
+ capability: provider.capability,
22
+ profile: provider.profile,
23
+ adapter: provider.adapter,
24
+ ownership: "managed",
25
+ configuration: provider.configuration,
26
+ environment: provider.environment,
27
+ }))
28
+ .sort((left, right) => left.id.localeCompare(right.id)),
29
+ http: {
30
+ logicalName: logicalName(appId, "http", "public"),
31
+ port: image.health.port,
32
+ health: image.health,
33
+ routes: routes(graph.nodes),
34
+ configurationNames: environmentNames,
35
+ },
36
+ jobs: jobs(context),
37
+ schedules: schedules(context),
38
+ events: events(context),
39
+ eventTriggers: eventTriggers(context),
40
+ buckets: buckets(context),
41
+ caches: caches(context),
42
+ iam: createIamPlan(appId, graph, providers),
43
+ ...managedObservability(providers, appId, environmentNames),
44
+ });
45
+ }
46
+ function managedObservability(providers, appId, environmentNames) {
47
+ const binding = [...providers.values()].find((provider) => provider.capability === "observability" && provider.ownership === "managed");
48
+ if (binding === undefined)
49
+ return {};
50
+ return {
51
+ observability: {
52
+ logicalName: logicalName(appId, "observability", binding.profile),
53
+ configurationNames: environmentNames.filter((name) => /log|trace|otlp/i.test(name)),
54
+ logs: true,
55
+ traces: true,
56
+ },
57
+ };
58
+ }
59
+ function jobs(context) {
60
+ return nodes(context.graph.nodes, "job")
61
+ .filter((job) => isManaged(context.providers, "jobs", job.profile))
62
+ .map((job) => ({
63
+ ...base(context, job.id, "job", "jobs", job.profile, iam("jobs", job.id, context.graph.edges)),
64
+ targetFunctionId: job.targetFunctionId,
65
+ profile: job.profile,
66
+ ...(defined(job.retry) ? { retry: job.retry } : {}),
67
+ ...(defined(job.timeoutMs) ? { timeoutMs: job.timeoutMs } : {}),
68
+ ...(defined(job.concurrency) ? { concurrency: job.concurrency } : {}),
69
+ ...(defined(job.idempotency) ? { idempotency: job.idempotency } : {}),
70
+ }))
71
+ .sort(byLogical);
72
+ }
73
+ function schedules(context) {
74
+ return nodes(context.graph.nodes, "job")
75
+ .filter((job) => isManaged(context.providers, "jobs", job.profile))
76
+ .flatMap((job) => {
77
+ if (!Array.isArray(job.schedule))
78
+ return [];
79
+ return job.schedule.map((schedule, index) => ({
80
+ ...base(context, descriptorId(schedule, `${job.id}:schedule:${index}`), "schedule", "jobs", job.profile),
81
+ jobId: job.id,
82
+ schedule,
83
+ }));
84
+ })
85
+ .sort(byLogical);
86
+ }
87
+ function defaultImage(appId, port) {
88
+ return {
89
+ name: appId,
90
+ tag: "latest",
91
+ health: {
92
+ livenessPath: "/_relkit/v1/health/live",
93
+ readinessPath: "/_relkit/v1/health/ready",
94
+ port,
95
+ },
96
+ };
97
+ }
98
+ function descriptorId(value, fallback) {
99
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
100
+ const id = value.id;
101
+ if (typeof id === "string" && id.length > 0)
102
+ return id;
103
+ }
104
+ return fallback;
105
+ }
106
+ function validateImage(image) {
107
+ if (!image.name ||
108
+ !image.health ||
109
+ !image.health.livenessPath ||
110
+ !image.health.readinessPath ||
111
+ !Number.isInteger(image.health.port) ||
112
+ image.health.port < 1)
113
+ throw new TypeError("Deployment image health metadata is invalid.");
114
+ }
115
+ function defined(value) {
116
+ return value !== null && value !== undefined;
117
+ }
118
+ //# sourceMappingURL=from-graph-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-graph-plan.js","sourceRoot":"","sources":["../src/from-graph-plan.ts"],"names":[],"mappings":"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"}