@g3nomaly/analyze 0.0.0-stage → 0.1.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/LICENSE +95 -0
- package/README.md +71 -2
- package/dist/THIRD_PARTY_LICENSES.txt +1904 -0
- package/dist/api/bundle-builder.d.ts +75 -0
- package/dist/api/bundle-cache.d.ts +70 -0
- package/dist/api/bundle-loader.d.ts +58 -0
- package/dist/api/create-docs.d.ts +72 -0
- package/dist/api/embedding.d.ts +32 -0
- package/dist/api/errors.d.ts +28 -0
- package/dist/api/list.d.ts +106 -0
- package/dist/api/options.d.ts +78 -0
- package/dist/api/refs.d.ts +133 -0
- package/dist/api/scan.d.ts +44 -0
- package/dist/api/search.d.ts +126 -0
- package/dist/api/services.d.ts +7 -0
- package/dist/api/show.d.ts +104 -0
- package/dist/api/site-reader.d.ts +11 -0
- package/dist/api/site-writer.d.ts +20 -0
- package/dist/api/source.d.ts +46 -0
- package/dist/api/target.d.ts +10 -0
- package/dist/api/template.d.ts +5 -0
- package/dist/assets/tree-sitter-c-sharp.wasm +0 -0
- package/dist/assets/tree-sitter-c.wasm +0 -0
- package/dist/assets/tree-sitter-cpp.wasm +0 -0
- package/dist/assets/tree-sitter-go.wasm +0 -0
- package/dist/assets/tree-sitter-java.wasm +0 -0
- package/dist/assets/tree-sitter-javascript.wasm +0 -0
- package/dist/assets/tree-sitter-kotlin.wasm +0 -0
- package/dist/assets/tree-sitter-php.wasm +0 -0
- package/dist/assets/tree-sitter-python.wasm +0 -0
- package/dist/assets/tree-sitter-ruby.wasm +0 -0
- package/dist/assets/tree-sitter-rust.wasm +0 -0
- package/dist/assets/tree-sitter-scala.wasm +0 -0
- package/dist/assets/tree-sitter-tsx.wasm +0 -0
- package/dist/assets/tree-sitter-typescript.wasm +0 -0
- package/dist/assets/vectors.bin +0 -0
- package/dist/assets/vocab.txt +33731 -0
- package/dist/cli.js +8885 -0
- package/dist/embeddings/abbreviations.d.ts +7 -0
- package/dist/embeddings/index-builder.d.ts +10 -0
- package/dist/embeddings/index.d.ts +10 -0
- package/dist/embeddings/model.d.ts +113 -0
- package/dist/embeddings/searcher.d.ts +67 -0
- package/dist/embeddings/vectors.d.ts +75 -0
- package/dist/embeddings/words.d.ts +42 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8329 -0
- package/dist/model/index.d.ts +560 -0
- package/dist/model/registry.d.ts +494 -0
- package/dist/query/graph.d.ts +66 -0
- package/dist/query/index.d.ts +4 -0
- package/dist/query/name-search.d.ts +47 -0
- package/dist/query/semantic.d.ts +30 -0
- package/dist/query/text.d.ts +22 -0
- package/dist/retrieval/describe.d.ts +26 -0
- package/dist/retrieval/filter.d.ts +17 -0
- package/dist/retrieval/index.d.ts +7 -0
- package/dist/retrieval/markdown.d.ts +16 -0
- package/dist/retrieval/report.d.ts +214 -0
- package/dist/retrieval/resolve.d.ts +27 -0
- package/dist/retrieval/retriever.d.ts +94 -0
- package/dist/retrieval/summary.d.ts +24 -0
- package/dist/scanner/code/doc/clean.d.ts +10 -0
- package/dist/scanner/code/doc/index.d.ts +6 -0
- package/dist/scanner/code/doc/markdown.d.ts +3 -0
- package/dist/scanner/code/doc/python.d.ts +3 -0
- package/dist/scanner/code/doc/tagged.d.ts +10 -0
- package/dist/scanner/code/doc/types.d.ts +22 -0
- package/dist/scanner/code/doc/xml.d.ts +3 -0
- package/dist/scanner/code/example.d.ts +36 -0
- package/dist/scanner/code/extract.d.ts +78 -0
- package/dist/scanner/code/grammar.d.ts +29 -0
- package/dist/scanner/code/language.d.ts +149 -0
- package/dist/scanner/code/languages/c-family.d.ts +5 -0
- package/dist/scanner/code/languages/csharp.d.ts +3 -0
- package/dist/scanner/code/languages/ecmascript.d.ts +7 -0
- package/dist/scanner/code/languages/go.d.ts +3 -0
- package/dist/scanner/code/languages/index.d.ts +19 -0
- package/dist/scanner/code/languages/java.d.ts +3 -0
- package/dist/scanner/code/languages/kotlin.d.ts +3 -0
- package/dist/scanner/code/languages/php.d.ts +3 -0
- package/dist/scanner/code/languages/python.d.ts +3 -0
- package/dist/scanner/code/languages/ruby.d.ts +3 -0
- package/dist/scanner/code/languages/rust.d.ts +3 -0
- package/dist/scanner/code/languages/scala.d.ts +3 -0
- package/dist/scanner/code/languages/shared.d.ts +17 -0
- package/dist/scanner/code/planner.d.ts +71 -0
- package/dist/scanner/code/symbols.d.ts +68 -0
- package/dist/scanner/code/types.d.ts +93 -0
- package/dist/scanner/content.d.ts +38 -0
- package/dist/scanner/decisions/parse.d.ts +28 -0
- package/dist/scanner/decisions/planner.d.ts +30 -0
- package/dist/scanner/docs.d.ts +52 -0
- package/dist/scanner/files.d.ts +60 -0
- package/dist/scanner/glossary/parse.d.ts +30 -0
- package/dist/scanner/glossary/planner.d.ts +42 -0
- package/dist/scanner/glossary/terms.d.ts +86 -0
- package/dist/scanner/graph/builder.d.ts +55 -0
- package/dist/scanner/highlight.d.ts +31 -0
- package/dist/scanner/index.d.ts +40 -0
- package/dist/scanner/markdown/frontmatter.d.ts +9 -0
- package/dist/scanner/markdown/links.d.ts +50 -0
- package/dist/scanner/markdown/outline.d.ts +27 -0
- package/dist/scanner/markdown/renderer.d.ts +44 -0
- package/dist/scanner/openapi/planner.d.ts +84 -0
- package/dist/scanner/reporter.d.ts +7 -0
- package/dist/scanner/scanner.d.ts +52 -0
- package/dist/scanner/schema/definitions.d.ts +69 -0
- package/dist/scanner/schema/describe.d.ts +79 -0
- package/dist/scanner/schema/planner.d.ts +46 -0
- package/dist/scanner/schema/registry.d.ts +61 -0
- package/dist/scanner/skills/classify.d.ts +20 -0
- package/dist/scanner/skills/layout.d.ts +28 -0
- package/dist/scanner/skills/planner.d.ts +46 -0
- package/dist/scanner/specs.d.ts +50 -0
- package/dist/scanner/sql/catalog.d.ts +84 -0
- package/dist/scanner/sql/cursor.d.ts +107 -0
- package/dist/scanner/sql/database.d.ts +48 -0
- package/dist/scanner/sql/parse.d.ts +87 -0
- package/dist/scanner/sql/planner.d.ts +65 -0
- package/dist/scanner/sql/query.d.ts +60 -0
- package/dist/scanner/sql/registry.d.ts +49 -0
- package/dist/scanner/sql/source.d.ts +9 -0
- package/dist/scanner/sql/statements.d.ts +36 -0
- package/dist/scanner/sql/tokens.d.ts +38 -0
- package/dist/scanner/tasks/layout.d.ts +40 -0
- package/dist/scanner/tasks/planner.d.ts +75 -0
- package/dist/scanner/tasks/schema.d.ts +88 -0
- package/dist/scanner/text.d.ts +14 -0
- package/package.json +104 -4
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { EdgeKind, LinkedText, NodeRef } from '../../model';
|
|
2
|
+
import type { DocFile } from '../docs';
|
|
3
|
+
import type { GraphBuilder } from '../graph/builder';
|
|
4
|
+
import type { ProseResolvers } from '../markdown/links';
|
|
5
|
+
import type { MarkdownRenderer } from '../markdown/renderer';
|
|
6
|
+
import { type TypeExpression } from './describe';
|
|
7
|
+
import type { DefinitionRegistry } from './registry';
|
|
8
|
+
/** The file a definition is in. */
|
|
9
|
+
export interface DefinitionOwner {
|
|
10
|
+
/** Node of the file. Definitions become its children. */
|
|
11
|
+
readonly ref: NodeRef;
|
|
12
|
+
readonly file: DocFile;
|
|
13
|
+
/** Anchors already used on the page of the file. */
|
|
14
|
+
readonly anchors: Set<string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Adds named JSON Schemas to the graph: one `definition` node per schema and
|
|
18
|
+
* one `field` node per property. A `$ref` in a type becomes a link to the
|
|
19
|
+
* definition it names, and an edge: `type` from a property, `extends` from a
|
|
20
|
+
* definition.
|
|
21
|
+
*
|
|
22
|
+
* Holds the graph, the markdown renderer, the prose resolvers and the
|
|
23
|
+
* definition registry. Created once per scan by `RepositoryScanner`. Used by
|
|
24
|
+
* `JsonSchemaPlanner` for the schemas of a schema file and by
|
|
25
|
+
* `OpenApiPlanner` for `components.schemas` and for the schemas of
|
|
26
|
+
* parameters, request bodies and responses.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const registry = new DefinitionRegistry();
|
|
30
|
+
* const definitions = new DefinitionPlanner(graph, markdown, resolvers, registry);
|
|
31
|
+
*/
|
|
32
|
+
export declare class DefinitionPlanner {
|
|
33
|
+
private readonly graph;
|
|
34
|
+
private readonly markdown;
|
|
35
|
+
private readonly resolvers;
|
|
36
|
+
private readonly registry;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a planner.
|
|
39
|
+
*
|
|
40
|
+
* @param resolvers - Links what descriptions refer to.
|
|
41
|
+
* @param registry - Receives every definition, and finds the targets of refs.
|
|
42
|
+
*/
|
|
43
|
+
constructor(graph: GraphBuilder, markdown: MarkdownRenderer, resolvers: ProseResolvers, registry: DefinitionRegistry);
|
|
44
|
+
/**
|
|
45
|
+
* Adds one definition with its properties.
|
|
46
|
+
*
|
|
47
|
+
* @param name - Name of the definition, as the page shows it.
|
|
48
|
+
* @param pointer - JSON pointer of the schema inside its file. Refs to that place link to the definition.
|
|
49
|
+
* @returns The node of the definition.
|
|
50
|
+
*/
|
|
51
|
+
add(owner: DefinitionOwner, name: string, pointer: string, schema: unknown): NodeRef;
|
|
52
|
+
/**
|
|
53
|
+
* Turns a type expression into text with links to the definitions its refs name.
|
|
54
|
+
*
|
|
55
|
+
* @param from - Node the expression belongs to.
|
|
56
|
+
* @param file - The file the expression is in. A relative ref starts there.
|
|
57
|
+
* @param relation - Kind of the edge each resolved ref records from `from`.
|
|
58
|
+
* @returns The text with a link for every ref the scan can resolve. A resolved ref reads as the name of its target, so a ref to a whole file reads as the title of its schema.
|
|
59
|
+
*/
|
|
60
|
+
linked(expression: TypeExpression, from: NodeRef, file: DocFile, relation: EdgeKind): LinkedText;
|
|
61
|
+
/**
|
|
62
|
+
* Renders a description.
|
|
63
|
+
*
|
|
64
|
+
* @param markdown - Markdown of the description, or `''`.
|
|
65
|
+
* @param node - Node the description belongs to. Links in it become edges from this node.
|
|
66
|
+
* @returns HTML, or `''`.
|
|
67
|
+
*/
|
|
68
|
+
html(markdown: string, node: NodeRef, { root, path, prefix }: DocFile): Promise<string>;
|
|
69
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** A JSON object as parsed from JSON or YAML. */
|
|
2
|
+
export type JsonObject = Readonly<Record<string, unknown>>;
|
|
3
|
+
/**
|
|
4
|
+
* Tells a JSON object from every other value: true for an object that is no
|
|
5
|
+
* array and not `null`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isJsonObject(value: unknown): value is JsonObject;
|
|
8
|
+
/** A span of a type expression that stands for a `$ref`. */
|
|
9
|
+
export interface SchemaRef {
|
|
10
|
+
readonly start: number;
|
|
11
|
+
readonly end: number;
|
|
12
|
+
/** The `$ref` as the schema writes it. */
|
|
13
|
+
readonly ref: string;
|
|
14
|
+
}
|
|
15
|
+
/** What a schema allows, as text: `string[]`, `Cat | Dog`, `"open" | "closed"`. */
|
|
16
|
+
export interface TypeExpression {
|
|
17
|
+
readonly text: string;
|
|
18
|
+
/** In text order, not overlapping. */
|
|
19
|
+
readonly refs: readonly SchemaRef[];
|
|
20
|
+
}
|
|
21
|
+
/** One property of an object schema. A nested property has a dotted name. */
|
|
22
|
+
export interface SchemaProperty {
|
|
23
|
+
/** `city`, `address.city`, `items[].sku`. */
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly type: TypeExpression;
|
|
26
|
+
readonly required: boolean;
|
|
27
|
+
/** The default as JSON, or `null`. */
|
|
28
|
+
readonly defaultValue: string | null;
|
|
29
|
+
/** Markdown. */
|
|
30
|
+
readonly description: string;
|
|
31
|
+
/** Keywords that narrow the type, as `keyword: value`. */
|
|
32
|
+
readonly constraints: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
/** What a schema says, in the shape the site shows. */
|
|
35
|
+
export interface SchemaDescription {
|
|
36
|
+
readonly type: TypeExpression;
|
|
37
|
+
/** Markdown. */
|
|
38
|
+
readonly description: string;
|
|
39
|
+
readonly constraints: readonly string[];
|
|
40
|
+
/** Values of an `enum` or a `const`, as JSON. */
|
|
41
|
+
readonly values: readonly string[];
|
|
42
|
+
readonly deprecated: boolean;
|
|
43
|
+
readonly properties: readonly SchemaProperty[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reads the last part of a `$ref` as a name.
|
|
47
|
+
*
|
|
48
|
+
* @param ref - A `$ref`, such as `#/$defs/Booking` or `cargo.schema.json`.
|
|
49
|
+
* @returns `Booking` for a ref into a file, the file name for a ref to a whole file.
|
|
50
|
+
*/
|
|
51
|
+
export declare function refName(ref: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Decodes one segment of a JSON pointer.
|
|
54
|
+
*
|
|
55
|
+
* @returns The key it names: percent escapes decoded, `~1` as `/` and `~0` as `~`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function decodePointerSegment(segment: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Writes what a schema allows as a type expression.
|
|
60
|
+
*
|
|
61
|
+
* @param schema - A schema: an object, or `true` or `false`.
|
|
62
|
+
* @param depth - Nesting of the schema inside the one that is described.
|
|
63
|
+
* @returns The expression. `any` for a schema that states no type.
|
|
64
|
+
*/
|
|
65
|
+
export declare function typeOf(schema: unknown, depth?: number): TypeExpression;
|
|
66
|
+
/**
|
|
67
|
+
* Describes a JSON Schema in the shape the site shows: a type expression, a
|
|
68
|
+
* description, constraints and a flat list of properties.
|
|
69
|
+
*
|
|
70
|
+
* @param schema - The schema: an object, or `true` or `false`.
|
|
71
|
+
* @returns The description. A value that is no schema is described as `any`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function describeSchema(schema: unknown): SchemaDescription;
|
|
74
|
+
/**
|
|
75
|
+
* Tells whether a schema says anything about a value: true when it has a
|
|
76
|
+
* type, properties, a composition, values or a `$ref`. A file that only
|
|
77
|
+
* holds `$defs` has a root schema that does not.
|
|
78
|
+
*/
|
|
79
|
+
export declare function describesValue(schema: JsonObject): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { NodeRef } from '../../model';
|
|
2
|
+
import type { FileRenderer } from '../content';
|
|
3
|
+
import type { DocFile } from '../docs';
|
|
4
|
+
import type { GraphBuilder } from '../graph/builder';
|
|
5
|
+
import type { ProseResolvers } from '../markdown/links';
|
|
6
|
+
import type { DefinitionPlanner } from './definitions';
|
|
7
|
+
import { type JsonObject } from './describe';
|
|
8
|
+
import type { DefinitionRegistry } from './registry';
|
|
9
|
+
/**
|
|
10
|
+
* Adds a JSON Schema file to the graph: one `schema` node for the file, with
|
|
11
|
+
* its text, and one definition per schema it names. The root schema is a
|
|
12
|
+
* definition when it describes a value.
|
|
13
|
+
*
|
|
14
|
+
* Holds the graph, the file renderer, the prose resolvers, the shared
|
|
15
|
+
* `DefinitionPlanner` and the `DefinitionRegistry`. Created by
|
|
16
|
+
* `RepositoryScanner` and used by `SpecPlanner` for every JSON or YAML file
|
|
17
|
+
* that is a JSON Schema.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const registry = new DefinitionRegistry();
|
|
21
|
+
* const definitions = new DefinitionPlanner(graph, markdown, resolvers, registry);
|
|
22
|
+
* const schemas = new JsonSchemaPlanner(graph, files, resolvers, definitions, registry);
|
|
23
|
+
*/
|
|
24
|
+
export declare class JsonSchemaPlanner {
|
|
25
|
+
private readonly graph;
|
|
26
|
+
private readonly files;
|
|
27
|
+
private readonly resolvers;
|
|
28
|
+
private readonly definitions;
|
|
29
|
+
private readonly registry;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a planner.
|
|
32
|
+
*
|
|
33
|
+
* @param files - Renders the text of the file.
|
|
34
|
+
* @param resolvers - Links what the file refers to.
|
|
35
|
+
* @param registry - Receives the file and its `$id`, so refs to the file resolve.
|
|
36
|
+
*/
|
|
37
|
+
constructor(graph: GraphBuilder, files: FileRenderer, resolvers: ProseResolvers, definitions: DefinitionPlanner, registry: DefinitionRegistry);
|
|
38
|
+
/**
|
|
39
|
+
* Adds one schema file.
|
|
40
|
+
*
|
|
41
|
+
* @param parent - Folder or skill the file is in.
|
|
42
|
+
* @param schema - The parsed file.
|
|
43
|
+
* @returns The node of the file.
|
|
44
|
+
*/
|
|
45
|
+
plan(parent: NodeRef, file: DocFile, schema: JsonObject): NodeRef;
|
|
46
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { NodeRef } from '../../model';
|
|
2
|
+
/**
|
|
3
|
+
* Writes a JSON pointer in one spelling, so two spellings of one place compare equal.
|
|
4
|
+
*
|
|
5
|
+
* @param pointer - A pointer, with or without the `#` in front.
|
|
6
|
+
* @returns The pointer with every segment decoded. `''` names the root.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizePointer(pointer: string): string;
|
|
9
|
+
/** What a `$ref` points at. */
|
|
10
|
+
export interface RefTarget {
|
|
11
|
+
readonly ref: NodeRef;
|
|
12
|
+
/** Name of the node, as a type expression shows it. */
|
|
13
|
+
readonly name: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Finds the nodes that `$ref`s point at, across the JSON Schema files and
|
|
17
|
+
* OpenAPI documents of one scan.
|
|
18
|
+
*
|
|
19
|
+
* Holds a map from `path#pointer` to the node at that place, and a map from
|
|
20
|
+
* `$id` to file path. Created once per scan by `RepositoryScanner` and shared
|
|
21
|
+
* by `JsonSchemaPlanner`, `OpenApiPlanner` and `DefinitionPlanner`. The
|
|
22
|
+
* planners register every file and definition when they add it;
|
|
23
|
+
* `DefinitionPlanner` resolves refs when the content of the graph is built.
|
|
24
|
+
* By then every file is read, so a ref can point into a later file.
|
|
25
|
+
*/
|
|
26
|
+
export declare class DefinitionRegistry {
|
|
27
|
+
/** `path#pointer` to the node at that place. */
|
|
28
|
+
private readonly places;
|
|
29
|
+
/** `$id` of a schema file to its path. */
|
|
30
|
+
private readonly ids;
|
|
31
|
+
/**
|
|
32
|
+
* Records the node that shows a place in a file.
|
|
33
|
+
*
|
|
34
|
+
* @param path - Path of the file, as the site shows it.
|
|
35
|
+
* @param pointer - JSON pointer of the place inside the file. `''` is the whole file.
|
|
36
|
+
*/
|
|
37
|
+
register(path: string, pointer: string, target: RefTarget): void;
|
|
38
|
+
/**
|
|
39
|
+
* Records the `$id` of a schema file, so a ref by that id finds the file.
|
|
40
|
+
*
|
|
41
|
+
* @param id - The `$id`, an absolute URI.
|
|
42
|
+
* @param path - Path of the file, as the site shows it.
|
|
43
|
+
*/
|
|
44
|
+
registerId(id: string, path: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Finds the node a `$ref` points at.
|
|
47
|
+
*
|
|
48
|
+
* @param ref - The `$ref` as written: `#/$defs/Cargo`, `cargo.schema.json#/$defs/Cargo`, or the `$id` of a file.
|
|
49
|
+
* @param fromPath - Path of the file the ref is in. A relative ref starts there.
|
|
50
|
+
* @returns The node and its name, or `null` when the ref leaves the scan or names nothing the site shows.
|
|
51
|
+
*/
|
|
52
|
+
resolve(ref: string, fromPath: string): RefTarget | null;
|
|
53
|
+
/**
|
|
54
|
+
* Finds the file a URI names.
|
|
55
|
+
*
|
|
56
|
+
* @param uri - The part of a ref in front of the `#`.
|
|
57
|
+
* @param fromPath - Path of the file the ref is in, as the site shows it.
|
|
58
|
+
* @returns Path of the file: the same file for an empty URI, a registered `$id`, or a relative path. `null` for any other absolute URI.
|
|
59
|
+
*/
|
|
60
|
+
private pathOf;
|
|
61
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FileKind } from '../../model';
|
|
2
|
+
/** What a file inside a skill directory can be. `source` is code, shown with its symbols. */
|
|
3
|
+
export type SkillFileKind = Exclude<FileKind, 'skill' | 'document'> | 'source';
|
|
4
|
+
/**
|
|
5
|
+
* Kind of a file in a skill, from where it is and what it is. The first rule that matches wins.
|
|
6
|
+
*
|
|
7
|
+
* | Rule | Kind |
|
|
8
|
+
* |---|---|
|
|
9
|
+
* | in a `hooks/` directory | `hook` |
|
|
10
|
+
* | in an `agents/` directory | `agent` |
|
|
11
|
+
* | in a `schemas/` directory, or named like a schema | `schema` |
|
|
12
|
+
* | source code | `source` |
|
|
13
|
+
* | markdown | `reference` |
|
|
14
|
+
* | JSON | `json` |
|
|
15
|
+
* | anything else | `asset` |
|
|
16
|
+
*
|
|
17
|
+
* @param path - Path relative to the skill directory.
|
|
18
|
+
* @param isSource - Answers whether a file is source code.
|
|
19
|
+
*/
|
|
20
|
+
export declare function classifySkillFile(path: string, isSource: (path: string) => boolean): SkillFileKind;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** File name that makes a directory a skill. */
|
|
2
|
+
export declare const SKILL_FILE = "SKILL.md";
|
|
3
|
+
/** A skill directory and the files that belong to it. */
|
|
4
|
+
export interface SkillLayout {
|
|
5
|
+
/** Root-relative directory of the `SKILL.md`. `''` for the root itself. */
|
|
6
|
+
readonly directory: string;
|
|
7
|
+
/** Root-relative path of the `SKILL.md`. */
|
|
8
|
+
readonly skillFile: string;
|
|
9
|
+
/** Every other file of the skill, root-relative. */
|
|
10
|
+
readonly files: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Tells whether a file lies in a directory or below it.
|
|
14
|
+
*
|
|
15
|
+
* @param file - Root-relative POSIX path.
|
|
16
|
+
* @param directory - Root-relative POSIX directory. `''` is the root and holds every file.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isInside(file: string, directory: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Finds the skills in a file list. A skill is a directory with a `SKILL.md`.
|
|
21
|
+
* Each file belongs to the deepest skill directory around it.
|
|
22
|
+
*
|
|
23
|
+
* @param files - Root-relative POSIX paths.
|
|
24
|
+
* @returns One layout per `SKILL.md`, deepest directory first.
|
|
25
|
+
*/
|
|
26
|
+
export declare function skillLayouts(files: readonly string[]): SkillLayout[];
|
|
27
|
+
/** The files of a list that belong to a skill, `SKILL.md` files included. */
|
|
28
|
+
export declare function skillOwnedFiles(files: readonly string[]): Set<string>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { NodeRef } from '../../model';
|
|
2
|
+
import type { CodePlanner } from '../code/planner';
|
|
3
|
+
import type { FileRenderer } from '../content';
|
|
4
|
+
import { type Source } from '../files';
|
|
5
|
+
import type { GraphBuilder } from '../graph/builder';
|
|
6
|
+
import type { ProseResolvers } from '../markdown/links';
|
|
7
|
+
import type { SpecPlanner } from '../specs';
|
|
8
|
+
/**
|
|
9
|
+
* Adds skills to the graph. A skill is its `SKILL.md`. The other files of its
|
|
10
|
+
* directory become its descendants, each with the kind its place and type
|
|
11
|
+
* give it. A file that is an OpenAPI document or a JSON Schema goes to the
|
|
12
|
+
* `SpecPlanner`, a source file to the `CodePlanner`.
|
|
13
|
+
*
|
|
14
|
+
* Holds the graph, the file renderer, the code planner, the prose resolvers
|
|
15
|
+
* and the spec planner. Created and run by `RepositoryScanner` once per scan.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* await new SkillPlanner(graph, files, code, resolvers, specs).plan(sections.skills, input.skills);
|
|
19
|
+
*/
|
|
20
|
+
export declare class SkillPlanner {
|
|
21
|
+
private readonly graph;
|
|
22
|
+
private readonly files;
|
|
23
|
+
private readonly code;
|
|
24
|
+
private readonly resolvers;
|
|
25
|
+
private readonly specs;
|
|
26
|
+
/** Creates a planner. */
|
|
27
|
+
constructor(graph: GraphBuilder, files: FileRenderer, code: CodePlanner, resolvers: ProseResolvers, specs: SpecPlanner);
|
|
28
|
+
/**
|
|
29
|
+
* Adds the skills of every source, sorted by name, each with a unique slug.
|
|
30
|
+
*
|
|
31
|
+
* @param section - Node of the skills section, the parent of every skill.
|
|
32
|
+
*/
|
|
33
|
+
plan(section: NodeRef, sources: readonly Source[]): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Reads the `SKILL.md` of a skill and picks its name: the `name` field of
|
|
36
|
+
* the frontmatter, else the first `#` heading, else the directory name.
|
|
37
|
+
*/
|
|
38
|
+
private read;
|
|
39
|
+
/**
|
|
40
|
+
* Adds one skill node and a node for each of its files, under folder nodes
|
|
41
|
+
* that mirror the skill directory.
|
|
42
|
+
*
|
|
43
|
+
* @param slugs - Slugs already taken by other skills. Receives the slug of this one.
|
|
44
|
+
*/
|
|
45
|
+
private planSkill;
|
|
46
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { NodeRef } from '../model';
|
|
2
|
+
import type { DocFile } from './docs';
|
|
3
|
+
import type { OpenApiPlanner } from './openapi/planner';
|
|
4
|
+
import { type Reporter } from './reporter';
|
|
5
|
+
import { type JsonObject } from './schema/describe';
|
|
6
|
+
import type { JsonSchemaPlanner } from './schema/planner';
|
|
7
|
+
/**
|
|
8
|
+
* A **spec** is a JSON or YAML file that describes data or an API in a
|
|
9
|
+
* standard format: an OpenAPI document or a JSON Schema.
|
|
10
|
+
*/
|
|
11
|
+
export type SpecKind = 'openapi' | 'json-schema';
|
|
12
|
+
/**
|
|
13
|
+
* Tells what kind of spec a parsed file is.
|
|
14
|
+
*
|
|
15
|
+
* @returns `openapi` for a document with an `openapi` version 3 and paths, components or webhooks. `json-schema` for a document whose `$schema` names JSON Schema, or that is named like a schema and uses its keywords. `null` for anything else.
|
|
16
|
+
*/
|
|
17
|
+
export declare function specKind(path: string, document: JsonObject): SpecKind | null;
|
|
18
|
+
/**
|
|
19
|
+
* Adds the specs among the JSON and YAML files of a scan to the graph.
|
|
20
|
+
*
|
|
21
|
+
* Used by `DocPlanner` and `SkillPlanner` for every JSON or YAML file, before
|
|
22
|
+
* they add the file as plain text. The file is parsed once here, and goes to
|
|
23
|
+
* the planner of its kind. Created by `RepositoryScanner` for every scan.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SpecPlanner {
|
|
26
|
+
private readonly openapi;
|
|
27
|
+
private readonly schemas;
|
|
28
|
+
private readonly reporter;
|
|
29
|
+
/**
|
|
30
|
+
* Keeps the planner of each spec kind.
|
|
31
|
+
*
|
|
32
|
+
* @param reporter - Receives files that cannot be read.
|
|
33
|
+
*/
|
|
34
|
+
constructor(openapi: OpenApiPlanner, schemas: JsonSchemaPlanner, reporter?: Reporter);
|
|
35
|
+
/** Tells whether a file can be a spec: true for a JSON or YAML file. */
|
|
36
|
+
handles(path: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Reads one file and adds it when it is a spec.
|
|
39
|
+
*
|
|
40
|
+
* @param parent - Gives the folder or skill the file is in. Called only for a spec, so a folder with nothing else in it is not added.
|
|
41
|
+
* @returns The node of the file, or `null` when the file is no spec or cannot be parsed.
|
|
42
|
+
*/
|
|
43
|
+
plan(file: DocFile, parent: () => NodeRef): Promise<NodeRef | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Parses a file.
|
|
46
|
+
*
|
|
47
|
+
* @returns The parsed object, or `null` for a file that is too large, holds no object or is not valid.
|
|
48
|
+
*/
|
|
49
|
+
private read;
|
|
50
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { NodeRef } from '../../model';
|
|
2
|
+
import type { SourceFile } from '../code/planner';
|
|
3
|
+
import type { GraphBuilder } from '../graph/builder';
|
|
4
|
+
import type { CodeHighlighter } from '../highlight';
|
|
5
|
+
import type { ProseResolvers } from '../markdown/links';
|
|
6
|
+
import type { MarkdownRenderer } from '../markdown/renderer';
|
|
7
|
+
import type { ParsedQuery } from './query';
|
|
8
|
+
import { type TableRegistry } from './registry';
|
|
9
|
+
/** One SQL file of a catalog with the entries it holds. */
|
|
10
|
+
export interface CatalogFile {
|
|
11
|
+
readonly file: SourceFile;
|
|
12
|
+
/** From `parseQueryFile`. Not empty. */
|
|
13
|
+
readonly queries: readonly ParsedQuery[];
|
|
14
|
+
}
|
|
15
|
+
/** Where a catalog goes in the tree and what it is called. */
|
|
16
|
+
export interface CatalogPlace {
|
|
17
|
+
readonly parent: NodeRef;
|
|
18
|
+
readonly name: string;
|
|
19
|
+
/** Segment of the route of the catalog, when it is not the name. */
|
|
20
|
+
readonly slug?: string;
|
|
21
|
+
/** Path of the directory of the catalog, as the site shows it. */
|
|
22
|
+
readonly path: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Adds query catalogs to the graph: one `catalog` node per directory, one
|
|
26
|
+
* `query` node per entry, one `parameter` node per placeholder and one
|
|
27
|
+
* `field` node per column of the rows an entry returns. A table an entry
|
|
28
|
+
* names becomes a `reads` or a `writes` edge to that table.
|
|
29
|
+
*
|
|
30
|
+
* `DatabasePlanner` calls `add` once per directory that holds SQL files
|
|
31
|
+
* without tables. Tables and columns are looked up when the content of the
|
|
32
|
+
* graph is built, so a query can name a table of any file of the scan.
|
|
33
|
+
* `RepositoryScanner` creates one per scan with the `TableRegistry` it shares
|
|
34
|
+
* with the `SqlPlanner`; `DatabasePlanner` shows the wiring.
|
|
35
|
+
*/
|
|
36
|
+
export declare class CatalogPlanner {
|
|
37
|
+
private readonly graph;
|
|
38
|
+
private readonly markdown;
|
|
39
|
+
private readonly highlighter;
|
|
40
|
+
private readonly resolvers;
|
|
41
|
+
private readonly tables;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a planner.
|
|
44
|
+
*
|
|
45
|
+
* @param markdown - Renders the notes of entries.
|
|
46
|
+
* @param highlighter - Highlights the SQL of entries.
|
|
47
|
+
* @param resolvers - Links what notes refer to.
|
|
48
|
+
* @param tables - Finds the tables and columns that entries name.
|
|
49
|
+
*/
|
|
50
|
+
constructor(graph: GraphBuilder, markdown: MarkdownRenderer, highlighter: CodeHighlighter, resolvers: ProseResolvers, tables: TableRegistry);
|
|
51
|
+
/**
|
|
52
|
+
* Adds one catalog with its entries.
|
|
53
|
+
*
|
|
54
|
+
* @param files - The SQL files of the catalog, in display order.
|
|
55
|
+
* @returns The node of the catalog.
|
|
56
|
+
*/
|
|
57
|
+
add(place: CatalogPlace, files: readonly CatalogFile[]): NodeRef;
|
|
58
|
+
/**
|
|
59
|
+
* Adds one entry with its placeholders and its result columns.
|
|
60
|
+
*
|
|
61
|
+
* @param catalog - Node of the catalog.
|
|
62
|
+
* @param anchors - Anchors the catalog uses already. The anchor of the entry is added.
|
|
63
|
+
* @returns The node of the entry.
|
|
64
|
+
*/
|
|
65
|
+
private addQuery;
|
|
66
|
+
/**
|
|
67
|
+
* Finds the table column a column of a statement means.
|
|
68
|
+
*
|
|
69
|
+
* @param ref - The column as the statement names it, or `null`.
|
|
70
|
+
* @param query - The entry the statement is in.
|
|
71
|
+
* @param path - Display path (`SourceFile.displayPath`) of the file of the entry.
|
|
72
|
+
* @returns The column of the named table. For a column without a table in front: the column of that name when exactly one table of the entry has it. Else `null`.
|
|
73
|
+
*/
|
|
74
|
+
private columnOf;
|
|
75
|
+
/**
|
|
76
|
+
* Replaces `*` and `t.*` in the result columns of an entry by the columns
|
|
77
|
+
* of the tables they stand for. That needs the tables at the time the
|
|
78
|
+
* entry is added, so `DatabasePlanner` adds schema files first.
|
|
79
|
+
*
|
|
80
|
+
* @param path - Display path (`SourceFile.displayPath`) of the file of the entry.
|
|
81
|
+
* @returns The result columns, with every star replaced whose tables the scan has. Any other star stays.
|
|
82
|
+
*/
|
|
83
|
+
private expand;
|
|
84
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { SqlToken } from './tokens';
|
|
2
|
+
/**
|
|
3
|
+
* Error for a statement that cannot be read. Thrown by `TokenCursor` and by
|
|
4
|
+
* the readers of `parse.ts`. `parseSqlSchema` catches it and skips the statement.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SqlSyntaxError extends Error {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Walks the tokens of one statement. Holds the tokens, the SQL text they come
|
|
10
|
+
* from and the position of the cursor. The functions of `parse.ts` that read a
|
|
11
|
+
* statement, a column or a constraint each take a cursor, read what they know
|
|
12
|
+
* and leave the cursor behind it. `parseSqlSchema` creates one per statement,
|
|
13
|
+
* and `over` creates one for a part of a statement.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TokenCursor {
|
|
16
|
+
private readonly tokens;
|
|
17
|
+
private readonly source;
|
|
18
|
+
private index;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a cursor at the first token.
|
|
21
|
+
*
|
|
22
|
+
* @param source - The SQL text the tokens come from, for reading text back as written.
|
|
23
|
+
*/
|
|
24
|
+
constructor(tokens: readonly SqlToken[], source: string);
|
|
25
|
+
/**
|
|
26
|
+
* Tells whether every token is taken.
|
|
27
|
+
*/
|
|
28
|
+
get done(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Looks at a token without taking it.
|
|
31
|
+
*
|
|
32
|
+
* @param offset - Tokens ahead of the current one.
|
|
33
|
+
* @returns The token, or `undefined` behind the end.
|
|
34
|
+
*/
|
|
35
|
+
peek(offset?: number): SqlToken | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Takes the current token.
|
|
38
|
+
*
|
|
39
|
+
* @throws {SqlSyntaxError} At the end of the statement.
|
|
40
|
+
*/
|
|
41
|
+
next(): SqlToken;
|
|
42
|
+
/**
|
|
43
|
+
* Tells whether the current token is one of the given keywords.
|
|
44
|
+
*
|
|
45
|
+
* @param words - Keywords in capitals.
|
|
46
|
+
* @param offset - Tokens ahead of the current one.
|
|
47
|
+
* @returns True for an unquoted word that is one of them, whatever its case.
|
|
48
|
+
*/
|
|
49
|
+
isWord(words: readonly string[], offset?: number): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Takes the tokens ahead when they are the given keywords in this order.
|
|
52
|
+
*
|
|
53
|
+
* @param words - Keywords in capitals.
|
|
54
|
+
* @returns True when all were there and are taken. False leaves the cursor in place.
|
|
55
|
+
*/
|
|
56
|
+
accept(...words: string[]): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Tells whether the current token is a given symbol.
|
|
59
|
+
*
|
|
60
|
+
* @param symbol - One character.
|
|
61
|
+
*/
|
|
62
|
+
isSymbol(symbol: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Takes the current token when it is a given symbol.
|
|
65
|
+
*
|
|
66
|
+
* @param symbol - One character.
|
|
67
|
+
*/
|
|
68
|
+
acceptSymbol(symbol: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Takes a name: an unquoted word or a quoted identifier. A string counts,
|
|
71
|
+
* because SQLite reads a string as a name where a name has to be.
|
|
72
|
+
*
|
|
73
|
+
* @returns The name without quotes.
|
|
74
|
+
* @throws {SqlSyntaxError} When the current token cannot be a name.
|
|
75
|
+
*/
|
|
76
|
+
name(): string;
|
|
77
|
+
/**
|
|
78
|
+
* Takes a name that may have a schema in front, as in `main.booking`.
|
|
79
|
+
*
|
|
80
|
+
* @returns The last part of the name.
|
|
81
|
+
*/
|
|
82
|
+
qualifiedName(): string;
|
|
83
|
+
/**
|
|
84
|
+
* Takes a group in parentheses with everything inside it.
|
|
85
|
+
*
|
|
86
|
+
* @returns The tokens between the parentheses.
|
|
87
|
+
* @throws {SqlSyntaxError} When the current token opens no group, or the group never closes.
|
|
88
|
+
*/
|
|
89
|
+
group(): SqlToken[];
|
|
90
|
+
/**
|
|
91
|
+
* Reads SQL back as written, with runs of whitespace as one space.
|
|
92
|
+
*
|
|
93
|
+
* @param to - Last token of the text. Defaults to the token in front of the cursor.
|
|
94
|
+
*/
|
|
95
|
+
text(from: SqlToken, to?: SqlToken | undefined): string;
|
|
96
|
+
/**
|
|
97
|
+
* Creates a cursor for some of the tokens of the same text.
|
|
98
|
+
*/
|
|
99
|
+
over(tokens: readonly SqlToken[]): TokenCursor;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Splits tokens at the commas that are not inside parentheses.
|
|
103
|
+
*
|
|
104
|
+
* @param tokens - Tokens of a list, without the parentheses around it.
|
|
105
|
+
* @returns The tokens of each item. An empty item is left out.
|
|
106
|
+
*/
|
|
107
|
+
export declare function splitAtCommas(tokens: readonly SqlToken[]): SqlToken[][];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { NodeRef } from '../../model';
|
|
2
|
+
import { type Source } from '../files';
|
|
3
|
+
import type { GraphBuilder } from '../graph/builder';
|
|
4
|
+
import { type Reporter } from '../reporter';
|
|
5
|
+
import type { CatalogPlanner } from './catalog';
|
|
6
|
+
import type { SqlPlanner } from './planner';
|
|
7
|
+
/**
|
|
8
|
+
* Builds the database section from the SQL files of a directory tree.
|
|
9
|
+
*
|
|
10
|
+
* A file that creates a table is a schema and goes to the `SqlPlanner`.
|
|
11
|
+
* Every other SQL file holds queries and statements. The files of one
|
|
12
|
+
* directory form a catalog, which goes to the `CatalogPlanner`. The section
|
|
13
|
+
* starts at the directory the SQL files share, so a reader is not led
|
|
14
|
+
* through folders that hold nothing else.
|
|
15
|
+
*
|
|
16
|
+
* `RepositoryScanner` creates one per scan and calls `planTree` once per
|
|
17
|
+
* source directory. The `SqlPlanner` and the `CatalogPlanner` share one
|
|
18
|
+
* `TableRegistry`, so queries can find the tables of schema files.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const tables = new TableRegistry();
|
|
22
|
+
* const sql = new SqlPlanner(graph, markdown, highlighter, resolvers, tables, reporter);
|
|
23
|
+
* const databases = new DatabasePlanner(
|
|
24
|
+
* graph,
|
|
25
|
+
* sql,
|
|
26
|
+
* new CatalogPlanner(graph, markdown, highlighter, resolvers, tables),
|
|
27
|
+
* reporter,
|
|
28
|
+
* );
|
|
29
|
+
* await databases.planTree(section, source);
|
|
30
|
+
*/
|
|
31
|
+
export declare class DatabasePlanner {
|
|
32
|
+
private readonly graph;
|
|
33
|
+
private readonly schemas;
|
|
34
|
+
private readonly catalogs;
|
|
35
|
+
private readonly reporter;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a planner.
|
|
38
|
+
*
|
|
39
|
+
* @param reporter - Receives files that cannot be read.
|
|
40
|
+
*/
|
|
41
|
+
constructor(graph: GraphBuilder, schemas: SqlPlanner, catalogs: CatalogPlanner, reporter?: Reporter);
|
|
42
|
+
/**
|
|
43
|
+
* Adds every SQL file of `source` below `section`.
|
|
44
|
+
*
|
|
45
|
+
* @param section - Node of the database section.
|
|
46
|
+
*/
|
|
47
|
+
planTree(section: NodeRef, source: Source): Promise<void>;
|
|
48
|
+
}
|