@telorun/kernel 0.2.4 → 0.2.5

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 (135) hide show
  1. package/dist/boot-context-registry.d.ts.map +1 -1
  2. package/dist/boot-context-registry.js +6 -6
  3. package/dist/boot-context-registry.js.map +1 -1
  4. package/dist/capabilities/capabilities/component.yaml +2 -1
  5. package/dist/capabilities/capabilities/executable.yaml +2 -1
  6. package/dist/capabilities/capabilities/handler.yaml +2 -1
  7. package/dist/capabilities/capabilities/listener.yaml +2 -1
  8. package/dist/capabilities/capabilities/provider.yaml +2 -1
  9. package/dist/capabilities/capabilities/template.yaml +2 -1
  10. package/dist/capabilities/capabilities/type.yaml +2 -1
  11. package/dist/capabilities/component.yaml +1 -1
  12. package/dist/capabilities/executable.yaml +1 -1
  13. package/dist/capabilities/handler.yaml +1 -1
  14. package/dist/capabilities/listener.yaml +1 -1
  15. package/dist/capabilities/provider.yaml +1 -1
  16. package/dist/capabilities/template.yaml +1 -1
  17. package/dist/capabilities/type.yaml +1 -1
  18. package/dist/controller-loader.d.ts +1 -1
  19. package/dist/controller-loader.d.ts.map +1 -1
  20. package/dist/controller-loader.js +4 -2
  21. package/dist/controller-loader.js.map +1 -1
  22. package/dist/controller-registry.d.ts +1 -2
  23. package/dist/controller-registry.d.ts.map +1 -1
  24. package/dist/controller-registry.js.map +1 -1
  25. package/dist/controllers/module/import-controller.d.ts +38 -0
  26. package/dist/controllers/module/import-controller.d.ts.map +1 -0
  27. package/dist/controllers/module/import-controller.js +119 -0
  28. package/dist/controllers/module/import-controller.js.map +1 -0
  29. package/dist/controllers/module/module-controller.d.ts +57 -11
  30. package/dist/controllers/module/module-controller.d.ts.map +1 -1
  31. package/dist/controllers/module/module-controller.js +46 -82
  32. package/dist/controllers/module/module-controller.js.map +1 -1
  33. package/dist/controllers/resource-definition/resource-definition-controller.d.ts.map +1 -1
  34. package/dist/controllers/resource-definition/resource-definition-controller.js +12 -4
  35. package/dist/controllers/resource-definition/resource-definition-controller.js.map +1 -1
  36. package/dist/evaluation-context.d.ts +91 -0
  37. package/dist/evaluation-context.d.ts.map +1 -0
  38. package/dist/evaluation-context.js +220 -0
  39. package/dist/evaluation-context.js.map +1 -0
  40. package/dist/execution-context.d.ts +13 -0
  41. package/dist/execution-context.d.ts.map +1 -0
  42. package/dist/execution-context.js +14 -0
  43. package/dist/execution-context.js.map +1 -0
  44. package/dist/index.d.ts +0 -3
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +0 -2
  47. package/dist/index.js.map +1 -1
  48. package/dist/kernel.d.ts +23 -31
  49. package/dist/kernel.d.ts.map +1 -1
  50. package/dist/kernel.js +212 -333
  51. package/dist/kernel.js.map +1 -1
  52. package/dist/loader.d.ts +2 -2
  53. package/dist/loader.d.ts.map +1 -1
  54. package/dist/loader.js +29 -9
  55. package/dist/loader.js.map +1 -1
  56. package/dist/manifest-adapters/local-file-adapter.d.ts.map +1 -1
  57. package/dist/manifest-adapters/local-file-adapter.js +21 -12
  58. package/dist/manifest-adapters/local-file-adapter.js.map +1 -1
  59. package/dist/manifest-schemas.d.ts +1 -25
  60. package/dist/manifest-schemas.d.ts.map +1 -1
  61. package/dist/manifest-schemas.js +3 -22
  62. package/dist/manifest-schemas.js.map +1 -1
  63. package/dist/module-context-registry.d.ts +48 -0
  64. package/dist/module-context-registry.d.ts.map +1 -0
  65. package/dist/module-context-registry.js +91 -0
  66. package/dist/module-context-registry.js.map +1 -0
  67. package/dist/module-context.d.ts +31 -0
  68. package/dist/module-context.d.ts.map +1 -0
  69. package/dist/module-context.js +67 -0
  70. package/dist/module-context.js.map +1 -0
  71. package/dist/registry.d.ts +1 -2
  72. package/dist/registry.d.ts.map +1 -1
  73. package/dist/registry.js +3 -3
  74. package/dist/registry.js.map +1 -1
  75. package/dist/resource-context.d.ts +25 -5
  76. package/dist/resource-context.d.ts.map +1 -1
  77. package/dist/resource-context.js +74 -28
  78. package/dist/resource-context.js.map +1 -1
  79. package/dist/schema-valiator.d.ts.map +1 -1
  80. package/dist/schema-valiator.js +3 -1
  81. package/dist/schema-valiator.js.map +1 -1
  82. package/dist/snapshot-serializer.d.ts +1 -2
  83. package/dist/snapshot-serializer.d.ts.map +1 -1
  84. package/dist/snapshot-serializer.js.map +1 -1
  85. package/dist/types.d.ts +3 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/types.js.map +1 -1
  88. package/package.json +9 -6
  89. package/src/boot-context-registry.ts +169 -0
  90. package/src/capabilities/component.yaml +4 -0
  91. package/src/capabilities/executable.yaml +8 -0
  92. package/src/capabilities/handler.yaml +4 -0
  93. package/src/capabilities/listener.yaml +4 -0
  94. package/src/capabilities/provider.yaml +4 -0
  95. package/src/capabilities/template.yaml +4 -0
  96. package/src/capabilities/type.yaml +4 -0
  97. package/src/controller-loader.ts +298 -0
  98. package/src/controller-registry.ts +206 -0
  99. package/src/controllers/capability/capability-controller.ts +41 -0
  100. package/src/controllers/module/import-controller.ts +143 -0
  101. package/src/controllers/module/module-controller.ts +67 -0
  102. package/src/controllers/module/module.json +48 -0
  103. package/src/controllers/resource-definition/resource-definition-controller.ts +87 -0
  104. package/src/controllers/resource-definition/resource-definition.json +18 -0
  105. package/src/event-stream.ts +121 -0
  106. package/src/events.ts +99 -0
  107. package/src/index.ts +7 -0
  108. package/src/kernel.ts +558 -0
  109. package/src/loader.ts +245 -0
  110. package/src/manifest-adapters/http-adapter.ts +35 -0
  111. package/src/manifest-adapters/local-file-adapter.ts +69 -0
  112. package/src/manifest-adapters/manifest-adapter.ts +33 -0
  113. package/src/manifest-adapters/registry-adapter.ts +56 -0
  114. package/src/manifest-schemas.ts +49 -0
  115. package/src/registry.ts +137 -0
  116. package/src/resource-context.ts +266 -0
  117. package/src/resource-uri.ts +200 -0
  118. package/src/schema-valiator.ts +57 -0
  119. package/dist/cli.d.ts +0 -3
  120. package/dist/cli.d.ts.map +0 -1
  121. package/dist/cli.js +0 -109
  122. package/dist/cli.js.map +0 -1
  123. package/dist/expressions.d.ts +0 -20
  124. package/dist/expressions.d.ts.map +0 -1
  125. package/dist/expressions.js +0 -253
  126. package/dist/expressions.js.map +0 -1
  127. package/dist/template-definition.d.ts +0 -38
  128. package/dist/template-definition.d.ts.map +0 -1
  129. package/dist/template-definition.js +0 -26
  130. package/dist/template-definition.js.map +0 -1
  131. package/dist/template-expander.d.ts +0 -19
  132. package/dist/template-expander.d.ts.map +0 -1
  133. package/dist/template-expander.js +0 -425
  134. package/dist/template-expander.js.map +0 -1
  135. /package/{dist/src → src}/controllers/module/module.yaml +0 -0
