@g3nomaly/analyze 0.0.0-stage → 0.1.1

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 (133) hide show
  1. package/LICENSE +95 -0
  2. package/README.md +76 -2
  3. package/dist/THIRD_PARTY_LICENSES.txt +1904 -0
  4. package/dist/api/bundle-builder.d.ts +94 -0
  5. package/dist/api/bundle-cache.d.ts +73 -0
  6. package/dist/api/bundle-loader.d.ts +65 -0
  7. package/dist/api/create-docs.d.ts +91 -0
  8. package/dist/api/embedding.d.ts +41 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/list.d.ts +106 -0
  11. package/dist/api/options.d.ts +74 -0
  12. package/dist/api/refs.d.ts +136 -0
  13. package/dist/api/scan.d.ts +56 -0
  14. package/dist/api/search.d.ts +132 -0
  15. package/dist/api/services.d.ts +15 -0
  16. package/dist/api/show.d.ts +100 -0
  17. package/dist/api/site-reader.d.ts +19 -0
  18. package/dist/api/site-writer.d.ts +43 -0
  19. package/dist/api/source.d.ts +57 -0
  20. package/dist/api/target.d.ts +12 -0
  21. package/dist/api/template.d.ts +5 -0
  22. package/dist/assets/tree-sitter-c-sharp.wasm +0 -0
  23. package/dist/assets/tree-sitter-c.wasm +0 -0
  24. package/dist/assets/tree-sitter-cpp.wasm +0 -0
  25. package/dist/assets/tree-sitter-go.wasm +0 -0
  26. package/dist/assets/tree-sitter-java.wasm +0 -0
  27. package/dist/assets/tree-sitter-javascript.wasm +0 -0
  28. package/dist/assets/tree-sitter-kotlin.wasm +0 -0
  29. package/dist/assets/tree-sitter-php.wasm +0 -0
  30. package/dist/assets/tree-sitter-python.wasm +0 -0
  31. package/dist/assets/tree-sitter-ruby.wasm +0 -0
  32. package/dist/assets/tree-sitter-rust.wasm +0 -0
  33. package/dist/assets/tree-sitter-scala.wasm +0 -0
  34. package/dist/assets/tree-sitter-tsx.wasm +0 -0
  35. package/dist/assets/tree-sitter-typescript.wasm +0 -0
  36. package/dist/assets/vectors.bin +0 -0
  37. package/dist/assets/vocab.txt +33731 -0
  38. package/dist/cli.js +9317 -0
  39. package/dist/embeddings/abbreviations.d.ts +7 -0
  40. package/dist/embeddings/index-builder.d.ts +12 -0
  41. package/dist/embeddings/index.d.ts +10 -0
  42. package/dist/embeddings/model.d.ts +126 -0
  43. package/dist/embeddings/searcher.d.ts +84 -0
  44. package/dist/embeddings/vectors.d.ts +77 -0
  45. package/dist/embeddings/words.d.ts +46 -0
  46. package/dist/index.d.ts +9 -0
  47. package/dist/index.js +8747 -0
  48. package/dist/model/index.d.ts +788 -0
  49. package/dist/model/registry.d.ts +687 -0
  50. package/dist/query/graph.d.ts +123 -0
  51. package/dist/query/index.d.ts +4 -0
  52. package/dist/query/name-search.d.ts +65 -0
  53. package/dist/query/semantic.d.ts +38 -0
  54. package/dist/query/text.d.ts +22 -0
  55. package/dist/retrieval/describe.d.ts +33 -0
  56. package/dist/retrieval/filter.d.ts +36 -0
  57. package/dist/retrieval/index.d.ts +7 -0
  58. package/dist/retrieval/markdown.d.ts +17 -0
  59. package/dist/retrieval/report.d.ts +291 -0
  60. package/dist/retrieval/resolve.d.ts +31 -0
  61. package/dist/retrieval/retriever.d.ts +105 -0
  62. package/dist/retrieval/summary.d.ts +27 -0
  63. package/dist/scanner/code/doc/clean.d.ts +36 -0
  64. package/dist/scanner/code/doc/index.d.ts +12 -0
  65. package/dist/scanner/code/doc/markdown.d.ts +8 -0
  66. package/dist/scanner/code/doc/python.d.ts +8 -0
  67. package/dist/scanner/code/doc/tagged.d.ts +19 -0
  68. package/dist/scanner/code/doc/types.d.ts +33 -0
  69. package/dist/scanner/code/doc/xml.d.ts +8 -0
  70. package/dist/scanner/code/example.d.ts +57 -0
  71. package/dist/scanner/code/extract.d.ts +113 -0
  72. package/dist/scanner/code/grammar.d.ts +44 -0
  73. package/dist/scanner/code/language.d.ts +183 -0
  74. package/dist/scanner/code/languages/c-family.d.ts +5 -0
  75. package/dist/scanner/code/languages/csharp.d.ts +3 -0
  76. package/dist/scanner/code/languages/ecmascript.d.ts +7 -0
  77. package/dist/scanner/code/languages/go.d.ts +3 -0
  78. package/dist/scanner/code/languages/index.d.ts +33 -0
  79. package/dist/scanner/code/languages/java.d.ts +3 -0
  80. package/dist/scanner/code/languages/kotlin.d.ts +3 -0
  81. package/dist/scanner/code/languages/php.d.ts +3 -0
  82. package/dist/scanner/code/languages/python.d.ts +3 -0
  83. package/dist/scanner/code/languages/ruby.d.ts +3 -0
  84. package/dist/scanner/code/languages/rust.d.ts +3 -0
  85. package/dist/scanner/code/languages/scala.d.ts +3 -0
  86. package/dist/scanner/code/languages/shared.d.ts +36 -0
  87. package/dist/scanner/code/planner.d.ts +107 -0
  88. package/dist/scanner/code/symbols.d.ts +134 -0
  89. package/dist/scanner/code/types.d.ts +126 -0
  90. package/dist/scanner/config.d.ts +42 -0
  91. package/dist/scanner/content.d.ts +73 -0
  92. package/dist/scanner/decisions/parse.d.ts +37 -0
  93. package/dist/scanner/decisions/planner.d.ts +42 -0
  94. package/dist/scanner/docs.d.ts +69 -0
  95. package/dist/scanner/files.d.ts +85 -0
  96. package/dist/scanner/glossary/parse.d.ts +40 -0
  97. package/dist/scanner/glossary/planner.d.ts +49 -0
  98. package/dist/scanner/glossary/terms.d.ts +116 -0
  99. package/dist/scanner/graph/builder.d.ts +114 -0
  100. package/dist/scanner/highlight.d.ts +54 -0
  101. package/dist/scanner/ignore.d.ts +25 -0
  102. package/dist/scanner/index.d.ts +43 -0
  103. package/dist/scanner/markdown/frontmatter.d.ts +24 -0
  104. package/dist/scanner/markdown/links.d.ts +60 -0
  105. package/dist/scanner/markdown/outline.d.ts +35 -0
  106. package/dist/scanner/markdown/renderer.d.ts +63 -0
  107. package/dist/scanner/openapi/planner.d.ts +96 -0
  108. package/dist/scanner/packages.d.ts +28 -0
  109. package/dist/scanner/reporter.d.ts +10 -0
  110. package/dist/scanner/scanner.d.ts +66 -0
  111. package/dist/scanner/schema/definitions.d.ts +79 -0
  112. package/dist/scanner/schema/describe.d.ts +105 -0
  113. package/dist/scanner/schema/planner.d.ts +49 -0
  114. package/dist/scanner/schema/registry.d.ts +68 -0
  115. package/dist/scanner/skills/classify.d.ts +21 -0
  116. package/dist/scanner/skills/layout.d.ts +46 -0
  117. package/dist/scanner/skills/planner.d.ts +61 -0
  118. package/dist/scanner/specs.d.ts +56 -0
  119. package/dist/scanner/sql/catalog.d.ts +98 -0
  120. package/dist/scanner/sql/cursor.d.ts +112 -0
  121. package/dist/scanner/sql/database.d.ts +51 -0
  122. package/dist/scanner/sql/parse.d.ts +122 -0
  123. package/dist/scanner/sql/planner.d.ts +69 -0
  124. package/dist/scanner/sql/query.d.ts +73 -0
  125. package/dist/scanner/sql/registry.d.ts +63 -0
  126. package/dist/scanner/sql/source.d.ts +10 -0
  127. package/dist/scanner/sql/statements.d.ts +42 -0
  128. package/dist/scanner/sql/tokens.d.ts +51 -0
  129. package/dist/scanner/tasks/layout.d.ts +52 -0
  130. package/dist/scanner/tasks/planner.d.ts +130 -0
  131. package/dist/scanner/tasks/schema.d.ts +88 -0
  132. package/dist/scanner/text.d.ts +14 -0
  133. package/package.json +104 -4
