@memberjunction/db-auto-doc 6.2.0-edge.3 → 6.2.0-edge.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +200 -3
  2. package/dist/commands/analyze.d.ts +1 -0
  3. package/dist/commands/analyze.d.ts.map +1 -1
  4. package/dist/commands/analyze.js +6 -0
  5. package/dist/commands/analyze.js.map +1 -1
  6. package/dist/commands/export.d.ts +32 -15
  7. package/dist/commands/export.d.ts.map +1 -1
  8. package/dist/commands/export.js +144 -14
  9. package/dist/commands/export.js.map +1 -1
  10. package/dist/commands/init.js +1 -1
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/core/AnalysisEngine.d.ts +15 -6
  13. package/dist/core/AnalysisEngine.d.ts.map +1 -1
  14. package/dist/core/AnalysisEngine.js +41 -40
  15. package/dist/core/AnalysisEngine.js.map +1 -1
  16. package/dist/core/AnalysisOrchestrator.d.ts +25 -1
  17. package/dist/core/AnalysisOrchestrator.d.ts.map +1 -1
  18. package/dist/core/AnalysisOrchestrator.js +163 -27
  19. package/dist/core/AnalysisOrchestrator.js.map +1 -1
  20. package/dist/core/PKProposalGate.d.ts +22 -0
  21. package/dist/core/PKProposalGate.d.ts.map +1 -0
  22. package/dist/core/PKProposalGate.js +52 -0
  23. package/dist/core/PKProposalGate.js.map +1 -0
  24. package/dist/database/Database.d.ts +8 -0
  25. package/dist/database/Database.d.ts.map +1 -1
  26. package/dist/database/Database.js +23 -1
  27. package/dist/database/Database.js.map +1 -1
  28. package/dist/discovery/EnumCandidateGate.d.ts +19 -0
  29. package/dist/discovery/EnumCandidateGate.d.ts.map +1 -1
  30. package/dist/discovery/EnumCandidateGate.js +47 -5
  31. package/dist/discovery/EnumCandidateGate.js.map +1 -1
  32. package/dist/discovery/FKGraphWalker.d.ts +35 -0
  33. package/dist/discovery/FKGraphWalker.d.ts.map +1 -1
  34. package/dist/discovery/FKGraphWalker.js +113 -12
  35. package/dist/discovery/FKGraphWalker.js.map +1 -1
  36. package/dist/discovery/LLMDiscoveryValidator.d.ts +2 -0
  37. package/dist/discovery/LLMDiscoveryValidator.d.ts.map +1 -1
  38. package/dist/discovery/LLMDiscoveryValidator.js +20 -9
  39. package/dist/discovery/LLMDiscoveryValidator.js.map +1 -1
  40. package/dist/discovery/OrganicKeyDetector.d.ts.map +1 -1
  41. package/dist/discovery/OrganicKeyDetector.js +8 -2
  42. package/dist/discovery/OrganicKeyDetector.js.map +1 -1
  43. package/dist/discovery/StructuralPhase.d.ts +27 -5
  44. package/dist/discovery/StructuralPhase.d.ts.map +1 -1
  45. package/dist/discovery/StructuralPhase.js +42 -9
  46. package/dist/discovery/StructuralPhase.js.map +1 -1
  47. package/dist/discovery/TransitiveBridgeDetector.d.ts +5 -1
  48. package/dist/discovery/TransitiveBridgeDetector.d.ts.map +1 -1
  49. package/dist/discovery/TransitiveBridgeDetector.js +25 -3
  50. package/dist/discovery/TransitiveBridgeDetector.js.map +1 -1
  51. package/dist/drivers/BaseAutoDocDriver.d.ts +6 -1
  52. package/dist/drivers/BaseAutoDocDriver.d.ts.map +1 -1
  53. package/dist/drivers/BaseAutoDocDriver.js +3 -5
  54. package/dist/drivers/BaseAutoDocDriver.js.map +1 -1
  55. package/dist/drivers/IndexCatalog.d.ts +54 -0
  56. package/dist/drivers/IndexCatalog.d.ts.map +1 -0
  57. package/dist/drivers/IndexCatalog.js +145 -0
  58. package/dist/drivers/IndexCatalog.js.map +1 -0
  59. package/dist/drivers/MySQLDriver.d.ts +5 -1
  60. package/dist/drivers/MySQLDriver.d.ts.map +1 -1
  61. package/dist/drivers/MySQLDriver.js +15 -6
  62. package/dist/drivers/MySQLDriver.js.map +1 -1
  63. package/dist/drivers/PostgreSQLDriver.d.ts +14 -2
  64. package/dist/drivers/PostgreSQLDriver.d.ts.map +1 -1
  65. package/dist/drivers/PostgreSQLDriver.js +52 -19
  66. package/dist/drivers/PostgreSQLDriver.js.map +1 -1
  67. package/dist/drivers/SQLServerDriver.d.ts +5 -1
  68. package/dist/drivers/SQLServerDriver.d.ts.map +1 -1
  69. package/dist/drivers/SQLServerDriver.js +13 -1
  70. package/dist/drivers/SQLServerDriver.js.map +1 -1
  71. package/dist/generators/AdditionalSchemaInfoGenerator.d.ts +34 -0
  72. package/dist/generators/AdditionalSchemaInfoGenerator.d.ts.map +1 -1
  73. package/dist/generators/AdditionalSchemaInfoGenerator.js +85 -4
  74. package/dist/generators/AdditionalSchemaInfoGenerator.js.map +1 -1
  75. package/dist/generators/ErdClusterGenerator.d.ts +44 -0
  76. package/dist/generators/ErdClusterGenerator.d.ts.map +1 -0
  77. package/dist/generators/ErdClusterGenerator.js +216 -0
  78. package/dist/generators/ErdClusterGenerator.js.map +1 -0
  79. package/dist/generators/ErdClusterer.d.ts +130 -0
  80. package/dist/generators/ErdClusterer.d.ts.map +1 -0
  81. package/dist/generators/ErdClusterer.js +308 -0
  82. package/dist/generators/ErdClusterer.js.map +1 -0
  83. package/dist/generators/HTMLGenerator.d.ts +6 -0
  84. package/dist/generators/HTMLGenerator.d.ts.map +1 -1
  85. package/dist/generators/HTMLGenerator.js +41 -6
  86. package/dist/generators/HTMLGenerator.js.map +1 -1
  87. package/dist/generators/MermaidGenerator.d.ts +3 -0
  88. package/dist/generators/MermaidGenerator.d.ts.map +1 -1
  89. package/dist/generators/MermaidGenerator.js +4 -0
  90. package/dist/generators/MermaidGenerator.js.map +1 -1
  91. package/dist/generators/index.d.ts +2 -0
  92. package/dist/generators/index.d.ts.map +1 -1
  93. package/dist/generators/index.js +2 -0
  94. package/dist/generators/index.js.map +1 -1
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +2 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/plugins/BaseAutoDocPlugin.d.ts +33 -0
  100. package/dist/plugins/BaseAutoDocPlugin.d.ts.map +1 -0
  101. package/dist/plugins/BaseAutoDocPlugin.js +70 -0
  102. package/dist/plugins/BaseAutoDocPlugin.js.map +1 -0
  103. package/dist/plugins/PluginManager.d.ts +54 -0
  104. package/dist/plugins/PluginManager.d.ts.map +1 -0
  105. package/dist/plugins/PluginManager.js +115 -0
  106. package/dist/plugins/PluginManager.js.map +1 -0
  107. package/dist/plugins/builtins.d.ts +13 -0
  108. package/dist/plugins/builtins.d.ts.map +1 -0
  109. package/dist/plugins/builtins.js +12 -0
  110. package/dist/plugins/builtins.js.map +1 -0
  111. package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts +25 -0
  112. package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts.map +1 -0
  113. package/dist/plugins/index-advisor/IndexAdvisorPlugin.js +128 -0
  114. package/dist/plugins/index-advisor/IndexAdvisorPlugin.js.map +1 -0
  115. package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts +111 -0
  116. package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts.map +1 -0
  117. package/dist/plugins/index-advisor/IndexAdvisorTypes.js +5 -0
  118. package/dist/plugins/index-advisor/IndexAdvisorTypes.js.map +1 -0
  119. package/dist/plugins/index-advisor/IndexLLMReview.d.ts +48 -0
  120. package/dist/plugins/index-advisor/IndexLLMReview.d.ts.map +1 -0
  121. package/dist/plugins/index-advisor/IndexLLMReview.js +181 -0
  122. package/dist/plugins/index-advisor/IndexLLMReview.js.map +1 -0
  123. package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts +28 -0
  124. package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts.map +1 -0
  125. package/dist/plugins/index-advisor/IndexMigrationGenerator.js +98 -0
  126. package/dist/plugins/index-advisor/IndexMigrationGenerator.js.map +1 -0
  127. package/dist/plugins/index-advisor/IndexRules.d.ts +19 -0
  128. package/dist/plugins/index-advisor/IndexRules.d.ts.map +1 -0
  129. package/dist/plugins/index-advisor/IndexRules.js +154 -0
  130. package/dist/plugins/index-advisor/IndexRules.js.map +1 -0
  131. package/dist/plugins/index.d.ts +13 -0
  132. package/dist/plugins/index.d.ts.map +1 -0
  133. package/dist/plugins/index.js +13 -0
  134. package/dist/plugins/index.js.map +1 -0
  135. package/dist/plugins/types.d.ts +82 -0
  136. package/dist/plugins/types.d.ts.map +1 -0
  137. package/dist/plugins/types.js +9 -0
  138. package/dist/plugins/types.js.map +1 -0
  139. package/dist/types/analysis.d.ts +2 -0
  140. package/dist/types/analysis.d.ts.map +1 -1
  141. package/dist/types/config.d.ts +52 -0
  142. package/dist/types/config.d.ts.map +1 -1
  143. package/dist/types/config.js +7 -4
  144. package/dist/types/config.js.map +1 -1
  145. package/dist/types/discovery.d.ts +2 -0
  146. package/dist/types/discovery.d.ts.map +1 -1
  147. package/dist/types/driver.d.ts +30 -0
  148. package/dist/types/driver.d.ts.map +1 -1
  149. package/dist/types/driver.js +5 -1
  150. package/dist/types/driver.js.map +1 -1
  151. package/dist/types/index.d.ts +1 -0
  152. package/dist/types/index.d.ts.map +1 -1
  153. package/dist/types/index.js +1 -0
  154. package/dist/types/index.js.map +1 -1
  155. package/dist/types/state.d.ts +36 -0
  156. package/dist/types/state.d.ts.map +1 -1
  157. package/dist/utils/config-loader.d.ts +5 -0
  158. package/dist/utils/config-loader.d.ts.map +1 -1
  159. package/dist/utils/config-loader.js +38 -1
  160. package/dist/utils/config-loader.js.map +1 -1
  161. package/dist/utils/index-hints.d.ts +36 -0
  162. package/dist/utils/index-hints.d.ts.map +1 -0
  163. package/dist/utils/index-hints.js +65 -0
  164. package/dist/utils/index-hints.js.map +1 -0
  165. package/dist/utils/index.d.ts +1 -0
  166. package/dist/utils/index.d.ts.map +1 -1
  167. package/dist/utils/index.js +1 -0
  168. package/dist/utils/index.js.map +1 -1
  169. package/dist/utils/llm-factory.d.ts +1 -0
  170. package/dist/utils/llm-factory.d.ts.map +1 -1
  171. package/dist/utils/llm-factory.js +6 -1
  172. package/dist/utils/llm-factory.js.map +1 -1
  173. package/package.json +5 -5
  174. package/prompts/fk-pruning-table.md +13 -1
  175. package/prompts/index-review.md +60 -0
  176. package/prompts/pk-pruning-table.md +10 -0
  177. package/prompts/table-analysis.md +11 -0
