@telorun/kernel 0.11.1 → 0.13.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 (161) hide show
  1. package/LICENSE +2 -2
  2. package/dist/application-env.d.ts +24 -0
  3. package/dist/application-env.d.ts.map +1 -0
  4. package/dist/application-env.js +156 -0
  5. package/dist/application-env.js.map +1 -0
  6. package/dist/base-definition.d.ts +14 -0
  7. package/dist/base-definition.d.ts.map +1 -0
  8. package/dist/base-definition.js +17 -0
  9. package/dist/base-definition.js.map +1 -0
  10. package/dist/capabilities/capabilities/component.yaml +4 -0
  11. package/dist/capabilities/capabilities/executable.yaml +8 -0
  12. package/dist/capabilities/capabilities/handler.yaml +4 -0
  13. package/dist/capabilities/capabilities/listener.yaml +4 -0
  14. package/dist/capabilities/capabilities/provider.yaml +4 -0
  15. package/dist/capabilities/capabilities/template.yaml +4 -0
  16. package/dist/capabilities/capabilities/type.yaml +4 -0
  17. package/dist/capabilities/component.d.ts +3 -0
  18. package/dist/capabilities/component.d.ts.map +1 -0
  19. package/dist/capabilities/component.js +4 -0
  20. package/dist/capabilities/component.js.map +1 -0
  21. package/dist/capabilities/component.yaml +3 -0
  22. package/dist/capabilities/executable.d.ts +3 -0
  23. package/dist/capabilities/executable.d.ts.map +1 -0
  24. package/dist/capabilities/executable.js +5 -0
  25. package/dist/capabilities/executable.js.map +1 -0
  26. package/dist/capabilities/executable.yaml +7 -0
  27. package/dist/capabilities/handler.d.ts +3 -0
  28. package/dist/capabilities/handler.d.ts.map +1 -0
  29. package/dist/capabilities/handler.js +4 -0
  30. package/dist/capabilities/handler.js.map +1 -0
  31. package/dist/capabilities/handler.yaml +3 -0
  32. package/dist/capabilities/invokable.d.ts +3 -0
  33. package/dist/capabilities/invokable.d.ts.map +1 -0
  34. package/dist/capabilities/invokable.js +5 -0
  35. package/dist/capabilities/invokable.js.map +1 -0
  36. package/dist/capabilities/listener.d.ts +3 -0
  37. package/dist/capabilities/listener.d.ts.map +1 -0
  38. package/dist/capabilities/listener.js +5 -0
  39. package/dist/capabilities/listener.js.map +1 -0
  40. package/dist/capabilities/listener.yaml +3 -0
  41. package/dist/capabilities/mount.d.ts +3 -0
  42. package/dist/capabilities/mount.d.ts.map +1 -0
  43. package/dist/capabilities/mount.js +5 -0
  44. package/dist/capabilities/mount.js.map +1 -0
  45. package/dist/capabilities/provider.d.ts +3 -0
  46. package/dist/capabilities/provider.d.ts.map +1 -0
  47. package/dist/capabilities/provider.js +8 -0
  48. package/dist/capabilities/provider.js.map +1 -0
  49. package/dist/capabilities/provider.yaml +3 -0
  50. package/dist/capabilities/runnable.d.ts +3 -0
  51. package/dist/capabilities/runnable.d.ts.map +1 -0
  52. package/dist/capabilities/runnable.js +5 -0
  53. package/dist/capabilities/runnable.js.map +1 -0
  54. package/dist/capabilities/service.d.ts +3 -0
  55. package/dist/capabilities/service.d.ts.map +1 -0
  56. package/dist/capabilities/service.js +5 -0
  57. package/dist/capabilities/service.js.map +1 -0
  58. package/dist/capabilities/template.d.ts +3 -0
  59. package/dist/capabilities/template.d.ts.map +1 -0
  60. package/dist/capabilities/template.js +5 -0
  61. package/dist/capabilities/template.js.map +1 -0
  62. package/dist/capabilities/template.yaml +3 -0
  63. package/dist/capabilities/type.d.ts +3 -0
  64. package/dist/capabilities/type.d.ts.map +1 -0
  65. package/dist/capabilities/type.js +5 -0
  66. package/dist/capabilities/type.js.map +1 -0
  67. package/dist/capabilities/type.yaml +3 -0
  68. package/dist/controller-loaders/npm-loader.d.ts +32 -8
  69. package/dist/controller-loaders/npm-loader.d.ts.map +1 -1
  70. package/dist/controller-loaders/npm-loader.js +120 -118
  71. package/dist/controller-loaders/npm-loader.js.map +1 -1
  72. package/dist/controllers/capability/capability-controller.d.ts +32 -0
  73. package/dist/controllers/capability/capability-controller.d.ts.map +1 -0
  74. package/dist/controllers/capability/capability-controller.js +26 -0
  75. package/dist/controllers/capability/capability-controller.js.map +1 -0
  76. package/dist/controllers/module/import-controller.d.ts +3 -2
  77. package/dist/controllers/module/import-controller.d.ts.map +1 -1
  78. package/dist/controllers/module/import-controller.js +23 -25
  79. package/dist/controllers/module/import-controller.js.map +1 -1
  80. package/dist/controllers/module/module.json +48 -0
  81. package/dist/controllers/resource-definition/resource-definition-controller.d.ts +1 -0
  82. package/dist/controllers/resource-definition/resource-definition-controller.d.ts.map +1 -1
  83. package/dist/controllers/resource-definition/resource-definition-controller.js +3 -0
  84. package/dist/controllers/resource-definition/resource-definition-controller.js.map +1 -1
  85. package/dist/controllers/resource-definition/resource-template-controller.d.ts +6 -1
  86. package/dist/controllers/resource-definition/resource-template-controller.d.ts.map +1 -1
  87. package/dist/controllers/resource-definition/resource-template-controller.js +79 -13
  88. package/dist/controllers/resource-definition/resource-template-controller.js.map +1 -1
  89. package/dist/internal-context.d.ts +25 -0
  90. package/dist/internal-context.d.ts.map +1 -0
  91. package/dist/internal-context.js +2 -0
  92. package/dist/internal-context.js.map +1 -0
  93. package/dist/kernel.d.ts +21 -1
  94. package/dist/kernel.d.ts.map +1 -1
  95. package/dist/kernel.js +109 -5
  96. package/dist/kernel.js.map +1 -1
  97. package/dist/loader.d.ts +18 -0
  98. package/dist/loader.d.ts.map +1 -0
  99. package/dist/loader.js +127 -0
  100. package/dist/loader.js.map +1 -0
  101. package/dist/manifest-adapters/http-adapter.d.ts +8 -0
  102. package/dist/manifest-adapters/http-adapter.d.ts.map +1 -0
  103. package/dist/manifest-adapters/http-adapter.js +31 -0
  104. package/dist/manifest-adapters/http-adapter.js.map +1 -0
  105. package/dist/manifest-adapters/local-file-adapter.d.ts +15 -0
  106. package/dist/manifest-adapters/local-file-adapter.d.ts.map +1 -0
  107. package/dist/manifest-adapters/local-file-adapter.js +95 -0
  108. package/dist/manifest-adapters/local-file-adapter.js.map +1 -0
  109. package/dist/manifest-adapters/manifest-adapter.d.ts +35 -0
  110. package/dist/manifest-adapters/manifest-adapter.d.ts.map +1 -0
  111. package/dist/manifest-adapters/manifest-adapter.js +2 -0
  112. package/dist/manifest-adapters/manifest-adapter.js.map +1 -0
  113. package/dist/manifest-adapters/registry-adapter.d.ts +9 -0
  114. package/dist/manifest-adapters/registry-adapter.d.ts.map +1 -0
  115. package/dist/manifest-adapters/registry-adapter.js +48 -0
  116. package/dist/manifest-adapters/registry-adapter.js.map +1 -0
  117. package/dist/manifest-schemas.d.ts +7 -23
  118. package/dist/manifest-schemas.d.ts.map +1 -1
  119. package/dist/manifest-schemas.js +18 -8
  120. package/dist/manifest-schemas.js.map +1 -1
  121. package/dist/manifest-sources/analysis-stamp.d.ts +25 -0
  122. package/dist/manifest-sources/analysis-stamp.d.ts.map +1 -0
  123. package/dist/manifest-sources/analysis-stamp.js +151 -0
  124. package/dist/manifest-sources/analysis-stamp.js.map +1 -0
  125. package/dist/module-context-registry.d.ts +48 -0
  126. package/dist/module-context-registry.d.ts.map +1 -0
  127. package/dist/module-context-registry.js +91 -0
  128. package/dist/module-context-registry.js.map +1 -0
  129. package/dist/resource-context.d.ts +2 -0
  130. package/dist/resource-context.d.ts.map +1 -1
  131. package/dist/resource-context.js +28 -0
  132. package/dist/resource-context.js.map +1 -1
  133. package/dist/schema-valiator.d.ts +15 -0
  134. package/dist/schema-valiator.d.ts.map +1 -0
  135. package/dist/schema-valiator.js +127 -0
  136. package/dist/schema-valiator.js.map +1 -0
  137. package/dist/schema-validator.d.ts +28 -0
  138. package/dist/schema-validator.d.ts.map +1 -1
  139. package/dist/schema-validator.js +161 -1
  140. package/dist/schema-validator.js.map +1 -1
  141. package/dist/snapshot-serializer.d.ts +62 -0
  142. package/dist/snapshot-serializer.d.ts.map +1 -0
  143. package/dist/snapshot-serializer.js +164 -0
  144. package/dist/snapshot-serializer.js.map +1 -0
  145. package/dist/types.d.ts +65 -0
  146. package/dist/types.d.ts.map +1 -0
  147. package/dist/types.js +8 -0
  148. package/dist/types.js.map +1 -0
  149. package/package.json +9 -6
  150. package/src/application-env.ts +216 -0
  151. package/src/controller-loaders/npm-loader.ts +133 -118
  152. package/src/controllers/module/import-controller.ts +33 -36
  153. package/src/controllers/resource-definition/resource-definition-controller.ts +6 -0
  154. package/src/controllers/resource-definition/resource-template-controller.ts +110 -16
  155. package/src/internal-context.ts +25 -0
  156. package/src/kernel.ts +130 -5
  157. package/src/manifest-schemas.ts +31 -11
  158. package/src/manifest-sources/analysis-stamp.ts +169 -0
  159. package/src/resource-context.ts +34 -0
  160. package/src/schema-validator.ts +178 -2
  161. package/dist/generated/runtime-deps.json +0 -6