@@ -0,0 +1,21 @@
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
+ * @brief Classifies a file in a skill by 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
+ * @returns The kind of the file, from the first rule that matches it.
20
+ */
21
+ export declare function classifySkillFile(path: string, isSource: (path: string) => boolean): SkillFileKind;
@@ -0,0 +1,46 @@
1
+ /** File name that makes a directory a skill. */
2
+ export declare const SKILL_FILE = "SKILL.md";
3
+ /**
4
+ * A skill directory and the files that belong to it.
5
+ *
6
+ * @property directory - Root-relative directory of the `SKILL.md`. `''` for the root itself.
7
+ * @property skillFile - Root-relative path of the `SKILL.md`.
8
+ * @property files - Every other file of the skill, root-relative.
9
+ */
10
+ export interface SkillLayout {
11
+ readonly directory: string;
12
+ readonly skillFile: string;
13
+ readonly files: string[];
14
+ }
15
+ /**
16
+ * Tells whether a file lies in a directory or below it.
17
+ *
18
+ * @param file - Root-relative POSIX path.
19
+ * @param directory - Root-relative POSIX directory. `''` is the root and holds every file.
20
+ */
21
+ export declare function isInside(file: string, directory: string): boolean;
22
+ /** Directories of AI tools that hold installed skills. A `SKILL.md` elsewhere in a repository is a doc. */
23
+ export declare const AI_DIRECTORIES: readonly string[];
24
+ /**
25
+ * @brief Tells whether a file is inside the directory of an AI tool, such as `.claude/skills/deploy/SKILL.md`.
26
+ *
27
+ * @param file - Root-relative POSIX path.
28
+ */
29
+ export declare function isInAiDirectory(file: string): boolean;
30
+ /**
31
+ * @brief Finds the skills in a file list. A skill is a directory with a `SKILL.md` inside the directory of
32
+ * an AI tool, see `AI_DIRECTORIES`. Each file belongs to the deepest skill directory around it.
33
+ *
34
+ * @param files - Root-relative POSIX paths.
35
+ * @param anywhere - Counts a `SKILL.md` outside an AI directory too, for a directory the reader names as skills.
36
+ * @returns One layout per `SKILL.md`, deepest directory first.
37
+ */
38
+ export declare function skillLayouts(files: readonly string[], anywhere?: boolean): SkillLayout[];
39
+ /**
40
+ * @brief Finds the files of a list that belong to a skill, `SKILL.md` files included.
41
+ *
42
+ * @param files - Root-relative POSIX paths.
43
+ * @param anywhere - Counts a `SKILL.md` outside an AI directory too, as `skillLayouts` does.
44
+ * @returns The `SKILL.md` files and the other files of every skill in the list.
45
+ */
46
+ export declare function skillOwnedFiles(files: readonly string[], anywhere?: boolean): Set<string>;
@@ -0,0 +1,61 @@
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
+ * @brief 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
+ /**
27
+ * Creates a planner.
28
+ *
29
+ * @param graph - Receives the skill, folder and file nodes.
30
+ * @param files - Renders the `SKILL.md` and the other files.
31
+ * @param code - Plans the source files of skills.
32
+ * @param resolvers - Links what the skill files refer to.
33
+ * @param specs - Plans the JSON and YAML files that are specs.
34
+ */
35
+ constructor(graph: GraphBuilder, files: FileRenderer, code: CodePlanner, resolvers: ProseResolvers, specs: SpecPlanner);
36
+ /**
37
+ * Adds the skills of every source, sorted by name, each with a unique slug.
38
+ *
39
+ * @param section - Node of the skills section, the parent of every skill.
40
+ * @param sources - Sources to read the skills from, each with the files it holds.
41
+ */
42
+ plan(section: NodeRef, sources: readonly Source[]): Promise<void>;
43
+ /**
44
+ * @brief Reads the `SKILL.md` of a skill and picks its name: the `name` field of
45
+ * the frontmatter, else the first `#` heading, else the directory name.
46
+ *
47
+ * @param source - Source the skill is in.
48
+ * @param layout - Files of the skill.
49
+ * @returns The skill with its text and name.
50
+ */
51
+ private read;
52
+ /**
53
+ * @brief Adds one skill node and a node for each of its files, under folder nodes
54
+ * that mirror the skill directory.
55
+ *
56
+ * @param section - Node of the skills section, the parent of the skill.
57
+ * @param skill - The skill as read from disk.
58
+ * @param slugs - Slugs already taken by other skills. Receives the slug of this one.
59
+ */
60
+ private planSkill;
61
+ }
@@ -0,0 +1,56 @@
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
+ * Kind of a spec: 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
+ * @param path - Path of the file, whose name is checked against the schema names.
16
+ * @param document - The parsed file.
17
+ * @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.
18
+ */
19
+ export declare function specKind(path: string, document: JsonObject): SpecKind | null;
20
+ /**
21
+ * @brief Adds the specs among the JSON and YAML files of a scan to the graph.
22
+ *
23
+ * Used by `DocPlanner` and `SkillPlanner` for every JSON or YAML file, before
24
+ * they add the file as plain text. The file is parsed once here, and goes to
25
+ * the planner of its kind. Created by `RepositoryScanner` for every scan.
26
+ */
27
+ export declare class SpecPlanner {
28
+ private readonly openapi;
29
+ private readonly schemas;
30
+ private readonly reporter;
31
+ /**
32
+ * Keeps the planner of each spec kind.
33
+ *
34
+ * @param openapi - Plans OpenAPI documents.
35
+ * @param schemas - Plans JSON Schemas.
36
+ * @param reporter - Receives files that cannot be read.
37
+ */
38
+ constructor(openapi: OpenApiPlanner, schemas: JsonSchemaPlanner, reporter?: Reporter);
39
+ /** Tells whether a file can be a spec: true for a JSON or YAML file. */
40
+ handles(path: string): boolean;
41
+ /**
42
+ * Reads one file and adds it when it is a spec.
43
+ *
44
+ * @param file - The file to read, with its root and path.
45
+ * @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.
46
+ * @returns The node of the file, or `null` when the file is no spec or cannot be parsed.
47
+ */
48
+ plan(file: DocFile, parent: () => NodeRef): Promise<NodeRef | null>;
49
+ /**
50
+ * Parses a file.
51
+ *
52
+ * @param file - The file to read, with its root and path.
53
+ * @returns The parsed object, or `null` for a file that is too large, holds no object or is not valid.
54
+ */
55
+ private read;
56
+ }
@@ -0,0 +1,98 @@
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
+ /**
10
+ * One SQL file of a catalog with the entries it holds.
11
+ *
12
+ * @property file - The SQL file, with its root and paths.
13
+ * @property queries - Entries from `parseQueryFile`. Not empty.
14
+ */
15
+ export interface CatalogFile {
16
+ readonly file: SourceFile;
17
+ readonly queries: readonly ParsedQuery[];
18
+ }
19
+ /**
20
+ * Where a catalog goes in the tree and what it is called.
21
+ *
22
+ * @property parent - Folder or section the catalog goes in.
23
+ * @property name - Name the catalog is shown under.
24
+ * @property slug - Segment of the route of the catalog, when it is not the name.
25
+ * @property path - Path of the directory of the catalog, as the site shows it.
26
+ */
27
+ export interface CatalogPlace {
28
+ readonly parent: NodeRef;
29
+ readonly name: string;
30
+ readonly slug?: string;
31
+ readonly path: string;
32
+ }
33
+ /**
34
+ * @brief Adds query catalogs to the graph: one `catalog` node per directory, one
35
+ * `query` node per entry, one `parameter` node per placeholder and one
36
+ * `field` node per column of the rows an entry returns. A table an entry
37
+ * names becomes a `reads` or a `writes` edge to that table.
38
+ *
39
+ * `DatabasePlanner` calls `add` once per directory that holds SQL files
40
+ * without tables. Tables and columns are looked up when the content of the
41
+ * graph is built, so a query can name a table of any file of the scan.
42
+ * `RepositoryScanner` creates one per scan with the `TableRegistry` it shares
43
+ * with the `SqlPlanner`; `DatabasePlanner` shows the wiring.
44
+ */
45
+ export declare class CatalogPlanner {
46
+ private readonly graph;
47
+ private readonly markdown;
48
+ private readonly highlighter;
49
+ private readonly resolvers;
50
+ private readonly tables;
51
+ /**
52
+ * Creates a planner.
53
+ *
54
+ * @param graph - Receives the catalog, entry, parameter and field nodes.
55
+ * @param markdown - Renders the notes of entries.
56
+ * @param highlighter - Highlights the SQL of entries.
57
+ * @param resolvers - Links what notes refer to.
58
+ * @param tables - Finds the tables and columns that entries name.
59
+ */
60
+ constructor(graph: GraphBuilder, markdown: MarkdownRenderer, highlighter: CodeHighlighter, resolvers: ProseResolvers, tables: TableRegistry);
61
+ /**
62
+ * Adds one catalog with its entries.
63
+ *
64
+ * @param place - Where the catalog goes in the tree and what it is called.
65
+ * @param files - The SQL files of the catalog, in display order.
66
+ * @returns The node of the catalog.
67
+ */
68
+ add(place: CatalogPlace, files: readonly CatalogFile[]): NodeRef;
69
+ /**
70
+ * Adds one entry with its placeholders and its result columns.
71
+ *
72
+ * @param catalog - Node of the catalog.
73
+ * @param file - The SQL file the entry is in.
74
+ * @param query - The entry as parsed.
75
+ * @param anchors - Anchors the catalog uses already. The anchor of the entry is added.
76
+ * @returns The node of the entry.
77
+ */
78
+ private addQuery;
79
+ /**
80
+ * Finds the table column a column of a statement means.
81
+ *
82
+ * @param ref - The column as the statement names it, or `null`.
83
+ * @param query - The entry the statement is in.
84
+ * @param path - Display path (`SourceFile.displayPath`) of the file of the entry.
85
+ * @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`.
86
+ */
87
+ private columnOf;
88
+ /**
89
+ * @brief Replaces `*` and `t.*` in the result columns of an entry by the columns
90
+ * of the tables they stand for. That needs the tables at the time the
91
+ * entry is added, so `DatabasePlanner` adds schema files first.
92
+ *
93
+ * @param query - The entry whose result columns are expanded.
94
+ * @param path - Display path (`SourceFile.displayPath`) of the file of the entry.
95
+ * @returns The result columns, with every star replaced whose tables the scan has. Any other star stays.
96
+ */
97
+ private expand;
98
+ }
@@ -0,0 +1,112 @@
1
+ import type { SqlToken } from './tokens';
2
+ /**
3
+ * @brief 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
+ * @brief 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 tokens - The tokens to walk, in order.
23
+ * @param source - The SQL text the tokens come from, for reading text back as written.
24
+ */
25
+ constructor(tokens: readonly SqlToken[], source: string);
26
+ /**
27
+ * Tells whether every token is taken.
28
+ */
29
+ get done(): boolean;
30
+ /**
31
+ * Looks at a token without taking it.
32
+ *
33
+ * @param offset - Tokens ahead of the current one.
34
+ * @returns The token, or `undefined` behind the end.
35
+ */
36
+ peek(offset?: number): SqlToken | undefined;
37
+ /**
38
+ * Takes the current token.
39
+ *
40
+ * @returns The token the cursor was on.
41
+ * @throws {SqlSyntaxError} At the end of the statement.
42
+ */
43
+ next(): SqlToken;
44
+ /**
45
+ * Tells whether the current token is one of the given keywords.
46
+ *
47
+ * @param words - Keywords in capitals.
48
+ * @param offset - Tokens ahead of the current one.
49
+ * @returns True for an unquoted word that is one of them, whatever its case.
50
+ */
51
+ isWord(words: readonly string[], offset?: number): boolean;
52
+ /**
53
+ * Takes the tokens ahead when they are the given keywords in this order.
54
+ *
55
+ * @param words - Keywords in capitals.
56
+ * @returns True when all were there and are taken. False leaves the cursor in place.
57
+ */
58
+ accept(...words: string[]): boolean;
59
+ /**
60
+ * Tells whether the current token is a given symbol.
61
+ *
62
+ * @param symbol - One character.
63
+ */
64
+ isSymbol(symbol: string): boolean;
65
+ /**
66
+ * Takes the current token when it is a given symbol.
67
+ *
68
+ * @param symbol - One character.
69
+ */
70
+ acceptSymbol(symbol: string): boolean;
71
+ /**
72
+ * Takes a name: an unquoted word, a quoted identifier or a string.
73
+ *
74
+ * @returns The name without quotes.
75
+ * @throws {SqlSyntaxError} When the current token cannot be a name.
76
+ */
77
+ name(): string;
78
+ /**
79
+ * Takes a name that may have a schema in front, as in `main.booking`.
80
+ *
81
+ * @returns The last part of the name.
82
+ */
83
+ qualifiedName(): string;
84
+ /**
85
+ * Takes a group in parentheses with everything inside it.
86
+ *
87
+ * @returns The tokens between the parentheses.
88
+ * @throws {SqlSyntaxError} When the current token opens no group, or the group never closes.
89
+ */
90
+ group(): SqlToken[];
91
+ /**
92
+ * Reads SQL back as written, with runs of whitespace as one space.
93
+ *
94
+ * @param from - First token of the text.
95
+ * @param to - Last token of the text. Defaults to the token in front of the cursor.
96
+ */
97
+ text(from: SqlToken, to?: SqlToken | undefined): string;
98
+ /**
99
+ * Creates a cursor for some of the tokens of the same text.
100
+ *
101
+ * @param tokens - Tokens of part of the statement, from the same text.
102
+ * @returns A cursor at the first of them.
103
+ */
104
+ over(tokens: readonly SqlToken[]): TokenCursor;
105
+ }
106
+ /**
107
+ * Splits tokens at the commas that are not inside parentheses.
108
+ *
109
+ * @param tokens - Tokens of a list, without the parentheses around it.
110
+ * @returns The tokens of each item. An empty item is left out.
111
+ */
112
+ export declare function splitAtCommas(tokens: readonly SqlToken[]): SqlToken[][];
@@ -0,0 +1,51 @@
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
+ * @brief 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.
14
+ *
15
+ * `RepositoryScanner` creates one per scan and calls `planTree` once per
16
+ * source directory. The `SqlPlanner` and the `CatalogPlanner` share one
17
+ * `TableRegistry`, so queries can find the tables of schema files.
18
+ *
19
+ * @example
20
+ * const tables = new TableRegistry();
21
+ * const sql = new SqlPlanner(graph, markdown, highlighter, resolvers, tables, reporter);
22
+ * const databases = new DatabasePlanner(
23
+ * graph,
24
+ * sql,
25
+ * new CatalogPlanner(graph, markdown, highlighter, resolvers, tables),
26
+ * reporter,
27
+ * );
28
+ * await databases.planTree(section, source);
29
+ */
30
+ export declare class DatabasePlanner {
31
+ private readonly graph;
32
+ private readonly schemas;
33
+ private readonly catalogs;
34
+ private readonly reporter;
35
+ /**
36
+ * Creates a planner.
37
+ *
38
+ * @param graph - Receives the database section nodes.
39
+ * @param schemas - Plans the schema files.
40
+ * @param catalogs - Plans the query catalogs.
41
+ * @param reporter - Receives files that cannot be read.
42
+ */
43
+ constructor(graph: GraphBuilder, schemas: SqlPlanner, catalogs: CatalogPlanner, reporter?: Reporter);
44
+ /**
45
+ * Adds every SQL file of `source` below `section`.
46
+ *
47
+ * @param section - Node of the database section.
48
+ * @param source - The SQL files to read, with their root and prefix.
49
+ */
50
+ planTree(section: NodeRef, source: Source): Promise<void>;
51
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * What a `REFERENCES` clause states.
3
+ *
4
+ * @property table - Name of the referenced table.
5
+ * @property columns - Referenced columns. Empty when the clause names none, which means the primary key.
6
+ * @property onDelete - Action in capitals, or `''`.
7
+ * @property onUpdate - Action in capitals, or `''`.
8
+ */
9
+ export interface ParsedReference {
10
+ readonly table: string;
11
+ readonly columns: readonly string[];
12
+ readonly onDelete: string;
13
+ readonly onUpdate: string;
14
+ }
15
+ /**
16
+ * A foreign key of a table, from a column or from a table constraint.
17
+ *
18
+ * @property name - Name of the constraint, or `''`.
19
+ * @property sourceColumns - Columns of the table that hold the key.
20
+ */
21
+ export interface ParsedForeignKey extends ParsedReference {
22
+ readonly name: string;
23
+ readonly sourceColumns: readonly string[];
24
+ }
25
+ /**
26
+ * One column of a table as its statement writes it.
27
+ *
28
+ * @property name - Name of the column.
29
+ * @property type - Declared type as written, with single spaces. `''` for a column without one.
30
+ * @property notNull - True when the column is declared `NOT NULL`.
31
+ * @property defaultValue - Default value as written, or `null`.
32
+ * @property constraints - Other constraints of the column as written, such as `UNIQUE`, `CHECK (n > 0)` or `COLLATE NOCASE`.
33
+ * @property description - Markdown from the comment behind or above the column.
34
+ */
35
+ export interface ParsedColumn {
36
+ readonly name: string;
37
+ readonly type: string;
38
+ readonly notNull: boolean;
39
+ readonly defaultValue: string | null;
40
+ readonly constraints: readonly string[];
41
+ readonly description: string;
42
+ }
43
+ /**
44
+ * An index of a table, from a `CREATE INDEX` statement.
45
+ *
46
+ * @property name - Name of the index.
47
+ * @property columns - Indexed columns or expressions as written.
48
+ * @property unique - True for a `UNIQUE` index.
49
+ */
50
+ export interface ParsedIndex {
51
+ readonly name: string;
52
+ readonly columns: readonly string[];
53
+ readonly unique: boolean;
54
+ }
55
+ /**
56
+ * One table of a schema.
57
+ *
58
+ * @property name - Name of the table.
59
+ * @property line - 1-based line of the statement.
60
+ * @property description - Markdown from the comment above the statement.
61
+ * @property columns - Columns of the table.
62
+ * @property primaryKey - Columns of the primary key, in key order.
63
+ * @property foreignKeys - Foreign keys of the table.
64
+ * @property constraints - Table constraints that are no key, as written.
65
+ * @property options - `WITHOUT ROWID`, `STRICT`, `VIRTUAL`, `TEMPORARY`.
66
+ * @property indexes - Indexes of the table.
67
+ */
68
+ export interface ParsedTable {
69
+ readonly name: string;
70
+ readonly line: number;
71
+ readonly description: string;
72
+ readonly columns: readonly ParsedColumn[];
73
+ readonly primaryKey: readonly string[];
74
+ readonly foreignKeys: readonly ParsedForeignKey[];
75
+ readonly constraints: readonly string[];
76
+ readonly options: readonly string[];
77
+ readonly indexes: readonly ParsedIndex[];
78
+ }
79
+ /**
80
+ * A view or a trigger of a schema.
81
+ *
82
+ * @property kind - `view` or `trigger`.
83
+ * @property name - Name of the view or trigger.
84
+ * @property table - The table a trigger fires on. `''` for a view.
85
+ * @property line - 1-based line of the statement.
86
+ * @property description - Markdown from the comment above the statement.
87
+ * @property sql - The statement as written, without the closing semicolon.
88
+ */
89
+ export interface ParsedObject {
90
+ readonly kind: 'view' | 'trigger';
91
+ readonly name: string;
92
+ readonly table: string;
93
+ readonly line: number;
94
+ readonly description: string;
95
+ readonly sql: string;
96
+ }
97
+ /**
98
+ * What a schema file declares, from `parseSqlSchema`.
99
+ *
100
+ * @property intro - Markdown from the comments that open the file.
101
+ * @property tables - Tables the file creates, in file order.
102
+ * @property objects - Views and triggers the file creates, in file order.
103
+ */
104
+ export interface ParsedSchema {
105
+ readonly intro: string;
106
+ readonly tables: readonly ParsedTable[];
107
+ readonly objects: readonly ParsedObject[];
108
+ }
109
+ /**
110
+ * @brief Reads the tables, indexes, views and triggers of a SQLite schema file.
111
+ * Statements of any other kind, and statements that cannot be read, are
112
+ * skipped. The SQL is read as text and never run.
113
+ *
114
+ * A comment directly above a statement describes its table, view or trigger.
115
+ * A comment behind a column on the same line, or directly above it, describes
116
+ * the column. The comments that open the file, apart from the first
117
+ * statement, are the introduction.
118
+ *
119
+ * @param source - Text of the file.
120
+ * @returns What the file declares, in file order.
121
+ */
122
+ export declare function parseSqlSchema(source: string): ParsedSchema;
@@ -0,0 +1,69 @@
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 Reporter } from '../reporter';
8
+ import { type ParsedSchema } from './parse';
9
+ import type { TableRegistry } from './registry';
10
+ /**
11
+ * @brief Adds SQL schema files to the graph: one `database` node per file, one
12
+ * `table` node per table and one `field` node per column. A foreign key
13
+ * becomes a `references` edge from its table to the table it points at.
14
+ *
15
+ * `DatabasePlanner` calls `add` for every schema file of the repository, and
16
+ * `CodePlanner` calls `plan` for a `.sql` file that belongs to a skill.
17
+ * `RepositoryScanner` creates one per scan with the `TableRegistry` it shares
18
+ * with the `CatalogPlanner`; `DatabasePlanner` shows the wiring.
19
+ */
20
+ export declare class SqlPlanner {
21
+ private readonly graph;
22
+ private readonly markdown;
23
+ private readonly highlighter;
24
+ private readonly resolvers;
25
+ private readonly tables;
26
+ private readonly reporter;
27
+ /**
28
+ * Creates a planner.
29
+ *
30
+ * @param graph - Receives the database, table and field nodes.
31
+ * @param markdown - Renders comments.
32
+ * @param highlighter - Highlights the statements of views and triggers.
33
+ * @param resolvers - Links what comments refer to.
34
+ * @param tables - Receives every table with its columns, and finds the targets of foreign keys.
35
+ * @param reporter - Receives files that cannot be read.
36
+ */
37
+ constructor(graph: GraphBuilder, markdown: MarkdownRenderer, highlighter: CodeHighlighter, resolvers: ProseResolvers, tables: TableRegistry, reporter?: Reporter);
38
+ /**
39
+ * Tells whether a file is SQL: its extension is `.sql`, in any case.
40
+ */
41
+ handles(path: string): boolean;
42
+ /**
43
+ * Reads one SQL file and adds its nodes when it creates a table.
44
+ *
45
+ * @param file - The SQL file to read.
46
+ * @param parent - Gives the folder or skill the file is in. Called only when the file creates a table, so a folder with nothing else in it is not added.
47
+ * @returns The node of the file, or `null` when it creates no table or cannot be read.
48
+ */
49
+ plan(file: SourceFile, parent: () => NodeRef): Promise<NodeRef | null>;
50
+ /**
51
+ * Adds the nodes of one schema file.
52
+ *
53
+ * @param file - The SQL file to add.
54
+ * @param schema - What the file declares, from `parseSqlSchema`.
55
+ * @param parent - The folder or skill the file is in.
56
+ * @returns The node of the file.
57
+ */
58
+ add(file: SourceFile, schema: ParsedSchema, parent: NodeRef): NodeRef;
59
+ /**
60
+ * @brief Resolves a foreign key against the tables of the scan, and records the
61
+ * edge to its target.
62
+ *
63
+ * @param from - Node of the table that holds the key.
64
+ * @param key - The foreign key as the statement wrote it.
65
+ * @param path - Display path (`SourceFile.displayPath`) of the file the key is in.
66
+ * @returns The key with its target, and with the primary key of the target as its columns when the statement names none.
67
+ */
68
+ private foreignKey;
69
+ }