package/dist/index.d.ts CHANGED
@@ -11,4 +11,5 @@ export * from './core/index.js';
11
11
  export * from './core/AnalysisOrchestrator.js';
12
12
  export * from './generators/index.js';
13
13
  export * from './utils/index.js';
14
+ export * from './plugins/index.js';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAG/C,cAAc,uBAAuB,CAAC;AAGtC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAG/C,cAAc,uBAAuB,CAAC;AAGtC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -19,4 +19,6 @@ export * from './core/AnalysisOrchestrator.js';
19
19
  export * from './generators/index.js';
20
20
  // Utilities
21
21
  export * from './utils/index.js';
22
+ // Plugin system
23
+ export * from './plugins/index.js';
22
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2DAA2D;AAC3D,cAAc,gBAAgB,CAAC;AAE/B,aAAa;AACb,cAAc,kBAAkB,CAAC;AAEjC,iBAAiB;AACjB,cAAc,qBAAqB,CAAC;AAEpC,UAAU;AACV,cAAc,oBAAoB,CAAC;AAEnC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AAEjC,kBAAkB;AAClB,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAE/C,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,YAAY;AACZ,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2DAA2D;AAC3D,cAAc,gBAAgB,CAAC;AAE/B,aAAa;AACb,cAAc,kBAAkB,CAAC;AAEjC,iBAAiB;AACjB,cAAc,qBAAqB,CAAC;AAEpC,UAAU;AACV,cAAc,oBAAoB,CAAC;AAEnC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AAEjC,kBAAkB;AAClB,cAAc,iBAAiB,CAAC;AAChC,cAAc,gCAAgC,CAAC;AAE/C,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,YAAY;AACZ,cAAc,kBAAkB,CAAC;AAEjC,gBAAgB;AAChB,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Base class for DBAutoDoc plugins.
3
+ *
4
+ * Subclass it, register it with `@RegisterClass(BaseAutoDocPlugin, '<Name>')`, and override
5
+ * only the hooks you need. Every hook is optional and defaults to a no-op. A hook that throws
6
+ * is recorded in the state file and does not stop the analysis run.
7
+ */
8
+ import type { AutoDocExporter, AutoDocPluginContext, AutoDocPluginStateSection } from './types.js';
9
+ export declare abstract class BaseAutoDocPlugin {
10
+ /** Runs after the state is loaded, before connecting to the database. */
11
+ OnPreRun(_context: AutoDocPluginContext): Promise<void>;
12
+ /** Runs after schema introspection and data sampling. */
13
+ OnAfterIntrospection(_context: AutoDocPluginContext): Promise<void>;
14
+ /** Runs after primary/foreign key discovery. */
15
+ OnAfterDiscovery(_context: AutoDocPluginContext): Promise<void>;
16
+ /** Runs after the LLM description loop. */
17
+ OnAfterDescriptions(_context: AutoDocPluginContext): Promise<void>;
18
+ /** Runs after key pruning (also runs when pruning is not configured). */
19
+ OnAfterPruning(_context: AutoDocPluginContext): Promise<void>;
20
+ /** Runs last, while the database connection is still open. */
21
+ OnPostRun(_context: AutoDocPluginContext): Promise<void>;
22
+ /** Export formats this plugin contributes to `db-auto-doc export --format`. */
23
+ GetExporters(): AutoDocExporter[];
24
+ /** Dispatches a hook name to the matching method. */
25
+ RunHook(context: AutoDocPluginContext): Promise<void>;
26
+ /** Reads this plugin's persisted data from the state file, if any. */
27
+ protected GetData<T extends object>(context: AutoDocPluginContext, pluginName: string): T | undefined;
28
+ /** Writes this plugin's data into its own section of the state file. */
29
+ protected SetData<T extends object>(context: AutoDocPluginContext, pluginName: string, data: T): void;
30
+ /** Returns the plugin's state section, creating it when missing. */
31
+ static EnsureSection(context: Pick<AutoDocPluginContext, 'State'>, pluginName: string): AutoDocPluginStateSection;
32
+ }
33
+ //# sourceMappingURL=BaseAutoDocPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAutoDocPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/BaseAutoDocPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EAEpB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAGpB,8BACsB,iBAAiB;IACrC,yEAAyE;IAC5D,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAEpE,yDAAyD;IAC5C,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhF,gDAAgD;IACnC,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5E,2CAA2C;IAC9B,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/E,yEAAyE;IAC5D,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1E,8DAA8D;IACjD,SAAS,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAErE,+EAA+E;IACxE,YAAY,IAAI,eAAe,EAAE;IAIxC,qDAAqD;IACxC,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlE,sEAAsE;IACtE,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIrG,wEAAwE;IACxE,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAKrG,oEAAoE;WACtD,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,yBAAyB;CASzH"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Base class for DBAutoDoc plugins.
3
+ *
4
+ * Subclass it, register it with `@RegisterClass(BaseAutoDocPlugin, '<Name>')`, and override
5
+ * only the hooks you need. Every hook is optional and defaults to a no-op. A hook that throws
6
+ * is recorded in the state file and does not stop the analysis run.
7
+ */
8
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
9
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
11
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
12
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
13
+ };
14
+ var BaseAutoDocPlugin_1;
15
+ import { RequiresSubclass } from '@memberjunction/global';
16
+ // Never hand back a hollow base instance for an unknown plugin name.
17
+ let BaseAutoDocPlugin = BaseAutoDocPlugin_1 = class BaseAutoDocPlugin {
18
+ /** Runs after the state is loaded, before connecting to the database. */
19
+ async OnPreRun(_context) { }
20
+ /** Runs after schema introspection and data sampling. */
21
+ async OnAfterIntrospection(_context) { }
22
+ /** Runs after primary/foreign key discovery. */
23
+ async OnAfterDiscovery(_context) { }
24
+ /** Runs after the LLM description loop. */
25
+ async OnAfterDescriptions(_context) { }
26
+ /** Runs after key pruning (also runs when pruning is not configured). */
27
+ async OnAfterPruning(_context) { }
28
+ /** Runs last, while the database connection is still open. */
29
+ async OnPostRun(_context) { }
30
+ /** Export formats this plugin contributes to `db-auto-doc export --format`. */
31
+ GetExporters() {
32
+ return [];
33
+ }
34
+ /** Dispatches a hook name to the matching method. */
35
+ async RunHook(context) {
36
+ const handlers = {
37
+ PreRun: (c) => this.OnPreRun(c),
38
+ AfterIntrospection: (c) => this.OnAfterIntrospection(c),
39
+ AfterDiscovery: (c) => this.OnAfterDiscovery(c),
40
+ AfterDescriptions: (c) => this.OnAfterDescriptions(c),
41
+ AfterPruning: (c) => this.OnAfterPruning(c),
42
+ PostRun: (c) => this.OnPostRun(c)
43
+ };
44
+ await handlers[context.Hook](context);
45
+ }
46
+ /** Reads this plugin's persisted data from the state file, if any. */
47
+ GetData(context, pluginName) {
48
+ return context.State.plugins?.[pluginName]?.Data;
49
+ }
50
+ /** Writes this plugin's data into its own section of the state file. */
51
+ SetData(context, pluginName, data) {
52
+ const section = BaseAutoDocPlugin_1.EnsureSection(context, pluginName);
53
+ section.Data = data;
54
+ }
55
+ /** Returns the plugin's state section, creating it when missing. */
56
+ static EnsureSection(context, pluginName) {
57
+ if (!context.State.plugins) {
58
+ context.State.plugins = {};
59
+ }
60
+ if (!context.State.plugins[pluginName]) {
61
+ context.State.plugins[pluginName] = { Runs: [] };
62
+ }
63
+ return context.State.plugins[pluginName];
64
+ }
65
+ };
66
+ BaseAutoDocPlugin = BaseAutoDocPlugin_1 = __decorate([
67
+ RequiresSubclass()
68
+ ], BaseAutoDocPlugin);
69
+ export { BaseAutoDocPlugin };
70
+ //# sourceMappingURL=BaseAutoDocPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAutoDocPlugin.js","sourceRoot":"","sources":["../../src/plugins/BaseAutoDocPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;;;;;;;;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAQ1D,qEAAqE;AAE9D,IAAe,iBAAiB,yBAAhC,MAAe,iBAAiB;IACrC,yEAAyE;IAClE,KAAK,CAAC,QAAQ,CAAC,QAA8B,IAAkB,CAAC;IAEvE,yDAAyD;IAClD,KAAK,CAAC,oBAAoB,CAAC,QAA8B,IAAkB,CAAC;IAEnF,gDAAgD;IACzC,KAAK,CAAC,gBAAgB,CAAC,QAA8B,IAAkB,CAAC;IAE/E,2CAA2C;IACpC,KAAK,CAAC,mBAAmB,CAAC,QAA8B,IAAkB,CAAC;IAElF,yEAAyE;IAClE,KAAK,CAAC,cAAc,CAAC,QAA8B,IAAkB,CAAC;IAE7E,8DAA8D;IACvD,KAAK,CAAC,SAAS,CAAC,QAA8B,IAAkB,CAAC;IAExE,+EAA+E;IACxE,YAAY;QACjB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,qDAAqD;IAC9C,KAAK,CAAC,OAAO,CAAC,OAA6B;QAChD,MAAM,QAAQ,GAA0E;YACtF,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/B,kBAAkB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;YACvD,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC/C,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACrD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;YAC3C,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;SAClC,CAAC;QACF,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,sEAAsE;IAC5D,OAAO,CAAmB,OAA6B,EAAE,UAAkB;QACnF,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,IAAqB,CAAC;IACpE,CAAC;IAED,wEAAwE;IAC9D,OAAO,CAAmB,OAA6B,EAAE,UAAkB,EAAE,IAAO;QAC5F,MAAM,OAAO,GAAG,mBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,oEAAoE;IAC7D,MAAM,CAAC,aAAa,CAAC,OAA4C,EAAE,UAAkB;QAC1F,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AA1DqB,iBAAiB;IADtC,gBAAgB,EAAE;GACG,iBAAiB,CA0DtC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Loads, orders and runs DBAutoDoc plugins.
3
+ *
4
+ * Plugins come from two places:
5
+ * - built-ins shipped with this package (registered by importing `./builtins.js`), and
6
+ * - external modules named in the config file's `plugins[].Module`, loaded at runtime.
7
+ *
8
+ * Each plugin is created through MJ's ClassFactory by its registration key, so anyone can
9
+ * ship a plugin as an npm package or a local file without changing DBAutoDoc.
10
+ */
11
+ import { BaseAutoDocPlugin } from './BaseAutoDocPlugin.js';
12
+ import type { AutoDocExporter, AutoDocPluginConfigEntry, AutoDocPluginContext, AutoDocPluginHook } from './types.js';
13
+ /** A plugin that resolved and is enabled for this run. */
14
+ export interface LoadedAutoDocPlugin {
15
+ Entry: AutoDocPluginConfigEntry;
16
+ Instance: BaseAutoDocPlugin;
17
+ }
18
+ /** The parts of a hook context the caller supplies; the manager adds the rest per plugin. */
19
+ export type AutoDocPluginRunContext = Omit<AutoDocPluginContext, 'Options' | 'Hook'>;
20
+ export declare class PluginManager {
21
+ private loaded;
22
+ /** Enabled plugins in execution order. Empty until {@link Load} runs. */
23
+ get Plugins(): LoadedAutoDocPlugin[];
24
+ /**
25
+ * Resolves the effective plugin list (built-ins plus config entries), loads external
26
+ * modules, and creates an instance of every enabled plugin.
27
+ * Throws when an enabled plugin's name is not registered, so typos fail loudly.
28
+ */
29
+ Load(entries: AutoDocPluginConfigEntry[] | undefined): Promise<void>;
30
+ /**
31
+ * Runs one hook on every enabled plugin, in priority order. A failing plugin is logged and
32
+ * recorded in its state section; the remaining plugins and the analysis run continue.
33
+ */
34
+ RunHook(hook: AutoDocPluginHook, context: AutoDocPluginRunContext): Promise<void>;
35
+ /** Every exporter contributed by the loaded plugins. */
36
+ GetExporters(): AutoDocExporter[];
37
+ private runOne;
38
+ /**
39
+ * Adds every built-in plugin the config doesn't mention, using its default enabled state.
40
+ * A config entry for a built-in (e.g. `{ "Name": "IndexAdvisor", "Enabled": false }`) wins.
41
+ */
42
+ static MergeWithBuiltIns(entries: AutoDocPluginConfigEntry[]): AutoDocPluginConfigEntry[];
43
+ /**
44
+ * Imports every external plugin module named in the entries, so its `@RegisterClass`
45
+ * decorators run. Relative paths resolve from the current working directory.
46
+ */
47
+ static LoadModules(entries: AutoDocPluginConfigEntry[]): Promise<void>;
48
+ /** Creates one plugin by registration key, failing clearly when it isn't registered. */
49
+ static CreatePlugin(name: string): BaseAutoDocPlugin;
50
+ /** Registration keys of every plugin currently registered with the ClassFactory. */
51
+ static RegisteredNames(): string[];
52
+ private static importModule;
53
+ }
54
+ //# sourceMappingURL=PluginManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginManager.d.ts","sourceRoot":"","sources":["../../src/plugins/PluginManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAIpB,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,wBAAwB,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,6FAA6F;AAC7F,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;AAErF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA6B;IAE3C,yEAAyE;IACzE,IAAW,OAAO,IAAI,mBAAmB,EAAE,CAE1C;IAED;;;;OAIG;IACU,IAAI,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IASjF;;;OAGG;IACU,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9F,wDAAwD;IACjD,YAAY,IAAI,eAAe,EAAE;YAI1B,MAAM;IAmBpB;;;OAGG;WACW,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,wBAAwB,EAAE;IAQhG;;;OAGG;WACiB,WAAW,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnF,wFAAwF;WAC1E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB;IAS3D,oFAAoF;WACtE,eAAe,IAAI,MAAM,EAAE;mBAMpB,YAAY;CAOlC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Loads, orders and runs DBAutoDoc plugins.
3
+ *
4
+ * Plugins come from two places:
5
+ * - built-ins shipped with this package (registered by importing `./builtins.js`), and
6
+ * - external modules named in the config file's `plugins[].Module`, loaded at runtime.
7
+ *
8
+ * Each plugin is created through MJ's ClassFactory by its registration key, so anyone can
9
+ * ship a plugin as an npm package or a local file without changing DBAutoDoc.
10
+ */
11
+ import * as path from 'path';
12
+ import { pathToFileURL } from 'node:url';
13
+ import { MJGlobal } from '@memberjunction/global';
14
+ import { BaseAutoDocPlugin } from './BaseAutoDocPlugin.js';
15
+ import { BUILT_IN_PLUGINS } from './builtins.js';
16
+ const DEFAULT_PRIORITY = 100;
17
+ export class PluginManager {
18
+ constructor() {
19
+ this.loaded = [];
20
+ }
21
+ /** Enabled plugins in execution order. Empty until {@link Load} runs. */
22
+ get Plugins() {
23
+ return this.loaded;
24
+ }
25
+ /**
26
+ * Resolves the effective plugin list (built-ins plus config entries), loads external
27
+ * modules, and creates an instance of every enabled plugin.
28
+ * Throws when an enabled plugin's name is not registered, so typos fail loudly.
29
+ */
30
+ async Load(entries) {
31
+ const effective = PluginManager.MergeWithBuiltIns(entries ?? []);
32
+ await PluginManager.LoadModules(effective);
33
+ this.loaded = effective
34
+ .filter((e) => e.Enabled !== false)
35
+ .sort((a, b) => (a.Priority ?? DEFAULT_PRIORITY) - (b.Priority ?? DEFAULT_PRIORITY))
36
+ .map((entry) => ({ Entry: entry, Instance: PluginManager.CreatePlugin(entry.Name) }));
37
+ }
38
+ /**
39
+ * Runs one hook on every enabled plugin, in priority order. A failing plugin is logged and
40
+ * recorded in its state section; the remaining plugins and the analysis run continue.
41
+ */
42
+ async RunHook(hook, context) {
43
+ for (const plugin of this.loaded) {
44
+ await this.runOne(plugin, hook, context);
45
+ }
46
+ }
47
+ /** Every exporter contributed by the loaded plugins. */
48
+ GetExporters() {
49
+ return this.loaded.flatMap((p) => p.Instance.GetExporters());
50
+ }
51
+ async runOne(plugin, hook, context) {
52
+ const startedAt = new Date().toISOString();
53
+ const fullContext = { ...context, Hook: hook, Options: plugin.Entry.Options ?? {} };
54
+ let errorMessage;
55
+ try {
56
+ await plugin.Instance.RunHook(fullContext);
57
+ }
58
+ catch (err) {
59
+ errorMessage = err instanceof Error ? err.message : String(err);
60
+ context.Log(`Plugin '${plugin.Entry.Name}' failed in ${hook} (continuing): ${errorMessage}`);
61
+ }
62
+ BaseAutoDocPlugin.EnsureSection(context, plugin.Entry.Name).Runs.push({
63
+ Hook: hook,
64
+ StartedAt: startedAt,
65
+ CompletedAt: new Date().toISOString(),
66
+ Success: errorMessage === undefined,
67
+ ErrorMessage: errorMessage
68
+ });
69
+ }
70
+ /**
71
+ * Adds every built-in plugin the config doesn't mention, using its default enabled state.
72
+ * A config entry for a built-in (e.g. `{ "Name": "IndexAdvisor", "Enabled": false }`) wins.
73
+ */
74
+ static MergeWithBuiltIns(entries) {
75
+ const named = new Set(entries.map((e) => e.Name.toLowerCase()));
76
+ const missingBuiltIns = BUILT_IN_PLUGINS
77
+ .filter((b) => !named.has(b.Name.toLowerCase()))
78
+ .map((b) => ({ Name: b.Name, Enabled: b.EnabledByDefault }));
79
+ return [...entries, ...missingBuiltIns];
80
+ }
81
+ /**
82
+ * Imports every external plugin module named in the entries, so its `@RegisterClass`
83
+ * decorators run. Relative paths resolve from the current working directory.
84
+ */
85
+ static async LoadModules(entries) {
86
+ for (const entry of entries) {
87
+ if (entry.Module && entry.Enabled !== false) {
88
+ await PluginManager.importModule(entry.Module);
89
+ }
90
+ }
91
+ }
92
+ /** Creates one plugin by registration key, failing clearly when it isn't registered. */
93
+ static CreatePlugin(name) {
94
+ const result = MJGlobal.Instance.ClassFactory.TryCreateInstance(BaseAutoDocPlugin, name);
95
+ if (!result.Resolved || !result.Instance) {
96
+ const known = PluginManager.RegisteredNames().join(', ') || '(none)';
97
+ throw new Error(`DBAutoDoc plugin '${name}' is not registered. Registered plugins: ${known}`);
98
+ }
99
+ return result.Instance;
100
+ }
101
+ /** Registration keys of every plugin currently registered with the ClassFactory. */
102
+ static RegisteredNames() {
103
+ return MJGlobal.Instance.ClassFactory.GetAllRegistrations(BaseAutoDocPlugin)
104
+ .map((r) => r.Key)
105
+ .filter((k) => !!k);
106
+ }
107
+ static async importModule(specifier) {
108
+ const isPath = specifier.startsWith('.') || path.isAbsolute(specifier);
109
+ const target = isPath ? pathToFileURL(path.resolve(specifier)).href : specifier;
110
+ // Dynamic import is intentional: runtime plugin discovery from config (the module path is
111
+ // only known at run time). DBAutoDoc runs outside the MJ runtime, where this is permitted.
112
+ await import(target);
113
+ }
114
+ }
115
+ //# sourceMappingURL=PluginManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginManager.js","sourceRoot":"","sources":["../../src/plugins/PluginManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Built-in plugins shipped with DBAutoDoc.
3
+ *
4
+ * Each built-in is imported here so its `@RegisterClass` registration runs whenever the plugin
5
+ * system is used, and listed with its default enabled state. Users can still turn a built-in
6
+ * off with `{ "Name": "<Name>", "Enabled": false }` in the config's `plugins` array.
7
+ */
8
+ export interface BuiltInAutoDocPlugin {
9
+ Name: string;
10
+ EnabledByDefault: boolean;
11
+ }
12
+ export declare const BUILT_IN_PLUGINS: BuiltInAutoDocPlugin[];
13
+ //# sourceMappingURL=builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/plugins/builtins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,gBAAgB,EAAE,oBAAoB,EAElD,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Built-in plugins shipped with DBAutoDoc.
3
+ *
4
+ * Each built-in is imported here so its `@RegisterClass` registration runs whenever the plugin
5
+ * system is used, and listed with its default enabled state. Users can still turn a built-in
6
+ * off with `{ "Name": "<Name>", "Enabled": false }` in the config's `plugins` array.
7
+ */
8
+ import { INDEX_ADVISOR_PLUGIN_NAME } from './index-advisor/IndexAdvisorPlugin.js';
9
+ export const BUILT_IN_PLUGINS = [
10
+ { Name: INDEX_ADVISOR_PLUGIN_NAME, EnabledByDefault: true }
11
+ ];
12
+ //# sourceMappingURL=builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/plugins/builtins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAOlF,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,EAAE,IAAI,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,IAAI,EAAE;CAC5D,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Index Advisor — built-in DBAutoDoc plugin.
3
+ *
4
+ * At the end of a run it reads the existing indexes, proposes new ones from what DBAutoDoc
5
+ * learned (foreign keys, discovered primary keys, column statistics), flags redundant existing
6
+ * indexes, and stores everything in `state.plugins.IndexAdvisor`. The `index-migration` export
7
+ * format turns the proposals into a SQL migration.
8
+ */
9
+ import { BaseAutoDocPlugin } from '../BaseAutoDocPlugin.js';
10
+ import type { AutoDocExporter, AutoDocPluginContext, AutoDocPluginJSONValue } from '../types.js';
11
+ import type { DatabaseDocumentation } from '../../types/state.js';
12
+ import type { IndexAdvisorData, IndexAdvisorOptions } from './IndexAdvisorTypes.js';
13
+ export declare const INDEX_ADVISOR_PLUGIN_NAME = "IndexAdvisor";
14
+ export declare const DEFAULT_INDEX_ADVISOR_OPTIONS: IndexAdvisorOptions;
15
+ export declare class IndexAdvisorPlugin extends BaseAutoDocPlugin {
16
+ OnPostRun(context: AutoDocPluginContext): Promise<void>;
17
+ GetExporters(): AutoDocExporter[];
18
+ }
19
+ /** The Index Advisor's section of a state file, when the plugin has run. */
20
+ export declare function GetIndexAdvisorData(state: DatabaseDocumentation): IndexAdvisorData | undefined;
21
+ /** Merges config-file options over the defaults, ignoring values of the wrong type. */
22
+ export declare function ResolveIndexAdvisorOptions(raw: {
23
+ [key: string]: AutoDocPluginJSONValue;
24
+ }): IndexAdvisorOptions;
25
+ //# sourceMappingURL=IndexAdvisorPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IndexAdvisorPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/index-advisor/IndexAdvisorPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGjG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAKpF,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAExD,eAAO,MAAM,6BAA6B,EAAE,mBAQ3C,CAAC;AAEF,qBACa,kBAAmB,SAAQ,iBAAiB;IACjC,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB7D,YAAY,IAAI,eAAe,EAAE;CAUlD;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,GAAG,SAAS,CAE9F;AAED,uFAAuF;AACvF,wBAAgB,0BAA0B,CAAC,GAAG,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,CAAA;CAAE,GAAG,mBAAmB,CAY9G"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Index Advisor — built-in DBAutoDoc plugin.
3
+ *
4
+ * At the end of a run it reads the existing indexes, proposes new ones from what DBAutoDoc
5
+ * learned (foreign keys, discovered primary keys, column statistics), flags redundant existing
6
+ * indexes, and stores everything in `state.plugins.IndexAdvisor`. The `index-migration` export
7
+ * format turns the proposals into a SQL migration.
8
+ */
9
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
10
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
11
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
12
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
13
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14
+ };
15
+ import { RegisterClass } from '@memberjunction/global';
16
+ import { BaseAutoDocPlugin } from '../BaseAutoDocPlugin.js';
17
+ import { ProposeIndexes, FindRedundantIndexes } from './IndexRules.js';
18
+ import { IndexMigrationGenerator } from './IndexMigrationGenerator.js';
19
+ import { IndexLLMReviewer } from './IndexLLMReview.js';
20
+ export const INDEX_ADVISOR_PLUGIN_NAME = 'IndexAdvisor';
21
+ export const DEFAULT_INDEX_ADVISOR_OPTIONS = {
22
+ MinRowCount: 1000,
23
+ IncludeDiscoveredFKs: true,
24
+ KeyMinConfidence: 90,
25
+ LLMReview: true,
26
+ MaxLLMTables: 40,
27
+ // PostgreSQL: build indexes without locking writes on a live database (Craig, 2026-10-08)
28
+ Concurrently: true
29
+ };
30
+ let IndexAdvisorPlugin = class IndexAdvisorPlugin extends BaseAutoDocPlugin {
31
+ async OnPostRun(context) {
32
+ if (!context.Driver) {
33
+ throw new Error('Index Advisor needs an open database connection');
34
+ }
35
+ const options = ResolveIndexAdvisorOptions(context.Options);
36
+ const { Existing, SkippedSchemas } = await readExistingIndexes(context.Driver, context.State);
37
+ const data = {
38
+ AnalyzedAt: new Date().toISOString(),
39
+ Options: options,
40
+ Existing,
41
+ Proposed: ProposeIndexes(withoutSkippedSchemas(context.State, SkippedSchemas), Existing, options),
42
+ Redundant: FindRedundantIndexes(Existing),
43
+ SkippedSchemas
44
+ };
45
+ if (options.LLMReview) {
46
+ await runLLMReview(context, data);
47
+ }
48
+ this.SetData(context, INDEX_ADVISOR_PLUGIN_NAME, data);
49
+ context.Log(`Index Advisor: ${data.Existing.length} existing index(es), ${data.Proposed.length} proposed, ${data.Redundant.length} redundant` +
50
+ (SkippedSchemas.length ? `, ${SkippedSchemas.length} schema(s) skipped` : '') +
51
+ (data.LLMReview ? `; LLM review: ${data.LLMReview.TablesReviewed} table(s), ${data.LLMReview.Dropped.length} dropped, ${data.LLMReview.Errors.length} error(s)` : ''));
52
+ }
53
+ GetExporters() {
54
+ return [{
55
+ Format: 'index-migration',
56
+ Description: 'SQL migration creating the indexes proposed by the Index Advisor',
57
+ Generate: (state, options) => {
58
+ const data = GetIndexAdvisorData(state);
59
+ return data ? new IndexMigrationGenerator().Generate(data, options) : [];
60
+ }
61
+ }];
62
+ }
63
+ };
64
+ IndexAdvisorPlugin = __decorate([
65
+ RegisterClass(BaseAutoDocPlugin, INDEX_ADVISOR_PLUGIN_NAME)
66
+ ], IndexAdvisorPlugin);
67
+ export { IndexAdvisorPlugin };
68
+ /** The Index Advisor's section of a state file, when the plugin has run. */
69
+ export function GetIndexAdvisorData(state) {
70
+ return state.plugins?.[INDEX_ADVISOR_PLUGIN_NAME]?.Data;
71
+ }
72
+ /** Merges config-file options over the defaults, ignoring values of the wrong type. */
73
+ export function ResolveIndexAdvisorOptions(raw) {
74
+ const num = (v, d) => (typeof v === 'number' && Number.isFinite(v) ? v : d);
75
+ const bool = (v, d) => (typeof v === 'boolean' ? v : d);
76
+ const d = DEFAULT_INDEX_ADVISOR_OPTIONS;
77
+ return {
78
+ MinRowCount: num(raw['MinRowCount'], d.MinRowCount),
79
+ IncludeDiscoveredFKs: bool(raw['IncludeDiscoveredFKs'], d.IncludeDiscoveredFKs),
80
+ KeyMinConfidence: num(raw['KeyMinConfidence'], d.KeyMinConfidence),
81
+ LLMReview: bool(raw['LLMReview'], d.LLMReview),
82
+ MaxLLMTables: num(raw['MaxLLMTables'], d.MaxLLMTables),
83
+ Concurrently: bool(raw['Concurrently'], d.Concurrently)
84
+ };
85
+ }
86
+ /** Reads indexes schema by schema; a schema that fails is recorded and skipped. */
87
+ async function readExistingIndexes(driver, state) {
88
+ const existing = [];
89
+ const skipped = [];
90
+ for (const schema of state.schemas) {
91
+ try {
92
+ existing.push(...(await driver.GetIndexes(schema.name)));
93
+ }
94
+ catch (err) {
95
+ skipped.push({ SchemaName: schema.name, Error: err instanceof Error ? err.message : String(err) });
96
+ }
97
+ }
98
+ return { Existing: existing, SkippedSchemas: skipped };
99
+ }
100
+ /**
101
+ * The state limited to schemas whose indexes were read. Proposing for a schema whose existing
102
+ * indexes are unknown would suggest indexes that may already exist.
103
+ */
104
+ function withoutSkippedSchemas(state, skipped) {
105
+ const skippedNames = new Set(skipped.map((s) => s.SchemaName));
106
+ return skippedNames.size ? { ...state, schemas: state.schemas.filter((s) => !skippedNames.has(s.name)) } : state;
107
+ }
108
+ /**
109
+ * Lets the LLM keep, drop, modify or add proposals. Any failure to set up the model keeps the
110
+ * rule-based proposals and is recorded in the review summary.
111
+ */
112
+ async function runLLMReview(context, data) {
113
+ const platform = context.State.database.provider ?? context.Config.database.provider ?? 'sqlserver';
114
+ try {
115
+ const reviewer = await IndexLLMReviewer.Create(context.Config.ai, context.Log);
116
+ const reviewed = await reviewer.Review(context.State, data, platform);
117
+ data.Proposed = reviewed.Proposals;
118
+ data.LLMReview = reviewed.Summary;
119
+ }
120
+ catch (err) {
121
+ data.LLMReview = {
122
+ Model: context.Config.ai.modelOverrides?.['indexAdvisor']?.model ?? context.Config.ai.model,
123
+ TablesReviewed: 0, TokensUsed: 0, Dropped: [], Rejected: [],
124
+ Errors: [{ TableName: '*', Error: err instanceof Error ? err.message : String(err) }]
125
+ };
126
+ }
127
+ }
128
+ //# sourceMappingURL=IndexAdvisorPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IndexAdvisorPlugin.js","sourceRoot":"","sources":["../../../src/plugins/index-advisor/IndexAdvisorPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Types for the Index Advisor plugin's options and its section of the state file.
3
+ */
4
+ import type { AutoDocIndex } from '../../types/driver.js';
5
+ /** Where a proposal came from. */
6
+ export type IndexProposalSource = 'FKCoverage' | 'SoftPrimaryKey' | 'LLM';
7
+ /** A proposed new index. */
8
+ export interface IndexProposal {
9
+ SchemaName: string;
10
+ TableName: string;
11
+ /** Key columns, in index order. */
12
+ Columns: string[];
13
+ /** Non-key covering columns (SQL Server / PostgreSQL INCLUDE). */
14
+ IncludeColumns: string[];
15
+ Source: IndexProposalSource;
16
+ Reason: string;
17
+ /** 1 (low) – 100 (high); larger tables score higher. */
18
+ Priority: number;
19
+ Evidence: IndexProposalEvidence;
20
+ }
21
+ export interface IndexProposalEvidence {
22
+ RowCount: number;
23
+ /** Distinct values of the leading column, when column statistics are available. */
24
+ LeadingColumnDistinctCount?: number;
25
+ /** `schema.table.column` the foreign key points at (FK coverage proposals). */
26
+ References?: string;
27
+ /** Confidence of the discovered key that motivated the proposal (0–100). */
28
+ KeyConfidence?: number;
29
+ /** Whether the motivating key is declared in the database or was discovered. */
30
+ KeyOrigin?: 'declared' | 'discovered';
31
+ }
32
+ /** An existing index whose job another index already does. Reported only; never dropped. */
33
+ export interface RedundantIndex {
34
+ SchemaName: string;
35
+ TableName: string;
36
+ IndexName: string;
37
+ CoveredBy: string;
38
+ Reason: string;
39
+ }
40
+ /** Index Advisor options from the config file (`plugins[].Options`). */
41
+ export interface IndexAdvisorOptions {
42
+ /** Tables with fewer rows get no proposals. Default 1000. */
43
+ MinRowCount: number;
44
+ /** Also index discovered (not just declared) foreign keys. Default true. */
45
+ IncludeDiscoveredFKs: boolean;
46
+ /** Minimum confidence for a discovered key to be used. Default 90. */
47
+ KeyMinConfidence: number;
48
+ /** Run the LLM review layer. Default true. */
49
+ LLMReview: boolean;
50
+ /** Most tables the LLM review looks at (largest first). Default 40. */
51
+ MaxLLMTables: number;
52
+ /** PostgreSQL: emit CREATE INDEX CONCURRENTLY (no write lock while building; runs outside a transaction). Default true. */
53
+ Concurrently: boolean;
54
+ }
55
+ /** The plugin's section of the state file (`state.plugins.IndexAdvisor.Data`). */
56
+ export interface IndexAdvisorData {
57
+ AnalyzedAt: string;
58
+ Options: IndexAdvisorOptions;
59
+ Existing: AutoDocIndex[];
60
+ Proposed: IndexProposal[];
61
+ Redundant: RedundantIndex[];
62
+ /** Schemas whose existing indexes could not be read (proposals for them are skipped). */
63
+ SkippedSchemas: {
64
+ SchemaName: string;
65
+ Error: string;
66
+ }[];
67
+ /** What the LLM review did. Absent when the review was off. */
68
+ LLMReview?: IndexLLMReviewSummary;
69
+ }
70
+ /** Outcome of the LLM review layer. */
71
+ export interface IndexLLMReviewSummary {
72
+ Model: string;
73
+ TablesReviewed: number;
74
+ TokensUsed: number;
75
+ /** Rule-based proposals the review removed, with its reason. */
76
+ Dropped: {
77
+ Proposal: IndexProposal;
78
+ Reason: string;
79
+ }[];
80
+ /** LLM suggestions that failed validation and were not applied. */
81
+ Rejected: {
82
+ TableName: string;
83
+ Columns: string[];
84
+ Why: string;
85
+ }[];
86
+ /** Tables whose review call failed; their rule-based proposals were kept unchanged. */
87
+ Errors: {
88
+ TableName: string;
89
+ Error: string;
90
+ }[];
91
+ }
92
+ /** One proposal decision the LLM returns. `Proposal` is the 1-based number shown in the prompt. */
93
+ export interface IndexReviewDecision {
94
+ Proposal: number;
95
+ Action: 'keep' | 'drop' | 'modify';
96
+ Columns?: string[];
97
+ IncludeColumns?: string[];
98
+ Reason: string;
99
+ }
100
+ /** A new index the LLM suggests. */
101
+ export interface IndexReviewAddition {
102
+ Columns: string[];
103
+ IncludeColumns?: string[];
104
+ Reason: string;
105
+ }
106
+ /** The LLM's full response for one table. */
107
+ export interface IndexReviewResponse {
108
+ Decisions: IndexReviewDecision[];
109
+ Additions: IndexReviewAddition[];
110
+ }
111
+ //# sourceMappingURL=IndexAdvisorTypes.d.ts.map