@@ -0,0 +1,164 @@
1
+ import * as fs from "fs/promises";
2
+ import * as YAML from "js-yaml";
3
+ import * as path from "path";
4
+ /**
5
+ * Serializes runtime state into YAML snapshots
6
+ * Captures resource definitions, instances, and custom state
7
+ * Recursively includes nested resources based on generationDepth
8
+ */
9
+ export class SnapshotSerializer {
10
+ /**
11
+ * Take a snapshot of runtime state
12
+ * @param resources Map of resources organized by kind
13
+ * @param resourceInstances Map of resource instances to include custom snapshots
14
+ * @param filePath Optional file path to write snapshot to
15
+ * @returns Snapshot data object
16
+ */
17
+ async takeSnapshot(resources, resourceInstances, filePath) {
18
+ const snapshot = {
19
+ timestamp: new Date().toISOString(),
20
+ resources: [],
21
+ };
22
+ // Get all resources organized by generation depth (0 = first level)
23
+ // Start with depth 0 (directly loaded resources) and recursively include nested ones
24
+ const resourcesByDepth = this.groupByGenerationDepth(resources);
25
+ // Process resources starting from depth 0
26
+ for (const depth of Array.from(resourcesByDepth.keys()).sort((a, b) => a - b)) {
27
+ const resourcesAtDepth = resourcesByDepth.get(depth) || [];
28
+ for (const resource of resourcesAtDepth) {
29
+ const resourceEntry = await this.serializeResource(resource, resourceInstances);
30
+ snapshot.resources.push(resourceEntry);
31
+ }
32
+ }
33
+ // Write to file if path provided
34
+ if (filePath) {
35
+ await this.writeSnapshotToFile(snapshot, filePath);
36
+ }
37
+ return snapshot;
38
+ }
39
+ /**
40
+ * Serialize a single resource
41
+ */
42
+ async serializeResource(resource, resourceInstances) {
43
+ const { kind, metadata, ...data } = resource;
44
+ const { name } = metadata;
45
+ const resourceEntry = {
46
+ kind,
47
+ name,
48
+ metadata: this.serializeMetadata(metadata),
49
+ data: this.serializeData(data),
50
+ };
51
+ // Include custom snapshot if resource instance has snapshot() method
52
+ if (resourceInstances) {
53
+ const key = this.getResourceKey(kind, name);
54
+ const instanceData = resourceInstances.get(key);
55
+ if (instanceData && instanceData.instance) {
56
+ const snapshotData = await this.getInstanceSnapshot(instanceData.instance);
57
+ if (snapshotData) {
58
+ resourceEntry.snapshot = snapshotData;
59
+ }
60
+ }
61
+ }
62
+ return resourceEntry;
63
+ }
64
+ /**
65
+ * Get snapshot from resource instance if it implements snapshot() method
66
+ */
67
+ async getInstanceSnapshot(instance) {
68
+ const instanceAny = instance;
69
+ // Check if snapshot method exists
70
+ if (typeof instanceAny.snapshot === "function") {
71
+ try {
72
+ const result = await Promise.resolve(instanceAny.snapshot(instance));
73
+ return result;
74
+ }
75
+ catch (error) {
76
+ console.error("Error calling snapshot() on resource instance:", error);
77
+ return null;
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+ /**
83
+ * Serialize metadata, filtering out circular references and functions
84
+ */
85
+ serializeMetadata(metadata) {
86
+ const serialized = {};
87
+ for (const [key, value] of Object.entries(metadata)) {
88
+ if (typeof value === "function") {
89
+ continue;
90
+ }
91
+ try {
92
+ serialized[key] = JSON.parse(JSON.stringify(value));
93
+ }
94
+ catch {
95
+ // Skip non-serializable values
96
+ }
97
+ }
98
+ return serialized;
99
+ }
100
+ /**
101
+ * Serialize resource data, filtering out circular references and functions
102
+ */
103
+ serializeData(data) {
104
+ const serialized = {};
105
+ for (const [key, value] of Object.entries(data)) {
106
+ if (typeof value === "function") {
107
+ continue;
108
+ }
109
+ try {
110
+ serialized[key] = JSON.parse(JSON.stringify(value));
111
+ }
112
+ catch {
113
+ // Skip non-serializable values
114
+ }
115
+ }
116
+ return serialized;
117
+ }
118
+ /**
119
+ * Group resources by generation depth for hierarchical ordering
120
+ */
121
+ groupByGenerationDepth(resources) {
122
+ const grouped = new Map();
123
+ for (const kindMap of resources.values()) {
124
+ for (const resource of kindMap.values()) {
125
+ const depth = resource.metadata.generationDepth ?? 0;
126
+ if (!grouped.has(depth)) {
127
+ grouped.set(depth, []);
128
+ }
129
+ grouped.get(depth).push(resource);
130
+ }
131
+ }
132
+ return grouped;
133
+ }
134
+ /**
135
+ * Write snapshot to YAML file
136
+ */
137
+ async writeSnapshotToFile(snapshot, filePath) {
138
+ // Ensure directory exists
139
+ const dir = path.dirname(filePath);
140
+ if (dir !== "." && dir !== "") {
141
+ await fs.mkdir(dir, { recursive: true });
142
+ }
143
+ // Convert to YAML
144
+ const yaml = YAML.dump(snapshot, {
145
+ indent: 2,
146
+ lineWidth: 0,
147
+ });
148
+ await fs.writeFile(filePath, yaml, "utf-8");
149
+ }
150
+ /**
151
+ * Generate resource key for instance lookup
152
+ */
153
+ getResourceKey(kind, name) {
154
+ return `${kind}:${name}`;
155
+ }
156
+ /**
157
+ * Load snapshot from YAML file
158
+ */
159
+ async loadSnapshotFromFile(filePath) {
160
+ const content = await fs.readFile(filePath, "utf-8");
161
+ return YAML.load(content);
162
+ }
163
+ }
164
+ //# sourceMappingURL=snapshot-serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-serializer.js","sourceRoot":"","sources":["../src/snapshot-serializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { ControllerContext, ResourceContext, ResourceInstance, ResourceManifest, RuntimeErrorCode, RuntimeResource } from "@telorun/sdk";
2
+ import type { ModuleContext } from "./module-context.js";
3
+ export type { ControllerContext, ResourceContext, ResourceInstance, ResourceManifest } from "@telorun/sdk";
4
+ export interface KernelContext {
5
+ kernel: Kernel;
6
+ }
7
+ export interface ExecContext {
8
+ execute(urn: string, input: any): Promise<any>;
9
+ [key: string]: any;
10
+ }
11
+ export type ResourceCapability = string;
12
+ export interface ResourceDefinition {
13
+ kind: string;
14
+ metadata: {
15
+ name: string;
16
+ module: string;
17
+ };
18
+ schema: Record<string, any>;
19
+ capabilities: ResourceCapability[];
20
+ events?: string[];
21
+ controllers?: Array<{
22
+ runtime: string;
23
+ entry: string;
24
+ }>;
25
+ }
26
+ /**
27
+ * Controller definition for a resource kind.
28
+ * Maps a fully-qualified resource kind to its controller implementation for a specific runtime.
29
+ */
30
+ export interface ControllerDefinition {
31
+ kind: string;
32
+ runtime: string;
33
+ entry: string;
34
+ controller?: any;
35
+ }
36
+ /**
37
+ * Controller instance - runtime representation of a controller that handles resource instances.
38
+ */
39
+ export interface ControllerInstance {
40
+ execute?(name: string, inputs: any, ctx: ExecContext): Promise<any>;
41
+ compile?(resource: ResourceManifest, ctx: ResourceContext): RuntimeResource | Promise<RuntimeResource>;
42
+ register?(ctx: ControllerContext): void | Promise<void>;
43
+ create?(resource: ResourceManifest, ctx: ResourceContext): ResourceInstance | null | Promise<ResourceInstance | null>;
44
+ schema: any;
45
+ }
46
+ export interface Kernel {
47
+ loadFromConfig(runtimeYamlPath: string): Promise<void>;
48
+ start(): Promise<void>;
49
+ acquireHold(reason?: string): () => void;
50
+ waitForIdle(): Promise<void>;
51
+ requestExit(code: number): void;
52
+ readonly exitCode: number;
53
+ teardownResource(module: string, kind: string, name: string): Promise<void>;
54
+ registerChildManifest(parentKey: string, resource: ResourceManifest): void;
55
+ getSourceFiles(): string[];
56
+ reloadSource(sourcePath: string): Promise<void>;
57
+ shutdown(): void;
58
+ registerModuleContext(moduleName: string, variables: Record<string, unknown>, secrets: Record<string, unknown>): void;
59
+ getModuleContext(moduleName: string): ModuleContext;
60
+ }
61
+ export declare class RuntimeError extends Error {
62
+ code: RuntimeErrorCode;
63
+ constructor(code: RuntimeErrorCode, message: string);
64
+ }
65
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ export class RuntimeError extends Error {
2
+ constructor(code, message) {
3
+ super(message);
4
+ this.code = code;
5
+ this.name = "RuntimeError";
6
+ }
7
+ }
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA0FA,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YACS,IAAsB,EAC7B,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,SAAI,GAAJ,IAAI,CAAkB;QAI7B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@telorun/kernel",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "description": "Telo Runtime - A lightweight, polyglot execution host.",
5
5
  "keywords": [
6
- "digly",
6
+ "telo",
7
7
  "runtime",
8
8
  "execution",
9
9
  "manifest"
@@ -47,8 +47,8 @@
47
47
  "dependencies": {
48
48
  "@marcbachmann/cel-js": "^7.5.3",
49
49
  "@sinclair/typebox": "^0.34.48",
50
- "@telorun/analyzer": "0.10.1",
51
- "@telorun/sdk": "0.11.1",
50
+ "@telorun/analyzer": "0.12.0",
51
+ "@telorun/templating": "0.3.0",
52
52
  "ajv": "^8.17.1",
53
53
  "ajv-formats": "^3.0.1",
54
54
  "minimatch": "^10.2.5",
@@ -60,11 +60,14 @@
60
60
  "typescript": "^5.0.0",
61
61
  "vitest": "^2.1.8"
62
62
  },
63
+ "peerDependencies": {
64
+ "@telorun/sdk": "0.12.0"
65
+ },
63
66
  "overrides": {
64
67
  "@marcbachmann/cel-js": "$@marcbachmann/cel-js",
65
68
  "@sinclair/typebox": "$@sinclair/typebox",
66
69
  "@telorun/analyzer": "$@telorun/analyzer",
67
- "@telorun/sdk": "$@telorun/sdk",
70
+ "@telorun/templating": "$@telorun/templating",
68
71
  "ajv": "$ajv",
69
72
  "ajv-formats": "$ajv-formats",
70
73
  "minimatch": "$minimatch",
@@ -72,7 +75,7 @@
72
75
  "yaml": "$yaml"
73
76
  },
74
77
  "scripts": {
75
- "build": "tsc && node ../../scripts/generate-runtime-deps.mjs .",
78
+ "build": "tsc",
76
79
  "dev": "tsc --watch",
77
80
  "test": "vitest run",
78
81
  "test:watch": "vitest"
@@ -0,0 +1,216 @@
1
+ import { residualEntrySchema } from "@telorun/analyzer";
2
+ import { RuntimeError } from "@telorun/sdk";
3
+ import { SchemaValidator } from "./schema-validator.js";
4
+
5
+ type EntryType = "string" | "integer" | "number" | "boolean" | "object" | "array";
6
+
7
+ interface EnvEntry {
8
+ env: string;
9
+ type: EntryType;
10
+ default?: unknown;
11
+ [key: string]: unknown;
12
+ }
13
+
14
+ export interface EnvResolutionResult {
15
+ variables: Record<string, unknown>;
16
+ secrets: Record<string, unknown>;
17
+ }
18
+
19
+ /**
20
+ * Populate the root Application's `variables` / `secrets` namespaces from
21
+ * host environment variables, per the per-field `env:` mapping declared on
22
+ * each entry.
23
+ *
24
+ * Implements the polyglot env-resolution spec from
25
+ * kernel/nodejs/plans/application-env-variables.md: read the env var, coerce
26
+ * per `entry.type`, validate the coerced value (or the declared default, when
27
+ * the env var is unset) against the entry's residual schema, and aggregate
28
+ * every failure into a single `ERR_MANIFEST_VALIDATION_FAILED` error so all
29
+ * problems surface before any controller initializes.
30
+ *
31
+ * This must run BEFORE any Telo.Import controller initializes — imports may
32
+ * pass `${{ variables.X }}` as their `variables:` inputs, so the root scope
33
+ * has to be populated by the time the import controller evaluates those
34
+ * expressions.
35
+ */
36
+ export function resolveApplicationEnv(
37
+ manifest: Record<string, any>,
38
+ env: Record<string, string | undefined>,
39
+ validator: SchemaValidator,
40
+ ): EnvResolutionResult {
41
+ const errors: string[] = [];
42
+ const variables = resolveBlock(
43
+ manifest.variables ?? {},
44
+ env,
45
+ validator,
46
+ errors,
47
+ false,
48
+ );
49
+ const secrets = resolveBlock(
50
+ manifest.secrets ?? {},
51
+ env,
52
+ validator,
53
+ errors,
54
+ true,
55
+ );
56
+ if (errors.length > 0) {
57
+ throw new RuntimeError(
58
+ "ERR_MANIFEST_VALIDATION_FAILED",
59
+ `Application environment validation failed:\n` +
60
+ errors.map((e) => ` - ${e}`).join("\n"),
61
+ );
62
+ }
63
+ return { variables, secrets };
64
+ }
65
+
66
+ function resolveBlock(
67
+ block: Record<string, EnvEntry> | unknown,
68
+ env: Record<string, string | undefined>,
69
+ validator: SchemaValidator,
70
+ errors: string[],
71
+ isSecret: boolean,
72
+ ): Record<string, unknown> {
73
+ const out: Record<string, unknown> = {};
74
+ if (!block || typeof block !== "object" || Array.isArray(block)) {
75
+ return out;
76
+ }
77
+ for (const [name, entry] of Object.entries(block as Record<string, EnvEntry>)) {
78
+ if (!entry || typeof entry !== "object") continue;
79
+ const envKey = entry.env;
80
+ const raw = env[envKey];
81
+ const residual = residualEntrySchema(entry as Record<string, unknown>);
82
+
83
+ if (raw === undefined || raw === null) {
84
+ if (entry.default !== undefined) {
85
+ const validation = validateResidual(entry.default, residual, validator);
86
+ if (validation) {
87
+ errors.push(`${name}: ${validation}`);
88
+ } else {
89
+ out[name] = entry.default;
90
+ }
91
+ continue;
92
+ }
93
+ errors.push(`${name}: environment variable ${envKey} is not set (no default)`);
94
+ continue;
95
+ }
96
+
97
+ let coerced: unknown;
98
+ try {
99
+ coerced = coerce(raw, entry.type, envKey, isSecret);
100
+ } catch (e) {
101
+ errors.push(`${name}: ${(e as Error).message}`);
102
+ continue;
103
+ }
104
+
105
+ const validation = validateResidual(coerced, residual, validator);
106
+ if (validation) {
107
+ errors.push(`${name}: ${validation}`);
108
+ continue;
109
+ }
110
+
111
+ out[name] = coerced;
112
+ }
113
+ return out;
114
+ }
115
+
116
+ /** Render a raw env value for inclusion in an error message. Secret values
117
+ * are masked so coercion / schema diagnostics don't leak secret material
118
+ * into logs (the env-var name and the failure reason still surface). */
119
+ function renderRawForError(raw: string, isSecret: boolean): string {
120
+ return isSecret ? "<redacted>" : `"${raw}"`;
121
+ }
122
+
123
+ function coerce(
124
+ raw: string,
125
+ type: EntryType,
126
+ envKey: string,
127
+ isSecret: boolean,
128
+ ): unknown {
129
+ switch (type) {
130
+ case "string":
131
+ return raw;
132
+ case "integer": {
133
+ const trimmed = raw.trim();
134
+ if (!/^-?\d+$/.test(trimmed)) {
135
+ throw new Error(
136
+ `environment variable ${envKey}: value ${renderRawForError(raw, isSecret)} is not a valid integer`,
137
+ );
138
+ }
139
+ return parseInt(trimmed, 10);
140
+ }
141
+ case "number": {
142
+ const n = parseFloat(raw);
143
+ if (Number.isNaN(n)) {
144
+ throw new Error(
145
+ `environment variable ${envKey}: value ${renderRawForError(raw, isSecret)} is not a valid number`,
146
+ );
147
+ }
148
+ return n;
149
+ }
150
+ case "boolean":
151
+ if (raw === "true") return true;
152
+ if (raw === "false") return false;
153
+ throw new Error(
154
+ `environment variable ${envKey}: value ${renderRawForError(raw, isSecret)} is not a valid boolean (expected "true" or "false")`,
155
+ );
156
+ case "object": {
157
+ const parsed = parseJson(raw, envKey, isSecret);
158
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
159
+ throw new Error(
160
+ `environment variable ${envKey}: expected JSON object, got ${describeJsonType(parsed)}`,
161
+ );
162
+ }
163
+ return parsed;
164
+ }
165
+ case "array": {
166
+ const parsed = parseJson(raw, envKey, isSecret);
167
+ if (!Array.isArray(parsed)) {
168
+ throw new Error(
169
+ `environment variable ${envKey}: expected JSON array, got ${describeJsonType(parsed)}`,
170
+ );
171
+ }
172
+ return parsed;
173
+ }
174
+ }
175
+ }
176
+
177
+ function parseJson(raw: string, envKey: string, isSecret: boolean): unknown {
178
+ try {
179
+ return JSON.parse(raw);
180
+ } catch (e) {
181
+ // Node's JSON.parse error embeds the offending character / position; for
182
+ // secrets, swallow the parser detail and surface only the env var name.
183
+ const detail = isSecret ? "value is not valid JSON" : (e as Error).message;
184
+ throw new Error(`environment variable ${envKey}: ${isSecret ? detail : `value is not valid JSON: ${detail}`}`);
185
+ }
186
+ }
187
+
188
+ function describeJsonType(value: unknown): string {
189
+ if (value === null) return "null";
190
+ if (Array.isArray(value)) return "array";
191
+ return typeof value;
192
+ }
193
+
194
+ function validateResidual(
195
+ value: unknown,
196
+ residual: Record<string, unknown>,
197
+ validator: SchemaValidator,
198
+ ): string | null {
199
+ try {
200
+ validator.compile(residual as any).validate(value);
201
+ return null;
202
+ } catch (e) {
203
+ const msg = e instanceof Error ? e.message : String(e);
204
+ // Strip SchemaValidator's "Invalid value passed: <JSON>. Error: " prefix
205
+ // so the JSON-stringified value (which can be secret material for entries
206
+ // under `secrets:`) never reaches the caller. The split is anchored on
207
+ // the literal ". Error: " delimiter — a `[^.]*` regex would have leaked
208
+ // any value containing a dot (URLs, versions, paths).
209
+ const sentinel = ". Error: ";
210
+ const idx = msg.indexOf(sentinel);
211
+ if (msg.startsWith("Invalid value passed:") && idx !== -1) {
212
+ return msg.slice(idx + sentinel.length);
213
+ }
214
+ return msg;
215
+ }
216
+ }