@telorun/analyzer 0.4.0 → 0.5.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.
- package/README.md +0 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/manifest-loader.d.ts +5 -5
- package/dist/manifest-loader.d.ts.map +1 -1
- package/dist/manifest-loader.js +35 -35
- package/dist/{adapters/http-adapter.d.ts → sources/http-source.d.ts} +3 -3
- package/dist/sources/http-source.d.ts.map +1 -0
- package/dist/{adapters/http-adapter.js → sources/http-source.js} +1 -1
- package/dist/{adapters/registry-adapter.d.ts → sources/registry-source.d.ts} +3 -3
- package/dist/sources/registry-source.d.ts.map +1 -0
- package/dist/{adapters/registry-adapter.js → sources/registry-source.js} +1 -1
- package/dist/types.d.ts +10 -10
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +7 -4
- package/src/manifest-loader.ts +34 -34
- package/src/{adapters/http-adapter.ts → sources/http-source.ts} +2 -2
- package/src/{adapters/registry-adapter.ts → sources/registry-source.ts} +2 -2
- package/src/types.ts +10 -10
- package/dist/adapters/http-adapter.d.ts.map +0 -1
- package/dist/adapters/registry-adapter.d.ts.map +0 -1
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { HttpAdapter } from "./adapters/http-adapter.js";
|
|
2
|
-
export { RegistryAdapter } from "./adapters/registry-adapter.js";
|
|
3
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
4
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
5
3
|
export { Loader } from "./manifest-loader.js";
|
|
6
|
-
export {
|
|
4
|
+
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
7
5
|
export type { ModuleKind } from "./module-kinds.js";
|
|
6
|
+
export { HttpSource } from "./sources/http-source.js";
|
|
7
|
+
export { RegistrySource } from "./sources/registry-source.js";
|
|
8
8
|
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
|
9
|
-
export type { AnalysisDiagnostic, AnalysisOptions, LoaderInitOptions, LoadOptions,
|
|
9
|
+
export type { AnalysisDiagnostic, AnalysisOptions, LoaderInitOptions, LoadOptions, ManifestSource, Position, PositionIndex, Range } from "./types.js";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { HttpAdapter } from "./adapters/http-adapter.js";
|
|
2
|
-
export { RegistryAdapter } from "./adapters/registry-adapter.js";
|
|
3
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
4
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
5
3
|
export { Loader } from "./manifest-loader.js";
|
|
6
|
-
export {
|
|
4
|
+
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
5
|
+
export { HttpSource } from "./sources/http-source.js";
|
|
6
|
+
export { RegistrySource } from "./sources/registry-source.js";
|
|
7
7
|
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type ResourceManifest } from "@telorun/sdk";
|
|
2
|
-
import { type LoadOptions, type LoaderInitOptions, type
|
|
2
|
+
import { type LoadOptions, type LoaderInitOptions, type ManifestSource } from "./types.js";
|
|
3
3
|
export declare class Loader {
|
|
4
|
-
private
|
|
5
|
-
protected
|
|
4
|
+
private readonly moduleCache;
|
|
5
|
+
protected sources: ManifestSource[];
|
|
6
6
|
private readonly celEnv;
|
|
7
|
-
constructor(
|
|
8
|
-
register(
|
|
7
|
+
constructor(extraSourcesOrOptions?: ManifestSource[] | LoaderInitOptions);
|
|
8
|
+
register(source: ManifestSource): this;
|
|
9
9
|
private pick;
|
|
10
10
|
resolveEntryPoint(url: string): Promise<string>;
|
|
11
11
|
loadModule(url: string, options?: LoadOptions): Promise<ResourceManifest[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOtE,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,
|
|
1
|
+
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOtE,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,YAAY,CAAC;AASpB,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IAEJ,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,qBAAqB,GAAE,cAAc,EAAE,GAAG,iBAAsB;IAmB5E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAqGnE,eAAe;YAoBf,eAAe;IAgEvB,iBAAiB,CACrB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,gBAAgB,EAAE,CAAC;QAC9B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;KAClD,GAAG,IAAI,CAAC;IAiCH,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAC5C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAsCrC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CA2GnE"}
|
package/dist/manifest-loader.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isCompiledValue } from "@telorun/sdk";
|
|
2
2
|
import { isMap, isPair, isScalar, isSeq, parseAllDocuments } from "yaml";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { HttpSource } from "./sources/http-source.js";
|
|
4
|
+
import { RegistrySource } from "./sources/registry-source.js";
|
|
5
5
|
import { buildCelEnvironment } from "./cel-environment.js";
|
|
6
6
|
import { isModuleKind } from "./module-kinds.js";
|
|
7
7
|
import { precompileDoc } from "./precompile.js";
|
|
@@ -13,34 +13,34 @@ const SYSTEM_KINDS = new Set([
|
|
|
13
13
|
"Telo.Definition",
|
|
14
14
|
]);
|
|
15
15
|
export class Loader {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
moduleCache = new Map();
|
|
17
|
+
sources;
|
|
18
18
|
celEnv;
|
|
19
|
-
constructor(
|
|
20
|
-
const options = Array.isArray(
|
|
21
|
-
? {
|
|
22
|
-
:
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
this.
|
|
26
|
-
if (
|
|
27
|
-
this.
|
|
28
|
-
if (
|
|
29
|
-
this.
|
|
30
|
-
if (options.
|
|
31
|
-
this.
|
|
19
|
+
constructor(extraSourcesOrOptions = []) {
|
|
20
|
+
const options = Array.isArray(extraSourcesOrOptions)
|
|
21
|
+
? { extraSources: extraSourcesOrOptions }
|
|
22
|
+
: extraSourcesOrOptions;
|
|
23
|
+
const includeHttpSource = options.includeHttpSource ?? true;
|
|
24
|
+
const includeRegistrySource = options.includeRegistrySource ?? true;
|
|
25
|
+
this.sources = [];
|
|
26
|
+
if (includeHttpSource)
|
|
27
|
+
this.sources.push(new HttpSource());
|
|
28
|
+
if (includeRegistrySource)
|
|
29
|
+
this.sources.push(new RegistrySource(options.registryUrl));
|
|
30
|
+
if (options.extraSources?.length) {
|
|
31
|
+
this.sources.unshift(...options.extraSources);
|
|
32
32
|
}
|
|
33
33
|
this.celEnv = buildCelEnvironment(options.celHandlers);
|
|
34
34
|
}
|
|
35
|
-
register(
|
|
36
|
-
this.
|
|
35
|
+
register(source) {
|
|
36
|
+
this.sources.unshift(source);
|
|
37
37
|
return this;
|
|
38
38
|
}
|
|
39
39
|
pick(url) {
|
|
40
|
-
const
|
|
41
|
-
if (!
|
|
42
|
-
throw new Error(`No
|
|
43
|
-
return
|
|
40
|
+
const s = this.sources.find((s) => s.supports(url));
|
|
41
|
+
if (!s)
|
|
42
|
+
throw new Error(`No source found for: ${url}`);
|
|
43
|
+
return s;
|
|
44
44
|
}
|
|
45
45
|
async resolveEntryPoint(url) {
|
|
46
46
|
const { source } = await this.pick(url).read(url);
|
|
@@ -49,7 +49,7 @@ export class Loader {
|
|
|
49
49
|
async loadModule(url, options) {
|
|
50
50
|
const { text, source } = await this.pick(url).read(url);
|
|
51
51
|
const cacheKey = `${options?.compile ? "compiled" : "raw"}:${source}`;
|
|
52
|
-
const cached =
|
|
52
|
+
const cached = this.moduleCache.get(cacheKey);
|
|
53
53
|
if (cached && cached.text === text) {
|
|
54
54
|
return cloneManifestArray(cached.manifests);
|
|
55
55
|
}
|
|
@@ -126,8 +126,8 @@ export class Loader {
|
|
|
126
126
|
const includePatterns = moduleManifest.include;
|
|
127
127
|
if (includePatterns?.length) {
|
|
128
128
|
hasIncludes = true;
|
|
129
|
-
const
|
|
130
|
-
const includedFiles = await this.resolveIncludes(source, includePatterns,
|
|
129
|
+
const picked = this.pick(source);
|
|
130
|
+
const includedFiles = await this.resolveIncludes(source, includePatterns, picked);
|
|
131
131
|
for (const includedUrl of includedFiles) {
|
|
132
132
|
const partialManifests = await this.loadPartialFile(includedUrl, moduleName, options);
|
|
133
133
|
resolved.push(...partialManifests);
|
|
@@ -135,22 +135,22 @@ export class Loader {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
if (!hasIncludes) {
|
|
138
|
-
|
|
138
|
+
this.moduleCache.set(cacheKey, { text, manifests: resolved });
|
|
139
139
|
}
|
|
140
140
|
return cloneManifestArray(resolved);
|
|
141
141
|
}
|
|
142
|
-
async resolveIncludes(ownerSource, patterns,
|
|
142
|
+
async resolveIncludes(ownerSource, patterns, source) {
|
|
143
143
|
const hasGlobs = patterns.some((p) => /[*?{}\[\]]/.test(p));
|
|
144
144
|
if (hasGlobs) {
|
|
145
|
-
if (!
|
|
146
|
-
throw new Error(`Include patterns in '${ownerSource}' contain globs but the
|
|
145
|
+
if (!source.expandGlob) {
|
|
146
|
+
throw new Error(`Include patterns in '${ownerSource}' contain globs but the source for this URL ` +
|
|
147
147
|
`does not support glob expansion. Use explicit file paths instead of patterns like: ` +
|
|
148
148
|
patterns.filter((p) => /[*?{}\[\]]/.test(p)).join(", "));
|
|
149
149
|
}
|
|
150
|
-
return
|
|
150
|
+
return source.expandGlob(ownerSource, patterns);
|
|
151
151
|
}
|
|
152
152
|
// Literal relative paths — deduplicate in case the same file appears under multiple patterns.
|
|
153
|
-
return [...new Set(patterns.map((p) =>
|
|
153
|
+
return [...new Set(patterns.map((p) => source.resolveRelative(ownerSource, p)))];
|
|
154
154
|
}
|
|
155
155
|
async loadPartialFile(url, ownerModuleName, options) {
|
|
156
156
|
const { text, source } = await this.pick(url).read(url);
|
|
@@ -228,10 +228,10 @@ export class Loader {
|
|
|
228
228
|
// Otherwise fall through to owner lookup — this is likely a partial file
|
|
229
229
|
}
|
|
230
230
|
// Find the owning telo.yaml via parent-directory traversal
|
|
231
|
-
const
|
|
232
|
-
if (!
|
|
231
|
+
const source = this.pick(fileUrl);
|
|
232
|
+
if (!source.resolveOwnerOf)
|
|
233
233
|
return null;
|
|
234
|
-
const ownerUrl = await
|
|
234
|
+
const ownerUrl = await source.resolveOwnerOf(fileUrl);
|
|
235
235
|
if (!ownerUrl)
|
|
236
236
|
return null;
|
|
237
237
|
// Load the owner module (which will load included files via include expansion)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export declare class
|
|
1
|
+
import { type ManifestSource } from "../types.js";
|
|
2
|
+
export declare class HttpSource implements ManifestSource {
|
|
3
3
|
supports(url: string): boolean;
|
|
4
4
|
read(url: string): Promise<{
|
|
5
5
|
text: string;
|
|
@@ -7,4 +7,4 @@ export declare class HttpAdapter implements ManifestAdapter {
|
|
|
7
7
|
}>;
|
|
8
8
|
resolveRelative(base: string, relative: string): string;
|
|
9
9
|
}
|
|
10
|
-
//# sourceMappingURL=http-
|
|
10
|
+
//# sourceMappingURL=http-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-source.d.ts","sourceRoot":"","sources":["../../src/sources/http-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7E,qBAAa,UAAW,YAAW,cAAc;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWlE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAIxD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export declare class
|
|
1
|
+
import { type ManifestSource } from "../types.js";
|
|
2
|
+
export declare class RegistrySource implements ManifestSource {
|
|
3
3
|
private registryUrl;
|
|
4
4
|
constructor(registryUrl?: string);
|
|
5
5
|
supports(url: string): boolean;
|
|
@@ -12,4 +12,4 @@ export declare class RegistryAdapter implements ManifestAdapter {
|
|
|
12
12
|
private toRegistryUrl;
|
|
13
13
|
private parseModuleRef;
|
|
14
14
|
}
|
|
15
|
-
//# sourceMappingURL=registry-
|
|
15
|
+
//# sourceMappingURL=registry-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-source.d.ts","sourceRoot":"","sources":["../../src/sources/registry-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAI7E,qBAAa,cAAe,YAAW,cAAc;IACvC,OAAO,CAAC,WAAW;gBAAX,WAAW,SAAuB;IAEtD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWxB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWxE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMvD,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;CAmBvB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_MANIFEST_FILENAME } from "../types.js";
|
|
2
2
|
const DEFAULT_REGISTRY_URL = "https://registry.telo.run";
|
|
3
|
-
export class
|
|
3
|
+
export class RegistrySource {
|
|
4
4
|
registryUrl;
|
|
5
5
|
constructor(registryUrl = DEFAULT_REGISTRY_URL) {
|
|
6
6
|
this.registryUrl = registryUrl;
|
package/dist/types.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface AnalysisDiagnostic {
|
|
|
35
35
|
/** Telo-specific extras such as { resource: { kind, name }, path } */
|
|
36
36
|
data?: unknown;
|
|
37
37
|
}
|
|
38
|
-
export interface
|
|
38
|
+
export interface ManifestSource {
|
|
39
39
|
supports(url: string): boolean;
|
|
40
40
|
read(url: string): Promise<{
|
|
41
41
|
text: string;
|
|
@@ -44,11 +44,11 @@ export interface ManifestAdapter {
|
|
|
44
44
|
resolveRelative(base: string, relative: string): string;
|
|
45
45
|
/** Expand glob patterns relative to a base source. Returns sources in the same
|
|
46
46
|
* format as read().source — suitable to pass back into read() / resolveRelative().
|
|
47
|
-
* Optional — only filesystem-capable
|
|
47
|
+
* Optional — only filesystem-capable sources implement this. */
|
|
48
48
|
expandGlob?(base: string, patterns: string[]): Promise<string[]>;
|
|
49
49
|
/** Walk parent directories from fileUrl looking for the nearest telo.yaml.
|
|
50
50
|
* Returns the source in the same format as read().source, or null if none found.
|
|
51
|
-
* Optional — only filesystem-capable
|
|
51
|
+
* Optional — only filesystem-capable sources implement this. */
|
|
52
52
|
resolveOwnerOf?(fileUrl: string): Promise<string | null>;
|
|
53
53
|
}
|
|
54
54
|
export interface LoadOptions {
|
|
@@ -59,13 +59,13 @@ export interface LoadOptions {
|
|
|
59
59
|
compile?: boolean;
|
|
60
60
|
}
|
|
61
61
|
export interface LoaderInitOptions {
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
/** Include built-in
|
|
65
|
-
|
|
66
|
-
/** Include built-in
|
|
67
|
-
|
|
68
|
-
/** Base URL used by built-in
|
|
62
|
+
/** Sources inserted with highest priority before built-ins. */
|
|
63
|
+
extraSources?: ManifestSource[];
|
|
64
|
+
/** Include built-in HttpSource. Defaults to true. */
|
|
65
|
+
includeHttpSource?: boolean;
|
|
66
|
+
/** Include built-in RegistrySource. Defaults to true. */
|
|
67
|
+
includeRegistrySource?: boolean;
|
|
68
|
+
/** Base URL used by built-in RegistrySource when enabled. */
|
|
69
69
|
registryUrl?: string;
|
|
70
70
|
/** Handlers for CEL stdlib functions (e.g. `sha256`). Analyzer-only callers may
|
|
71
71
|
* omit this and get throwing stubs; runtime callers (kernel) must supply real impls. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAExD;;qEAEiE;IACjE,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjE;;qEAEiE;IACjE,cAAc,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IAC1B;;;+EAG2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6FACyF;IACzF,WAAW,CAAC,EAAE,OAAO,sBAAsB,EAAE,WAAW,CAAC;CAC1D;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;gEAKgE;AAChE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,0BAA0B,EAAE,kBAAkB,CAAC;CACrE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telorun/analyzer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Telo Analyzer - Static manifest validator for Telo manifests.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"telo",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"ajv-formats": "^3.0.1",
|
|
42
42
|
"jsonpath-plus": "^10.3.0",
|
|
43
43
|
"yaml": "^2.8.3",
|
|
44
|
-
"@telorun/sdk": "0.
|
|
44
|
+
"@telorun/sdk": "0.6.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^20.0.0",
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
export { HttpAdapter } from "./adapters/http-adapter.js";
|
|
2
|
-
export { RegistryAdapter } from "./adapters/registry-adapter.js";
|
|
3
1
|
export { AnalysisRegistry } from "./analysis-registry.js";
|
|
4
2
|
export { StaticAnalyzer } from "./analyzer.js";
|
|
5
3
|
export { Loader } from "./manifest-loader.js";
|
|
6
|
-
export {
|
|
4
|
+
export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
|
|
7
5
|
export type { ModuleKind } from "./module-kinds.js";
|
|
6
|
+
export { HttpSource } from "./sources/http-source.js";
|
|
7
|
+
export { RegistrySource } from "./sources/registry-source.js";
|
|
8
8
|
export { DEFAULT_MANIFEST_FILENAME, DiagnosticSeverity } from "./types.js";
|
|
9
9
|
export type {
|
|
10
10
|
AnalysisDiagnostic,
|
|
11
|
-
AnalysisOptions,
|
|
11
|
+
AnalysisOptions,
|
|
12
|
+
LoaderInitOptions,
|
|
13
|
+
LoadOptions,
|
|
14
|
+
ManifestSource,
|
|
12
15
|
Position,
|
|
13
16
|
PositionIndex,
|
|
14
17
|
Range
|
package/src/manifest-loader.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Environment } from "@marcbachmann/cel-js";
|
|
2
2
|
import { isCompiledValue, type ResourceManifest } from "@telorun/sdk";
|
|
3
3
|
import { isMap, isPair, isScalar, isSeq, parseAllDocuments, type Document } from "yaml";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { HttpSource } from "./sources/http-source.js";
|
|
5
|
+
import { RegistrySource } from "./sources/registry-source.js";
|
|
6
6
|
import { buildCelEnvironment } from "./cel-environment.js";
|
|
7
7
|
import { isModuleKind } from "./module-kinds.js";
|
|
8
8
|
import { precompileDoc } from "./precompile.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
DEFAULT_MANIFEST_FILENAME,
|
|
11
11
|
type LoadOptions,
|
|
12
12
|
type LoaderInitOptions,
|
|
13
|
-
type
|
|
13
|
+
type ManifestSource,
|
|
14
14
|
type Position,
|
|
15
15
|
type PositionIndex,
|
|
16
16
|
} from "./types.js";
|
|
@@ -23,42 +23,42 @@ const SYSTEM_KINDS = new Set([
|
|
|
23
23
|
]);
|
|
24
24
|
|
|
25
25
|
export class Loader {
|
|
26
|
-
private
|
|
26
|
+
private readonly moduleCache = new Map<
|
|
27
27
|
string,
|
|
28
28
|
{ text: string; manifests: ResourceManifest[] }
|
|
29
29
|
>();
|
|
30
30
|
|
|
31
|
-
protected
|
|
31
|
+
protected sources: ManifestSource[];
|
|
32
32
|
private readonly celEnv: Environment;
|
|
33
33
|
|
|
34
|
-
constructor(
|
|
35
|
-
const options: LoaderInitOptions = Array.isArray(
|
|
36
|
-
? {
|
|
37
|
-
:
|
|
34
|
+
constructor(extraSourcesOrOptions: ManifestSource[] | LoaderInitOptions = []) {
|
|
35
|
+
const options: LoaderInitOptions = Array.isArray(extraSourcesOrOptions)
|
|
36
|
+
? { extraSources: extraSourcesOrOptions }
|
|
37
|
+
: extraSourcesOrOptions;
|
|
38
38
|
|
|
39
|
-
const
|
|
40
|
-
const
|
|
39
|
+
const includeHttpSource = options.includeHttpSource ?? true;
|
|
40
|
+
const includeRegistrySource = options.includeRegistrySource ?? true;
|
|
41
41
|
|
|
42
|
-
this.
|
|
43
|
-
if (
|
|
44
|
-
if (
|
|
42
|
+
this.sources = [];
|
|
43
|
+
if (includeHttpSource) this.sources.push(new HttpSource());
|
|
44
|
+
if (includeRegistrySource) this.sources.push(new RegistrySource(options.registryUrl));
|
|
45
45
|
|
|
46
|
-
if (options.
|
|
47
|
-
this.
|
|
46
|
+
if (options.extraSources?.length) {
|
|
47
|
+
this.sources.unshift(...options.extraSources);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
this.celEnv = buildCelEnvironment(options.celHandlers);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
register(
|
|
54
|
-
this.
|
|
53
|
+
register(source: ManifestSource): this {
|
|
54
|
+
this.sources.unshift(source);
|
|
55
55
|
return this;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
private pick(url: string):
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
61
|
-
return
|
|
58
|
+
private pick(url: string): ManifestSource {
|
|
59
|
+
const s = this.sources.find((s) => s.supports(url));
|
|
60
|
+
if (!s) throw new Error(`No source found for: ${url}`);
|
|
61
|
+
return s;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
async resolveEntryPoint(url: string): Promise<string> {
|
|
@@ -69,7 +69,7 @@ export class Loader {
|
|
|
69
69
|
async loadModule(url: string, options?: LoadOptions): Promise<ResourceManifest[]> {
|
|
70
70
|
const { text, source } = await this.pick(url).read(url);
|
|
71
71
|
const cacheKey = `${options?.compile ? "compiled" : "raw"}:${source}`;
|
|
72
|
-
const cached =
|
|
72
|
+
const cached = this.moduleCache.get(cacheKey);
|
|
73
73
|
if (cached && cached.text === text) {
|
|
74
74
|
return cloneManifestArray(cached.manifests);
|
|
75
75
|
}
|
|
@@ -152,8 +152,8 @@ export class Loader {
|
|
|
152
152
|
const includePatterns = (moduleManifest as any).include as string[] | undefined;
|
|
153
153
|
if (includePatterns?.length) {
|
|
154
154
|
hasIncludes = true;
|
|
155
|
-
const
|
|
156
|
-
const includedFiles = await this.resolveIncludes(source, includePatterns,
|
|
155
|
+
const picked = this.pick(source);
|
|
156
|
+
const includedFiles = await this.resolveIncludes(source, includePatterns, picked);
|
|
157
157
|
for (const includedUrl of includedFiles) {
|
|
158
158
|
const partialManifests = await this.loadPartialFile(includedUrl, moduleName, options);
|
|
159
159
|
resolved.push(...partialManifests);
|
|
@@ -162,7 +162,7 @@ export class Loader {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
if (!hasIncludes) {
|
|
165
|
-
|
|
165
|
+
this.moduleCache.set(cacheKey, { text, manifests: resolved });
|
|
166
166
|
}
|
|
167
167
|
return cloneManifestArray(resolved);
|
|
168
168
|
}
|
|
@@ -170,21 +170,21 @@ export class Loader {
|
|
|
170
170
|
private async resolveIncludes(
|
|
171
171
|
ownerSource: string,
|
|
172
172
|
patterns: string[],
|
|
173
|
-
|
|
173
|
+
source: ManifestSource,
|
|
174
174
|
): Promise<string[]> {
|
|
175
175
|
const hasGlobs = patterns.some((p) => /[*?{}\[\]]/.test(p));
|
|
176
176
|
if (hasGlobs) {
|
|
177
|
-
if (!
|
|
177
|
+
if (!source.expandGlob) {
|
|
178
178
|
throw new Error(
|
|
179
|
-
`Include patterns in '${ownerSource}' contain globs but the
|
|
179
|
+
`Include patterns in '${ownerSource}' contain globs but the source for this URL ` +
|
|
180
180
|
`does not support glob expansion. Use explicit file paths instead of patterns like: ` +
|
|
181
181
|
patterns.filter((p) => /[*?{}\[\]]/.test(p)).join(", "),
|
|
182
182
|
);
|
|
183
183
|
}
|
|
184
|
-
return
|
|
184
|
+
return source.expandGlob(ownerSource, patterns);
|
|
185
185
|
}
|
|
186
186
|
// Literal relative paths — deduplicate in case the same file appears under multiple patterns.
|
|
187
|
-
return [...new Set(patterns.map((p) =>
|
|
187
|
+
return [...new Set(patterns.map((p) => source.resolveRelative(ownerSource, p)))];
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
private async loadPartialFile(
|
|
@@ -280,9 +280,9 @@ export class Loader {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
// Find the owning telo.yaml via parent-directory traversal
|
|
283
|
-
const
|
|
284
|
-
if (!
|
|
285
|
-
const ownerUrl = await
|
|
283
|
+
const source = this.pick(fileUrl);
|
|
284
|
+
if (!source.resolveOwnerOf) return null;
|
|
285
|
+
const ownerUrl = await source.resolveOwnerOf(fileUrl);
|
|
286
286
|
if (!ownerUrl) return null;
|
|
287
287
|
|
|
288
288
|
// Load the owner module (which will load included files via include expansion)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DEFAULT_MANIFEST_FILENAME, type
|
|
1
|
+
import { DEFAULT_MANIFEST_FILENAME, type ManifestSource } from "../types.js";
|
|
2
2
|
|
|
3
|
-
export class
|
|
3
|
+
export class HttpSource implements ManifestSource {
|
|
4
4
|
supports(url: string): boolean {
|
|
5
5
|
return url.startsWith("http://") || url.startsWith("https://");
|
|
6
6
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DEFAULT_MANIFEST_FILENAME, type
|
|
1
|
+
import { DEFAULT_MANIFEST_FILENAME, type ManifestSource } from "../types.js";
|
|
2
2
|
|
|
3
3
|
const DEFAULT_REGISTRY_URL = "https://registry.telo.run";
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class RegistrySource implements ManifestSource {
|
|
6
6
|
constructor(private registryUrl = DEFAULT_REGISTRY_URL) {}
|
|
7
7
|
|
|
8
8
|
supports(url: string): boolean {
|
package/src/types.ts
CHANGED
|
@@ -41,19 +41,19 @@ export interface AnalysisDiagnostic {
|
|
|
41
41
|
data?: unknown;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export interface
|
|
44
|
+
export interface ManifestSource {
|
|
45
45
|
supports(url: string): boolean;
|
|
46
46
|
read(url: string): Promise<{ text: string; source: string }>;
|
|
47
47
|
resolveRelative(base: string, relative: string): string;
|
|
48
48
|
|
|
49
49
|
/** Expand glob patterns relative to a base source. Returns sources in the same
|
|
50
50
|
* format as read().source — suitable to pass back into read() / resolveRelative().
|
|
51
|
-
* Optional — only filesystem-capable
|
|
51
|
+
* Optional — only filesystem-capable sources implement this. */
|
|
52
52
|
expandGlob?(base: string, patterns: string[]): Promise<string[]>;
|
|
53
53
|
|
|
54
54
|
/** Walk parent directories from fileUrl looking for the nearest telo.yaml.
|
|
55
55
|
* Returns the source in the same format as read().source, or null if none found.
|
|
56
|
-
* Optional — only filesystem-capable
|
|
56
|
+
* Optional — only filesystem-capable sources implement this. */
|
|
57
57
|
resolveOwnerOf?(fileUrl: string): Promise<string | null>;
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -66,13 +66,13 @@ export interface LoadOptions {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export interface LoaderInitOptions {
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
/** Include built-in
|
|
72
|
-
|
|
73
|
-
/** Include built-in
|
|
74
|
-
|
|
75
|
-
/** Base URL used by built-in
|
|
69
|
+
/** Sources inserted with highest priority before built-ins. */
|
|
70
|
+
extraSources?: ManifestSource[];
|
|
71
|
+
/** Include built-in HttpSource. Defaults to true. */
|
|
72
|
+
includeHttpSource?: boolean;
|
|
73
|
+
/** Include built-in RegistrySource. Defaults to true. */
|
|
74
|
+
includeRegistrySource?: boolean;
|
|
75
|
+
/** Base URL used by built-in RegistrySource when enabled. */
|
|
76
76
|
registryUrl?: string;
|
|
77
77
|
/** Handlers for CEL stdlib functions (e.g. `sha256`). Analyzer-only callers may
|
|
78
78
|
* omit this and get throwing stubs; runtime callers (kernel) must supply real impls. */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/http-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9E,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWlE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAIxD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/registry-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9E,qBAAa,eAAgB,YAAW,eAAe;IACzC,OAAO,CAAC,WAAW;gBAAX,WAAW,SAAuB;IAEtD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWxB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWxE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMvD,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;CAmBvB"}
|