@@ -0,0 +1,266 @@
1
+ import {
2
+ EvaluationContext,
3
+ ModuleContext,
4
+ NoopValidator,
5
+ ResourceContext,
6
+ RuntimeError,
7
+ RuntimeResource,
8
+ } from "@telorun/sdk";
9
+ import AjvModule from "ajv";
10
+ import addFormats from "ajv-formats";
11
+ import { Kernel } from "./kernel.js";
12
+ import { formatAjvErrors } from "./manifest-schemas.js";
13
+ import { SchemaValidator } from "./schema-valiator.js";
14
+
15
+ const Ajv = AjvModule.default ?? AjvModule;
16
+
17
+ export class ResourceContextImpl implements ResourceContext {
18
+ constructor(
19
+ readonly kernel: Kernel,
20
+ readonly moduleContext: ModuleContext,
21
+ private readonly metadata: Record<string, any>,
22
+ private readonly validator: SchemaValidator = new SchemaValidator(),
23
+ ) {}
24
+
25
+ stdin: NodeJS.ReadableStream = process.stdin;
26
+ stdout: NodeJS.WritableStream = process.stdout;
27
+ stderr: NodeJS.WritableStream = process.stderr;
28
+
29
+ createSchemaValidator(schema: any) {
30
+ if (!schema) {
31
+ return new NoopValidator();
32
+ }
33
+ return this.validator.compile(schema);
34
+ }
35
+
36
+ registerSchema(name: string, schema: object): void {
37
+ this.validator.addSchema(name, schema);
38
+ }
39
+
40
+ lookupSchema(name: string): object | undefined {
41
+ return this.validator.getSchema(name);
42
+ }
43
+
44
+ validateSchema(value: any, schema: any) {
45
+ const ajv = new Ajv();
46
+ addFormats.default(ajv);
47
+ const validate = ajv.compile(
48
+ "type" in schema && typeof schema.type === "string"
49
+ ? schema
50
+ : {
51
+ type: "object",
52
+ properties: schema,
53
+ required: Object.keys(schema),
54
+ additionalProperties: false,
55
+ },
56
+ );
57
+ const isValid = validate(value);
58
+ if (!isValid) {
59
+ throw new RuntimeError(
60
+ "ERR_INVALID_VALUE",
61
+ `[${this.metadata.name}] Invalid value passed: ${JSON.stringify(value)}. Error: ${formatAjvErrors(validate.errors)}`,
62
+ );
63
+ }
64
+ }
65
+
66
+ invoke(kind: string, name: string, ...args: any[]): Promise<any> {
67
+ return this.moduleContext.invoke(kind, name, ...args);
68
+ }
69
+
70
+ async run(name: string) {
71
+ await this.moduleContext.run(name);
72
+ }
73
+
74
+ registerManifest(resource: any): void {
75
+ this.moduleContext.registerManifest(resource);
76
+ }
77
+
78
+ /**
79
+ * Resolves a resource into a normalized {kind, name} reference.
80
+ * If the resource contains a definition (kind + properties), registers it as a manifest.
81
+ * Returns the normalized reference in all cases.
82
+ *
83
+ * @param resource Resource definition or reference object with 'kind' property
84
+ * @param resourceName Optional name to assign if not present in resource
85
+ * @returns Normalized {kind, name} reference
86
+ * @throws RuntimeError if 'kind' is missing
87
+ */
88
+ resolveChildren(resource: any, resourceName?: string): { kind: string; name: string } {
89
+ if (!resource || typeof resource !== "object") {
90
+ throw new RuntimeError(
91
+ "ERR_INVALID_VALUE",
92
+ `[${this.metadata.name}] Resource must be an object. Got: ${typeof resource}`,
93
+ );
94
+ }
95
+
96
+ if (!resource.kind) {
97
+ throw new RuntimeError(
98
+ "ERR_INVALID_VALUE",
99
+ `[${this.metadata.name}] Resource must have 'kind' property. Got: ${JSON.stringify(resource)}`,
100
+ );
101
+ }
102
+
103
+ const kind = resource.kind;
104
+ const name =
105
+ resource.name ??
106
+ resource.metadata?.name ??
107
+ resourceName ??
108
+ `Unnamed${Math.random().toString(16).slice(2, 8)}`;
109
+
110
+ // If resource has properties beyond kind/name, it's a definition - register it
111
+ const definitionKeys = Object.keys(resource).filter(
112
+ (k) => k !== "kind" && k !== "name" && k !== "metadata",
113
+ );
114
+
115
+ if (definitionKeys.length > 0) {
116
+ this.registerManifest({
117
+ ...resource,
118
+ metadata: {
119
+ name,
120
+ module: this.metadata.module,
121
+ ...resource.metadata,
122
+ },
123
+ });
124
+ }
125
+
126
+ return { kind, name };
127
+ }
128
+
129
+ teardownResource(kind: string, name: string): Promise<void> {
130
+ throw new Error("Method teardownResource not implemented.");
131
+ // const parts = kind.split(".");
132
+ // if (parts.length > 2) {
133
+ // return this.kernel.teardownResource(parts[0], parts.slice(1).join("."), name);
134
+ // }
135
+ // return this.kernel.teardownResource(this.metadata.module, kind, name);
136
+ }
137
+
138
+ getResources(kind: string): RuntimeResource[] {
139
+ throw new Error("Method teardownResource not implemented.");
140
+ // return this.kernel.getResourcesByKind(kind);
141
+ }
142
+
143
+ getResourcesByName(_kind: string, name: string): RuntimeResource | null {
144
+ const entry = this.moduleContext.resourceInstances.get(name);
145
+ return (entry?.resource ?? null) as RuntimeResource | null;
146
+ }
147
+
148
+ async registerController(
149
+ moduleName: string,
150
+ kindName: string,
151
+ controllerInstance: any,
152
+ ): Promise<void> {
153
+ await this.kernel.registerController(moduleName, kindName, controllerInstance);
154
+ }
155
+
156
+ registerDefinition(def: any) {
157
+ this.kernel.registerResourceDefinition(def);
158
+ }
159
+
160
+ registerCapability(name: string, schema?: Record<string, any>): void {
161
+ this.kernel.registerCapability(name, schema);
162
+ }
163
+
164
+ isCapabilityRegistered(name: string): boolean {
165
+ return this.kernel.isCapabilityRegistered(name);
166
+ }
167
+
168
+ getCapabilitySchema(name: string): Record<string, any> | null | undefined {
169
+ return this.kernel.getCapabilitySchema(name);
170
+ }
171
+
172
+ on(event: string, handler: (payload?: any) => void | Promise<void>): void {
173
+ this.kernel.on(event, handler);
174
+ }
175
+
176
+ once(event: string, handler: (payload?: any) => void | Promise<void>): void {
177
+ throw new Error("Method once not implemented.");
178
+ }
179
+
180
+ off(event: string, handler: (payload?: any) => void | Promise<void>): void {
181
+ throw new Error("Method off not implemented.");
182
+ }
183
+
184
+ async emit(event: string, payload?: any) {
185
+ await this.kernel.emitRuntimeEvent(`${this.metadata.name}.${event}`, payload);
186
+ }
187
+
188
+ acquireHold(reason?: string): () => void {
189
+ return this.kernel.acquireHold(reason);
190
+ }
191
+
192
+ requestExit(code: number): void {
193
+ this.kernel.requestExit(code);
194
+ }
195
+
196
+ evaluateCel(expression: string, context: Record<string, any>): unknown {
197
+ return new EvaluationContext(
198
+ this.moduleContext.source,
199
+ context,
200
+ undefined,
201
+ new Set(),
202
+ this.emit,
203
+ ).evaluate(expression);
204
+ }
205
+
206
+ expandValue(value: any, context: Record<string, any>) {
207
+ return this.moduleContext.merge(context).expand(value);
208
+ }
209
+
210
+ async emitEvent(event: string, payload?: any) {
211
+ await this.kernel.emitRuntimeEvent(event, payload);
212
+ }
213
+
214
+ registerModuleImport(alias: string, targetModule: string, kinds: string[]): void {
215
+ const declaringModule = (this.metadata as any).module as string | undefined;
216
+ this.kernel.registerModuleImport(declaringModule ?? "", alias, targetModule, kinds);
217
+ }
218
+
219
+ resolveModuleAlias(declaringModule: string, alias: string): string | undefined {
220
+ return this.kernel.resolveModuleAlias(declaringModule, alias);
221
+ }
222
+
223
+ getModuleContext(moduleName: string): ModuleContext {
224
+ return this.kernel.getModuleContext(moduleName);
225
+ }
226
+
227
+ /**
228
+ * Create a child EvaluationContext attached to the current module context.
229
+ * Queue resources on the returned context with pendingResources.push(), then
230
+ * call initializeChildContext() to initialize them in isolation.
231
+ */
232
+ spawnChildContext(): EvaluationContext {
233
+ const child = new EvaluationContext(
234
+ this.moduleContext.source,
235
+ this.moduleContext.context,
236
+ this.moduleContext.createInstance,
237
+ this.moduleContext.secretValues,
238
+ this.moduleContext.emit,
239
+ );
240
+ return this.moduleContext.spawnChild(child);
241
+ }
242
+
243
+ /**
244
+ * Create a temporary child context, queue manifests on it, run a function,
245
+ * then tear down the child context and its resources.
246
+ * Note: This always returns a Promise even though the interface signature
247
+ * suggests T. The callback can be sync or async (passed as async function).
248
+ */
249
+ withManifests<T>(manifests: any[], fn: () => T): T {
250
+ const child = this.spawnChildContext();
251
+ // Return a Promise cast as T - callers will use await
252
+ return (async () => {
253
+ try {
254
+ for (const manifest of manifests || []) {
255
+ if (manifest) {
256
+ child.registerManifest(manifest);
257
+ }
258
+ }
259
+ await child.initializeResources();
260
+ return await Promise.resolve(fn() as any);
261
+ } finally {
262
+ await this.kernel.teardownContext(child);
263
+ }
264
+ })() as unknown as T;
265
+ }
266
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * ResourceURI: Parses and builds standard URIs for resources
3
+ *
4
+ * Format: scheme://host/path#kind.name[/kind.child/kind.child/...]
5
+ * Examples:
6
+ * file:///path/to/file.yaml#Http.Server.Example
7
+ * http://localhost/template/ApiServer#Http.Server/api-us-east
8
+ * https://example.com/resources.yaml#Data.Type.User
9
+ */
10
+ export class ResourceURI {
11
+ readonly scheme: string;
12
+ readonly host: string;
13
+ readonly path: string;
14
+ readonly fragment: string; // kind.name/kind.child/...
15
+
16
+ private constructor(
17
+ scheme: string,
18
+ host: string,
19
+ path: string,
20
+ fragment: string,
21
+ ) {
22
+ this.scheme = scheme;
23
+ this.host = host;
24
+ this.path = path;
25
+ this.fragment = fragment;
26
+ }
27
+
28
+ /**
29
+ * Parse a URI string into components
30
+ * Format: scheme://host/path#fragment
31
+ */
32
+ static parse(uri: string): ResourceURI {
33
+ const schemeMatch = uri.match(/^([a-z][a-z0-9+.-]*):\/\//);
34
+ if (!schemeMatch) {
35
+ throw new Error(
36
+ `Invalid URI format: ${uri}. Expected "scheme://host/path#fragment"`,
37
+ );
38
+ }
39
+
40
+ const scheme = schemeMatch[1];
41
+ const rest = uri.slice(schemeMatch[0].length);
42
+
43
+ // Split host/path from fragment
44
+ const hashIndex = rest.indexOf('#');
45
+ if (hashIndex === -1) {
46
+ throw new Error(`Invalid URI format: ${uri}. Missing fragment after "#"`);
47
+ }
48
+
49
+ const hostPath = rest.slice(0, hashIndex);
50
+ const fragment = rest.slice(hashIndex + 1);
51
+
52
+ if (!fragment) {
53
+ throw new Error(`Invalid URI format: ${uri}. Fragment cannot be empty`);
54
+ }
55
+
56
+ // Split host from path
57
+ const pathIndex = hostPath.indexOf('/');
58
+ let host: string;
59
+ let path: string;
60
+
61
+ if (pathIndex === -1) {
62
+ host = hostPath;
63
+ path = '';
64
+ } else {
65
+ host = hostPath.slice(0, pathIndex);
66
+ path = hostPath.slice(pathIndex);
67
+ }
68
+
69
+ if (!host) {
70
+ throw new Error(`Invalid URI format: ${uri}. Host cannot be empty`);
71
+ }
72
+
73
+ return new ResourceURI(scheme, host, path, fragment);
74
+ }
75
+
76
+ /**
77
+ * Build a file:// URI from an absolute file path and kind.name
78
+ */
79
+ static fromFile(
80
+ absolutePath: string,
81
+ kind: string,
82
+ name: string,
83
+ ): ResourceURI {
84
+ const normalizedPath = absolutePath.replace(/\\/g, '/');
85
+ const fragment = `${kind}.${name}`;
86
+ return new ResourceURI('file', 'localhost', normalizedPath, fragment);
87
+ }
88
+
89
+ /**
90
+ * Build a template URI from template definition name and kind.name
91
+ * Used for resources generated by template expansion
92
+ */
93
+ static fromTemplate(
94
+ templateDefinitionName: string,
95
+ kind: string,
96
+ resourceId: string,
97
+ ): ResourceURI {
98
+ const path = `/template/${templateDefinitionName}`;
99
+ const fragment = `${kind}.${resourceId}`;
100
+ return new ResourceURI('http', 'localhost', path, fragment);
101
+ }
102
+
103
+ /**
104
+ * Create a child URI by appending kind.name to the fragment path
105
+ * Used when a template generates child resources
106
+ */
107
+ withChild(kind: string, name: string): ResourceURI {
108
+ const newFragment = `${this.fragment}/${kind}.${name}`;
109
+ return new ResourceURI(this.scheme, this.host, this.path, newFragment);
110
+ }
111
+
112
+ /**
113
+ * Get the full URI as a string
114
+ */
115
+ toString(): string {
116
+ return `${this.scheme}://${this.host}${this.path}#${this.fragment}`;
117
+ }
118
+
119
+ /**
120
+ * Get just the resource identifier part (kind.name)
121
+ */
122
+ getResourceId(): string {
123
+ const parts = this.fragment.split('/');
124
+ return parts[parts.length - 1];
125
+ }
126
+
127
+ /**
128
+ * Get the kind and name from the last fragment component
129
+ */
130
+ getResourceKindName(): { kind: string; name: string } {
131
+ const resourceId = this.getResourceId();
132
+ const lastDot = resourceId.lastIndexOf('.');
133
+ if (lastDot === -1) {
134
+ throw new Error(`Invalid resource identifier in URI: ${this.toString()}`);
135
+ }
136
+ return {
137
+ kind: resourceId.slice(0, lastDot),
138
+ name: resourceId.slice(lastDot + 1),
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Get the full fragment path as array of kind.name pairs
144
+ */
145
+ getFragmentPath(): string[] {
146
+ return this.fragment.split('/');
147
+ }
148
+
149
+ /**
150
+ * Check if this URI is from a file source
151
+ */
152
+ isFileSource(): boolean {
153
+ return this.scheme === 'file';
154
+ }
155
+
156
+ /**
157
+ * Check if this URI is from a template source
158
+ */
159
+ isTemplateSource(): boolean {
160
+ return this.scheme === 'http' && this.path.startsWith('/template/');
161
+ }
162
+
163
+ /**
164
+ * Check if this URI represents a generated/nested resource (has multiple fragment components)
165
+ */
166
+ isNested(): boolean {
167
+ return this.fragment.includes('/');
168
+ }
169
+
170
+ /**
171
+ * Get the depth of nesting (number of / in fragment)
172
+ */
173
+ getDepth(): number {
174
+ return this.fragment.split('/').length - 1;
175
+ }
176
+
177
+ /**
178
+ * Get the parent URI by removing the last fragment component
179
+ * Returns undefined if already at root level
180
+ */
181
+ getParent(): ResourceURI | undefined {
182
+ const parts = this.fragment.split('/');
183
+ if (parts.length === 1) {
184
+ return undefined;
185
+ }
186
+ const parentFragment = parts.slice(0, -1).join('/');
187
+ return new ResourceURI(this.scheme, this.host, this.path, parentFragment);
188
+ }
189
+
190
+ /**
191
+ * Get template name if this is a template-generated resource
192
+ */
193
+ getTemplateName(): string | undefined {
194
+ if (!this.isTemplateSource()) {
195
+ return undefined;
196
+ }
197
+ const match = this.path.match(/^\/template\/(.+)$/);
198
+ return match ? match[1] : undefined;
199
+ }
200
+ }
@@ -0,0 +1,57 @@
1
+ import { DataValidator, RuntimeError } from "@telorun/sdk";
2
+ import AjvModule from "ajv";
3
+ import addFormats from "ajv-formats";
4
+ import { formatAjvErrors } from "./manifest-schemas.js";
5
+
6
+ const Ajv = AjvModule.default ?? AjvModule;
7
+
8
+ export class SchemaValidator {
9
+ private ajv: InstanceType<typeof Ajv>;
10
+
11
+ constructor() {
12
+ this.ajv = new Ajv({
13
+ strict: false,
14
+ removeAdditional: false,
15
+ useDefaults: true,
16
+ });
17
+ addFormats.default(this.ajv);
18
+ }
19
+
20
+ addSchema(name: string, schema: object): void {
21
+ if (!this.ajv.getSchema(name)) {
22
+ this.ajv.addSchema(schema, name);
23
+ }
24
+ }
25
+
26
+ getSchema(name: string): object | undefined {
27
+ return this.ajv.getSchema(name) as object | undefined;
28
+ }
29
+
30
+ compile(schema: any): DataValidator {
31
+ const validate = this.ajv.compile(
32
+ "type" in schema && typeof schema.type === "string"
33
+ ? schema
34
+ : {
35
+ type: "object",
36
+ properties: schema,
37
+ required: Object.keys(schema),
38
+ additionalProperties: false,
39
+ },
40
+ );
41
+
42
+ return {
43
+ validate: (data: any) => {
44
+ const isValid = validate(data);
45
+ if (!isValid) {
46
+ throw new RuntimeError(
47
+ "ERR_RESOURCE_NOT_FOUND",
48
+ `Invalid value passed: ${JSON.stringify(data)}. Error: ${formatAjvErrors(validate.errors)}`,
49
+ );
50
+ }
51
+ },
52
+ isValid: (data: any) => {
53
+ return validate(data);
54
+ },
55
+ };
56
+ }
57
+ }
package/dist/cli.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js DELETED
@@ -1,109 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- Object.defineProperty(exports, "__esModule", { value: true });
37
- const fs = __importStar(require("fs/promises"));
38
- const path = __importStar(require("path"));
39
- const kernel_1 = require("./kernel");
40
- async function main() {
41
- const args = process.argv.slice(2);
42
- const verbose = args.includes('--verbose');
43
- const debug = args.includes('--debug');
44
- const snapshotOnExit = args.includes('--snapshot-on-exit');
45
- const filteredArgs = args.filter((arg) => arg !== '--verbose' && arg !== '--debug' && arg !== '--snapshot-on-exit');
46
- if (filteredArgs.length === 0) {
47
- console.error('Usage: digly [--verbose] [--debug] [--snapshot-on-exit] <runtime.yaml|directory>');
48
- console.error('Example: digly --verbose --debug ./runtime.yaml');
49
- process.exit(1);
50
- }
51
- const inputPath = path.resolve(filteredArgs[0]);
52
- let inputStat;
53
- try {
54
- inputStat = await fs.stat(inputPath);
55
- }
56
- catch (error) {
57
- const message = error instanceof Error ? error.message : String(error);
58
- console.error(`Error reading path: ${inputPath}: ${message}`);
59
- process.exit(1);
60
- }
61
- const isDirectory = inputStat.isDirectory();
62
- const log = createLogger(verbose);
63
- // log.info(`Digly Runtime v1.0`);
64
- // log.info(`Loading from: ${inputPath}`);
65
- try {
66
- const kernel = new kernel_1.Kernel();
67
- if (verbose) {
68
- kernel.on('*', (event) => {
69
- log.info(`${event.name}: ${JSON.stringify(event.payload)}`);
70
- });
71
- }
72
- // Enable event streaming if debug flag is set
73
- if (debug) {
74
- const debugDir = path.join(process.cwd(), '.digly-debug');
75
- const eventStreamPath = path.join(debugDir, 'events.jsonl');
76
- await kernel.enableEventStream(eventStreamPath);
77
- log.info(`Event stream enabled: ${eventStreamPath}`);
78
- }
79
- // Load from manifest or directory
80
- if (isDirectory) {
81
- await kernel.loadDirectory(inputPath);
82
- }
83
- else {
84
- await kernel.loadFromConfig(inputPath);
85
- }
86
- await kernel.start();
87
- }
88
- catch (error) {
89
- console.error('Error loading runtime:', error instanceof Error ? error.stack : String(error));
90
- process.exit(1);
91
- }
92
- }
93
- function createLogger(verbose) {
94
- const useColor = process.stdout.isTTY;
95
- const wrap = (code, text) => useColor ? `\x1b[${code}m${text}\x1b[0m` : text;
96
- return {
97
- info: (...args) => console.log(...args),
98
- ok: (text) => wrap('32', text),
99
- warn: (text) => wrap('33', text),
100
- error: (text) => wrap('31', text),
101
- dim: (text) => wrap('2', text),
102
- verbose,
103
- };
104
- }
105
- main().catch((error) => {
106
- console.error('Fatal error:', error);
107
- process.exit(1);
108
- });
109
- //# sourceMappingURL=cli.js.map
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,gDAAkC;AAClC,2CAA6B;AAC7B,qCAAkC;AAElC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAE3D,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,oBAAoB,CAC3E,CAAC;IAEF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CACX,kFAAkF,CACnF,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,SAA8C,CAAC;IACnD,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,uBAAuB,SAAS,KAAK,OAAO,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAElC,kCAAkC;IAClC,0CAA0C;IAE1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAM,EAAE,CAAC;QAC5B,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,8CAA8C;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;YAC1D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,MAAM,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,yBAAyB,eAAe,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,kCAAkC;QAClC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,wBAAwB,EACxB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACrD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,OAAgB;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CAC1C,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,OAAO;QACL,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAC9C,EAAE,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACtC,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACxC,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACzC,GAAG,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;QACtC,OAAO;KACR,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1,20 +0,0 @@
1
- import { RuntimeResource } from "@telorun/sdk";
2
- import type { ResourceManifest } from "./types.js";
3
- export declare function evaluateCel(expression: string, context: Record<string, any>): unknown;
4
- export declare function expandValue(value: any, context: Record<string, any>): any;
5
- export declare function resolveExpressionsInRegistry(registry: Map<string, Map<string, RuntimeResource>>, runtimeConfig: ResourceManifest | null): void;
6
- /**
7
- * Resolve all non-deferred CEL expressions in a resource manifest using the
8
- * provided boot context. Expressions referencing `request.*` or `result.*` are
9
- * left untouched — they will be resolved at request time by the runtime.
10
- *
11
- * Missing identifiers that are not deferred prefixes will throw, which is
12
- * intentional: if a consumer's manifest references a boot-context identifier
13
- * that is absent from the context, it is a configuration error.
14
- *
15
- * @param manifest - The raw (pre-creation) ResourceManifest
16
- * @param context - CEL evaluation context built by BootContextRegistry.buildContext()
17
- * @returns A new manifest object with all resolvable `${{ }}` templates replaced
18
- */
19
- export declare function resolveManifestWithContext(manifest: ResourceManifest, context: Record<string, any>): ResourceManifest;
20
- //# sourceMappingURL=expressions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"expressions.d.ts","sourceRoot":"","sources":["../src/expressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAOnD,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAErF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAezE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,EACnD,aAAa,EAAE,gBAAgB,GAAG,IAAI,GACrC,IAAI,CAuBN;AAsND;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,gBAAgB,CAOlB"}