@query-doctor/core 0.10.3 → 0.10.4

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 (37) hide show
  1. package/dist/action-plan/aggregate-index-recommendations.cjs +52 -0
  2. package/dist/action-plan/aggregate-index-recommendations.cjs.map +1 -0
  3. package/dist/action-plan/aggregate-index-recommendations.d.cts +36 -0
  4. package/dist/action-plan/aggregate-index-recommendations.d.cts.map +1 -0
  5. package/dist/action-plan/aggregate-index-recommendations.d.mts +36 -0
  6. package/dist/action-plan/aggregate-index-recommendations.d.mts.map +1 -0
  7. package/dist/action-plan/aggregate-index-recommendations.mjs +52 -0
  8. package/dist/action-plan/aggregate-index-recommendations.mjs.map +1 -0
  9. package/dist/action-plan/build-action-plan.cjs +179 -0
  10. package/dist/action-plan/build-action-plan.cjs.map +1 -0
  11. package/dist/action-plan/build-action-plan.d.cts +132 -0
  12. package/dist/action-plan/build-action-plan.d.cts.map +1 -0
  13. package/dist/action-plan/build-action-plan.d.mts +132 -0
  14. package/dist/action-plan/build-action-plan.d.mts.map +1 -0
  15. package/dist/action-plan/build-action-plan.mjs +179 -0
  16. package/dist/action-plan/build-action-plan.mjs.map +1 -0
  17. package/dist/action-plan/index-coverage.cjs +72 -0
  18. package/dist/action-plan/index-coverage.cjs.map +1 -0
  19. package/dist/action-plan/index-coverage.d.cts +44 -0
  20. package/dist/action-plan/index-coverage.d.cts.map +1 -0
  21. package/dist/action-plan/index-coverage.d.mts +44 -0
  22. package/dist/action-plan/index-coverage.d.mts.map +1 -0
  23. package/dist/action-plan/index-coverage.mjs +71 -0
  24. package/dist/action-plan/index-coverage.mjs.map +1 -0
  25. package/dist/index.cjs +7 -0
  26. package/dist/index.d.cts +5 -2
  27. package/dist/index.d.mts +5 -2
  28. package/dist/index.mjs +4 -1
  29. package/dist/sql/builder.cjs +1 -1
  30. package/dist/sql/builder.cjs.map +1 -1
  31. package/dist/sql/builder.mjs +1 -1
  32. package/dist/sql/builder.mjs.map +1 -1
  33. package/dist/websocket-server.d.cts +1 -0
  34. package/dist/websocket-server.d.cts.map +1 -1
  35. package/dist/websocket-server.d.mts +1 -0
  36. package/dist/websocket-server.d.mts.map +1 -1
  37. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -12,7 +12,10 @@ import { CompactSelectListOptions, compactSelectList } from "./sql/display-query
12
12
  import { DuplicateIndexGroup, groupDuplicateIndexes, isIndexProbablyDroppable, isIndexSupported } from "./sql/indexes.cjs";
13
13
  import { CombinedExport, ExportedQuery, QuerySource, combinedDumpSql, dumpQueriesSql } from "./optimizer/dump.cjs";
14
14
  import { PssRewriter } from "./optimizer/pss-rewriter.cjs";
15
- import { deriveSentryEnvironment } from "./sentry.cjs";
16
15
  import { IndexRecommendation, LiveQueryOptimization, OptimizationResult, OptimizedQuery, QueryHash, RecentQuery } from "./query.cjs";
16
+ import { AggregatedIndexRecommendation, IndexGroup, groupIndexesByCoverage, indexCovers } from "./action-plan/index-coverage.cjs";
17
+ import { ActionPlanQuery, aggregateIndexRecommendations } from "./action-plan/aggregate-index-recommendations.cjs";
18
+ import { ActionPlanNudgeQuery, ActionableStep, AffectedQueryCost, CostReduction, DomainLabel, IndexAction, NudgeFinding, RegressionBreach, buildActionPlan } from "./action-plan/build-action-plan.cjs";
19
+ import { deriveSentryEnvironment } from "./sentry.cjs";
17
20
  import { ClientApi, ConnectionMode, ExtensionPresence, IndexDefinition, RepoConfig, ServerApi, UnauthenticatedServerApi } from "./websocket-server.cjs";
18
- export { AnalysisResult, Analyzer, ClientApi, ColumnMetadata, CombinedExport, CompactSelectListOptions, ComputedColumnStats, ComputedReltuples, ComputedStats, ConnectionMode, DUMP_STATS_SQL, DatabaseDriver, DiscoveredColumnReference, DuplicateIndexGroup, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, ExtensionPresence, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexDefinition, IndexIdentifier, IndexOptimizer, IndexRecommendation, IndexToCreate, JsonbOperator, LiveQueryOptimization, Nudge, OptimizationResult, OptimizeResult, OptimizedQuery, PROCEED, Parameter, Parser, Path, PermutedIndexCandidate, PgIdentifier, Postgres, PostgresConnectionInput, PostgresExplainResult, PostgresExplainStage, PostgresExplainStageCommon, PostgresExplainStageSchema, PostgresFactory, PostgresQueryBuilder, PostgresQueryBuilderCommand, PostgresStage, PostgresStageId, PostgresTransaction, PostgresVersion, PssRewriter, QueryHash, QuerySource, RecentQuery, RepoConfig, RootIndexCandidate, SKIP, SQLCommenterExtraction, SQLCommenterTag, SerializeResult, ServerApi, SortContext, StatementType, Statistics, StatisticsMode, StatisticsSource, TableMetadata, TableReference, TableStats, UnauthenticatedServerApi, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, ignoredIdentifier, isIndexProbablyDroppable, isIndexSupported, parseNudges };
21
+ export { ActionPlanNudgeQuery, ActionPlanQuery, ActionableStep, AffectedQueryCost, AggregatedIndexRecommendation, AnalysisResult, Analyzer, ClientApi, ColumnMetadata, CombinedExport, CompactSelectListOptions, ComputedColumnStats, ComputedReltuples, ComputedStats, ConnectionMode, CostReduction, DUMP_STATS_SQL, DatabaseDriver, DiscoveredColumnReference, DomainLabel, DuplicateIndexGroup, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, ExtensionPresence, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexAction, IndexDefinition, IndexGroup, IndexIdentifier, IndexOptimizer, IndexRecommendation, IndexToCreate, JsonbOperator, LiveQueryOptimization, Nudge, NudgeFinding, OptimizationResult, OptimizeResult, OptimizedQuery, PROCEED, Parameter, Parser, Path, PermutedIndexCandidate, PgIdentifier, Postgres, PostgresConnectionInput, PostgresExplainResult, PostgresExplainStage, PostgresExplainStageCommon, PostgresExplainStageSchema, PostgresFactory, PostgresQueryBuilder, PostgresQueryBuilderCommand, PostgresStage, PostgresStageId, PostgresTransaction, PostgresVersion, PssRewriter, QueryHash, QuerySource, RecentQuery, RegressionBreach, RepoConfig, RootIndexCandidate, SKIP, SQLCommenterExtraction, SQLCommenterTag, SerializeResult, ServerApi, SortContext, StatementType, Statistics, StatisticsMode, StatisticsSource, TableMetadata, TableReference, TableStats, UnauthenticatedServerApi, aggregateIndexRecommendations, buildActionPlan, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, groupIndexesByCoverage, ignoredIdentifier, indexCovers, isIndexProbablyDroppable, isIndexSupported, parseNudges };
package/dist/index.d.mts CHANGED
@@ -12,7 +12,10 @@ import { CompactSelectListOptions, compactSelectList } from "./sql/display-query
12
12
  import { DuplicateIndexGroup, groupDuplicateIndexes, isIndexProbablyDroppable, isIndexSupported } from "./sql/indexes.mjs";
13
13
  import { CombinedExport, ExportedQuery, QuerySource, combinedDumpSql, dumpQueriesSql } from "./optimizer/dump.mjs";
14
14
  import { PssRewriter } from "./optimizer/pss-rewriter.mjs";
15
- import { deriveSentryEnvironment } from "./sentry.mjs";
16
15
  import { IndexRecommendation, LiveQueryOptimization, OptimizationResult, OptimizedQuery, QueryHash, RecentQuery } from "./query.mjs";
16
+ import { AggregatedIndexRecommendation, IndexGroup, groupIndexesByCoverage, indexCovers } from "./action-plan/index-coverage.mjs";
17
+ import { ActionPlanQuery, aggregateIndexRecommendations } from "./action-plan/aggregate-index-recommendations.mjs";
18
+ import { ActionPlanNudgeQuery, ActionableStep, AffectedQueryCost, CostReduction, DomainLabel, IndexAction, NudgeFinding, RegressionBreach, buildActionPlan } from "./action-plan/build-action-plan.mjs";
19
+ import { deriveSentryEnvironment } from "./sentry.mjs";
17
20
  import { ClientApi, ConnectionMode, ExtensionPresence, IndexDefinition, RepoConfig, ServerApi, UnauthenticatedServerApi } from "./websocket-server.mjs";
18
- export { AnalysisResult, Analyzer, ClientApi, ColumnMetadata, CombinedExport, CompactSelectListOptions, ComputedColumnStats, ComputedReltuples, ComputedStats, ConnectionMode, DUMP_STATS_SQL, DatabaseDriver, DiscoveredColumnReference, DuplicateIndexGroup, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, ExtensionPresence, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexDefinition, IndexIdentifier, IndexOptimizer, IndexRecommendation, IndexToCreate, JsonbOperator, LiveQueryOptimization, Nudge, OptimizationResult, OptimizeResult, OptimizedQuery, PROCEED, Parameter, Parser, Path, PermutedIndexCandidate, PgIdentifier, Postgres, PostgresConnectionInput, PostgresExplainResult, PostgresExplainStage, PostgresExplainStageCommon, PostgresExplainStageSchema, PostgresFactory, PostgresQueryBuilder, PostgresQueryBuilderCommand, PostgresStage, PostgresStageId, PostgresTransaction, PostgresVersion, PssRewriter, QueryHash, QuerySource, RecentQuery, RepoConfig, RootIndexCandidate, SKIP, SQLCommenterExtraction, SQLCommenterTag, SerializeResult, ServerApi, SortContext, StatementType, Statistics, StatisticsMode, StatisticsSource, TableMetadata, TableReference, TableStats, UnauthenticatedServerApi, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, ignoredIdentifier, isIndexProbablyDroppable, isIndexSupported, parseNudges };
21
+ export { ActionPlanNudgeQuery, ActionPlanQuery, ActionableStep, AffectedQueryCost, AggregatedIndexRecommendation, AnalysisResult, Analyzer, ClientApi, ColumnMetadata, CombinedExport, CompactSelectListOptions, ComputedColumnStats, ComputedReltuples, ComputedStats, ConnectionMode, CostReduction, DUMP_STATS_SQL, DatabaseDriver, DiscoveredColumnReference, DomainLabel, DuplicateIndexGroup, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, ExtensionPresence, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexAction, IndexDefinition, IndexGroup, IndexIdentifier, IndexOptimizer, IndexRecommendation, IndexToCreate, JsonbOperator, LiveQueryOptimization, Nudge, NudgeFinding, OptimizationResult, OptimizeResult, OptimizedQuery, PROCEED, Parameter, Parser, Path, PermutedIndexCandidate, PgIdentifier, Postgres, PostgresConnectionInput, PostgresExplainResult, PostgresExplainStage, PostgresExplainStageCommon, PostgresExplainStageSchema, PostgresFactory, PostgresQueryBuilder, PostgresQueryBuilderCommand, PostgresStage, PostgresStageId, PostgresTransaction, PostgresVersion, PssRewriter, QueryHash, QuerySource, RecentQuery, RegressionBreach, RepoConfig, RootIndexCandidate, SKIP, SQLCommenterExtraction, SQLCommenterTag, SerializeResult, ServerApi, SortContext, StatementType, Statistics, StatisticsMode, StatisticsSource, TableMetadata, TableReference, TableStats, UnauthenticatedServerApi, aggregateIndexRecommendations, buildActionPlan, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, groupIndexesByCoverage, ignoredIdentifier, indexCovers, isIndexProbablyDroppable, isIndexSupported, parseNudges };
package/dist/index.mjs CHANGED
@@ -11,6 +11,9 @@ import { IndexOptimizer, PROCEED, SKIP } from "./optimizer/genalgo.mjs";
11
11
  import { ComputedColumnStats, ComputedReltuples, ComputedStats, DUMP_STATS_SQL, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, Statistics, StatisticsMode, StatisticsSource } from "./optimizer/statistics.mjs";
12
12
  import { CombinedExport, ExportedQuery, combinedDumpSql, dumpQueriesSql } from "./optimizer/dump.mjs";
13
13
  import { PssRewriter } from "./optimizer/pss-rewriter.mjs";
14
+ import { groupIndexesByCoverage, indexCovers } from "./action-plan/index-coverage.mjs";
15
+ import { aggregateIndexRecommendations } from "./action-plan/aggregate-index-recommendations.mjs";
16
+ import { buildActionPlan } from "./action-plan/build-action-plan.mjs";
14
17
  import { deriveSentryEnvironment } from "./sentry.mjs";
15
18
  import { OptimizedQuery, RecentQuery } from "./query.mjs";
16
- export { Analyzer, CombinedExport, ComputedColumnStats, ComputedReltuples, ComputedStats, DUMP_STATS_SQL, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexOptimizer, OptimizedQuery, PROCEED, PgIdentifier, PostgresExplainStageSchema, PostgresQueryBuilder, PostgresVersion, PssRewriter, RecentQuery, SKIP, Statistics, StatisticsMode, StatisticsSource, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, ignoredIdentifier, isIndexProbablyDroppable, isIndexSupported, parseNudges };
19
+ export { Analyzer, CombinedExport, ComputedColumnStats, ComputedReltuples, ComputedStats, DUMP_STATS_SQL, ExportedQuery, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, FullSchema, FullSchemaColumn, FullSchemaCompositeAttribute, FullSchemaConstraint, FullSchemaExtension, FullSchemaFunction, FullSchemaIncludedColumn, FullSchemaIndex, FullSchemaKeyColumn, FullSchemaTable, FullSchemaTrigger, FullSchemaType, FullSchemaTypeConstraint, FullSchemaView, IndexOptimizer, OptimizedQuery, PROCEED, PgIdentifier, PostgresExplainStageSchema, PostgresQueryBuilder, PostgresVersion, PssRewriter, RecentQuery, SKIP, Statistics, StatisticsMode, StatisticsSource, aggregateIndexRecommendations, buildActionPlan, combinedDumpSql, compactSelectList, deriveSentryEnvironment, dropIndex, dumpQueriesSql, dumpSchema, groupDuplicateIndexes, groupIndexesByCoverage, ignoredIdentifier, indexCovers, isIndexProbablyDroppable, isIndexSupported, parseNudges };
@@ -83,7 +83,7 @@ var PostgresQueryBuilder = class PostgresQueryBuilder {
83
83
  }
84
84
  substituteQuery() {
85
85
  let query = this.query;
86
- if (this.limitSubstitution !== void 0) query = query.replace(/limit\s+\$\d+/g, `limit ${this.limitSubstitution}`);
86
+ if (this.limitSubstitution !== void 0) query = query.replace(/(limit)\s+\$\d+/gi, `$1 ${this.limitSubstitution}`);
87
87
  for (const [key, value] of Object.entries(this.parameters)) query = query.replaceAll(`\\$${key}`, value.toString());
88
88
  return query;
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"builder.cjs","names":[],"sources":["../../src/sql/builder.ts"],"sourcesContent":["import { PgIdentifier } from \"./pg-identifier\";\n\nexport type PostgresQueryBuilderCommand =\n | \"bitmapscan\"\n | \"indexscan\"\n | \"seqscan\";\n\nexport class PostgresQueryBuilder {\n private readonly commands: Record<string, string> = {};\n private isIntrospection: boolean = false;\n private explainFlags: string[] = [];\n private _preamble = 0;\n private parameters: Record<Parameter, number> = {};\n // substitution for `limit $1` -> `limit 5`\n private limitSubstitution?: number;\n\n constructor(private query: string) {}\n\n get preamble(): number {\n return this._preamble;\n }\n\n static createIndex(definition: string, name?: PgIdentifier) {\n if (name) {\n return new PostgresQueryBuilder(\n `create index \"${name}\" on ${definition};`,\n );\n }\n return new PostgresQueryBuilder(`create index on ${definition};`);\n }\n\n enable(command: PostgresQueryBuilderCommand, value: boolean = true): this {\n const commandString = `enable_${command}`;\n if (value) {\n this.commands[commandString] = \"on\";\n } else {\n this.commands[commandString] = \"off\";\n }\n return this;\n }\n\n withQuery(query: string): this {\n this.query = query;\n return this;\n }\n\n introspect(): this {\n this.isIntrospection = true;\n return this;\n }\n\n explain(flags: string[]): this {\n this.explainFlags = flags;\n return this;\n }\n\n parameterize(parameters: Record<Parameter, number>) {\n Object.assign(this.parameters, parameters);\n return this;\n }\n\n replaceLimit(limit: number) {\n this.limitSubstitution = limit;\n return this;\n }\n\n build(): string {\n let commands = this.generateSetCommands();\n commands += this.generateExplain().query;\n if (this.isIntrospection) {\n commands += \" -- @qd_introspection\";\n }\n return commands;\n }\n\n /** Return the \"set a=b\" parts of the command in the query separate from the explain select ... part */\n buildParts() {\n const commands = this.generateSetCommands();\n const explain = this.generateExplain();\n this._preamble = explain.preamble;\n if (this.isIntrospection) {\n explain.query += \" -- @qd_introspection\";\n }\n return { commands, query: explain.query };\n }\n\n private generateSetCommands() {\n let commands = \"\";\n for (const key in this.commands) {\n const value = this.commands[key];\n commands += `set local ${key}=${value};\\n`;\n }\n return commands;\n }\n\n private generateExplain() {\n let finalQuery = \"\";\n if (this.explainFlags.length > 0) {\n finalQuery += `explain (${this.explainFlags.join(\", \")}) `;\n }\n const query = this.substituteQuery();\n const semicolon = query.endsWith(\";\") ? \"\" : \";\";\n\n const preamble = finalQuery.length;\n finalQuery += `${query}${semicolon}`;\n return { query: finalQuery, preamble };\n }\n\n private substituteQuery() {\n let query = this.query;\n if (this.limitSubstitution !== undefined) {\n query = query.replace(\n /limit\\s+\\$\\d+/g,\n `limit ${this.limitSubstitution}`,\n );\n }\n for (const [key, value] of Object.entries(this.parameters)) {\n query = query.replaceAll(`\\\\$${key}`, value.toString());\n }\n return query;\n }\n}\n\nexport type Parameter = `$${string}`;\n"],"mappings":";;;AAOA,IAAa,uBAAb,MAAa,qBAAqB;CAShC,YAAY,OAAuB;AAAf,OAAA,QAAA;+CARH,YAAmC,EAAE,CAAC;+CAC/C,mBAA2B,MAAM;+CACjC,gBAAyB,EAAE,CAAC;+CAC5B,aAAY,EAAE;+CACd,cAAwC,EAAE,CAAC;+CAE3C,qBAAA,KAAA,EAA2B;;CAInC,IAAI,WAAmB;AACrB,SAAO,KAAK;;CAGd,OAAO,YAAY,YAAoB,MAAqB;AAC1D,MAAI,KACF,QAAO,IAAI,qBACT,iBAAiB,KAAK,OAAO,WAAW,GACzC;AAEH,SAAO,IAAI,qBAAqB,mBAAmB,WAAW,GAAG;;CAGnE,OAAO,SAAsC,QAAiB,MAAY;EACxE,MAAM,gBAAgB,UAAU;AAChC,MAAI,MACF,MAAK,SAAS,iBAAiB;MAE/B,MAAK,SAAS,iBAAiB;AAEjC,SAAO;;CAGT,UAAU,OAAqB;AAC7B,OAAK,QAAQ;AACb,SAAO;;CAGT,aAAmB;AACjB,OAAK,kBAAkB;AACvB,SAAO;;CAGT,QAAQ,OAAuB;AAC7B,OAAK,eAAe;AACpB,SAAO;;CAGT,aAAa,YAAuC;AAClD,SAAO,OAAO,KAAK,YAAY,WAAW;AAC1C,SAAO;;CAGT,aAAa,OAAe;AAC1B,OAAK,oBAAoB;AACzB,SAAO;;CAGT,QAAgB;EACd,IAAI,WAAW,KAAK,qBAAqB;AACzC,cAAY,KAAK,iBAAiB,CAAC;AACnC,MAAI,KAAK,gBACP,aAAY;AAEd,SAAO;;;CAIT,aAAa;EACX,MAAM,WAAW,KAAK,qBAAqB;EAC3C,MAAM,UAAU,KAAK,iBAAiB;AACtC,OAAK,YAAY,QAAQ;AACzB,MAAI,KAAK,gBACP,SAAQ,SAAS;AAEnB,SAAO;GAAE;GAAU,OAAO,QAAQ;GAAO;;CAG3C,sBAA8B;EAC5B,IAAI,WAAW;AACf,OAAK,MAAM,OAAO,KAAK,UAAU;GAC/B,MAAM,QAAQ,KAAK,SAAS;AAC5B,eAAY,aAAa,IAAI,GAAG,MAAM;;AAExC,SAAO;;CAGT,kBAA0B;EACxB,IAAI,aAAa;AACjB,MAAI,KAAK,aAAa,SAAS,EAC7B,eAAc,YAAY,KAAK,aAAa,KAAK,KAAK,CAAC;EAEzD,MAAM,QAAQ,KAAK,iBAAiB;EACpC,MAAM,YAAY,MAAM,SAAS,IAAI,GAAG,KAAK;EAE7C,MAAM,WAAW,WAAW;AAC5B,gBAAc,GAAG,QAAQ;AACzB,SAAO;GAAE,OAAO;GAAY;GAAU;;CAGxC,kBAA0B;EACxB,IAAI,QAAQ,KAAK;AACjB,MAAI,KAAK,sBAAsB,KAAA,EAC7B,SAAQ,MAAM,QACZ,kBACA,SAAS,KAAK,oBACf;AAEH,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,WAAW,CACxD,SAAQ,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,CAAC;AAEzD,SAAO"}
1
+ {"version":3,"file":"builder.cjs","names":[],"sources":["../../src/sql/builder.ts"],"sourcesContent":["import { PgIdentifier } from \"./pg-identifier\";\n\nexport type PostgresQueryBuilderCommand =\n | \"bitmapscan\"\n | \"indexscan\"\n | \"seqscan\";\n\nexport class PostgresQueryBuilder {\n private readonly commands: Record<string, string> = {};\n private isIntrospection: boolean = false;\n private explainFlags: string[] = [];\n private _preamble = 0;\n private parameters: Record<Parameter, number> = {};\n // substitution for `limit $1` -> `limit 5`\n private limitSubstitution?: number;\n\n constructor(private query: string) {}\n\n get preamble(): number {\n return this._preamble;\n }\n\n static createIndex(definition: string, name?: PgIdentifier) {\n if (name) {\n return new PostgresQueryBuilder(\n `create index \"${name}\" on ${definition};`,\n );\n }\n return new PostgresQueryBuilder(`create index on ${definition};`);\n }\n\n enable(command: PostgresQueryBuilderCommand, value: boolean = true): this {\n const commandString = `enable_${command}`;\n if (value) {\n this.commands[commandString] = \"on\";\n } else {\n this.commands[commandString] = \"off\";\n }\n return this;\n }\n\n withQuery(query: string): this {\n this.query = query;\n return this;\n }\n\n introspect(): this {\n this.isIntrospection = true;\n return this;\n }\n\n explain(flags: string[]): this {\n this.explainFlags = flags;\n return this;\n }\n\n parameterize(parameters: Record<Parameter, number>) {\n Object.assign(this.parameters, parameters);\n return this;\n }\n\n replaceLimit(limit: number) {\n this.limitSubstitution = limit;\n return this;\n }\n\n build(): string {\n let commands = this.generateSetCommands();\n commands += this.generateExplain().query;\n if (this.isIntrospection) {\n commands += \" -- @qd_introspection\";\n }\n return commands;\n }\n\n /** Return the \"set a=b\" parts of the command in the query separate from the explain select ... part */\n buildParts() {\n const commands = this.generateSetCommands();\n const explain = this.generateExplain();\n this._preamble = explain.preamble;\n if (this.isIntrospection) {\n explain.query += \" -- @qd_introspection\";\n }\n return { commands, query: explain.query };\n }\n\n private generateSetCommands() {\n let commands = \"\";\n for (const key in this.commands) {\n const value = this.commands[key];\n commands += `set local ${key}=${value};\\n`;\n }\n return commands;\n }\n\n private generateExplain() {\n let finalQuery = \"\";\n if (this.explainFlags.length > 0) {\n finalQuery += `explain (${this.explainFlags.join(\", \")}) `;\n }\n const query = this.substituteQuery();\n const semicolon = query.endsWith(\";\") ? \"\" : \";\";\n\n const preamble = finalQuery.length;\n finalQuery += `${query}${semicolon}`;\n return { query: finalQuery, preamble };\n }\n\n private substituteQuery() {\n let query = this.query;\n if (this.limitSubstitution !== undefined) {\n query = query.replace(\n /(limit)\\s+\\$\\d+/gi,\n `$1 ${this.limitSubstitution}`,\n );\n }\n for (const [key, value] of Object.entries(this.parameters)) {\n query = query.replaceAll(`\\\\$${key}`, value.toString());\n }\n return query;\n }\n}\n\nexport type Parameter = `$${string}`;\n"],"mappings":";;;AAOA,IAAa,uBAAb,MAAa,qBAAqB;CAShC,YAAY,OAAuB;AAAf,OAAA,QAAA;+CARH,YAAmC,EAAE,CAAC;+CAC/C,mBAA2B,MAAM;+CACjC,gBAAyB,EAAE,CAAC;+CAC5B,aAAY,EAAE;+CACd,cAAwC,EAAE,CAAC;+CAE3C,qBAAA,KAAA,EAA2B;;CAInC,IAAI,WAAmB;AACrB,SAAO,KAAK;;CAGd,OAAO,YAAY,YAAoB,MAAqB;AAC1D,MAAI,KACF,QAAO,IAAI,qBACT,iBAAiB,KAAK,OAAO,WAAW,GACzC;AAEH,SAAO,IAAI,qBAAqB,mBAAmB,WAAW,GAAG;;CAGnE,OAAO,SAAsC,QAAiB,MAAY;EACxE,MAAM,gBAAgB,UAAU;AAChC,MAAI,MACF,MAAK,SAAS,iBAAiB;MAE/B,MAAK,SAAS,iBAAiB;AAEjC,SAAO;;CAGT,UAAU,OAAqB;AAC7B,OAAK,QAAQ;AACb,SAAO;;CAGT,aAAmB;AACjB,OAAK,kBAAkB;AACvB,SAAO;;CAGT,QAAQ,OAAuB;AAC7B,OAAK,eAAe;AACpB,SAAO;;CAGT,aAAa,YAAuC;AAClD,SAAO,OAAO,KAAK,YAAY,WAAW;AAC1C,SAAO;;CAGT,aAAa,OAAe;AAC1B,OAAK,oBAAoB;AACzB,SAAO;;CAGT,QAAgB;EACd,IAAI,WAAW,KAAK,qBAAqB;AACzC,cAAY,KAAK,iBAAiB,CAAC;AACnC,MAAI,KAAK,gBACP,aAAY;AAEd,SAAO;;;CAIT,aAAa;EACX,MAAM,WAAW,KAAK,qBAAqB;EAC3C,MAAM,UAAU,KAAK,iBAAiB;AACtC,OAAK,YAAY,QAAQ;AACzB,MAAI,KAAK,gBACP,SAAQ,SAAS;AAEnB,SAAO;GAAE;GAAU,OAAO,QAAQ;GAAO;;CAG3C,sBAA8B;EAC5B,IAAI,WAAW;AACf,OAAK,MAAM,OAAO,KAAK,UAAU;GAC/B,MAAM,QAAQ,KAAK,SAAS;AAC5B,eAAY,aAAa,IAAI,GAAG,MAAM;;AAExC,SAAO;;CAGT,kBAA0B;EACxB,IAAI,aAAa;AACjB,MAAI,KAAK,aAAa,SAAS,EAC7B,eAAc,YAAY,KAAK,aAAa,KAAK,KAAK,CAAC;EAEzD,MAAM,QAAQ,KAAK,iBAAiB;EACpC,MAAM,YAAY,MAAM,SAAS,IAAI,GAAG,KAAK;EAE7C,MAAM,WAAW,WAAW;AAC5B,gBAAc,GAAG,QAAQ;AACzB,SAAO;GAAE,OAAO;GAAY;GAAU;;CAGxC,kBAA0B;EACxB,IAAI,QAAQ,KAAK;AACjB,MAAI,KAAK,sBAAsB,KAAA,EAC7B,SAAQ,MAAM,QACZ,qBACA,MAAM,KAAK,oBACZ;AAEH,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,WAAW,CACxD,SAAQ,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,CAAC;AAEzD,SAAO"}
@@ -83,7 +83,7 @@ var PostgresQueryBuilder = class PostgresQueryBuilder {
83
83
  }
84
84
  substituteQuery() {
85
85
  let query = this.query;
86
- if (this.limitSubstitution !== void 0) query = query.replace(/limit\s+\$\d+/g, `limit ${this.limitSubstitution}`);
86
+ if (this.limitSubstitution !== void 0) query = query.replace(/(limit)\s+\$\d+/gi, `$1 ${this.limitSubstitution}`);
87
87
  for (const [key, value] of Object.entries(this.parameters)) query = query.replaceAll(`\\$${key}`, value.toString());
88
88
  return query;
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"builder.mjs","names":[],"sources":["../../src/sql/builder.ts"],"sourcesContent":["import { PgIdentifier } from \"./pg-identifier\";\n\nexport type PostgresQueryBuilderCommand =\n | \"bitmapscan\"\n | \"indexscan\"\n | \"seqscan\";\n\nexport class PostgresQueryBuilder {\n private readonly commands: Record<string, string> = {};\n private isIntrospection: boolean = false;\n private explainFlags: string[] = [];\n private _preamble = 0;\n private parameters: Record<Parameter, number> = {};\n // substitution for `limit $1` -> `limit 5`\n private limitSubstitution?: number;\n\n constructor(private query: string) {}\n\n get preamble(): number {\n return this._preamble;\n }\n\n static createIndex(definition: string, name?: PgIdentifier) {\n if (name) {\n return new PostgresQueryBuilder(\n `create index \"${name}\" on ${definition};`,\n );\n }\n return new PostgresQueryBuilder(`create index on ${definition};`);\n }\n\n enable(command: PostgresQueryBuilderCommand, value: boolean = true): this {\n const commandString = `enable_${command}`;\n if (value) {\n this.commands[commandString] = \"on\";\n } else {\n this.commands[commandString] = \"off\";\n }\n return this;\n }\n\n withQuery(query: string): this {\n this.query = query;\n return this;\n }\n\n introspect(): this {\n this.isIntrospection = true;\n return this;\n }\n\n explain(flags: string[]): this {\n this.explainFlags = flags;\n return this;\n }\n\n parameterize(parameters: Record<Parameter, number>) {\n Object.assign(this.parameters, parameters);\n return this;\n }\n\n replaceLimit(limit: number) {\n this.limitSubstitution = limit;\n return this;\n }\n\n build(): string {\n let commands = this.generateSetCommands();\n commands += this.generateExplain().query;\n if (this.isIntrospection) {\n commands += \" -- @qd_introspection\";\n }\n return commands;\n }\n\n /** Return the \"set a=b\" parts of the command in the query separate from the explain select ... part */\n buildParts() {\n const commands = this.generateSetCommands();\n const explain = this.generateExplain();\n this._preamble = explain.preamble;\n if (this.isIntrospection) {\n explain.query += \" -- @qd_introspection\";\n }\n return { commands, query: explain.query };\n }\n\n private generateSetCommands() {\n let commands = \"\";\n for (const key in this.commands) {\n const value = this.commands[key];\n commands += `set local ${key}=${value};\\n`;\n }\n return commands;\n }\n\n private generateExplain() {\n let finalQuery = \"\";\n if (this.explainFlags.length > 0) {\n finalQuery += `explain (${this.explainFlags.join(\", \")}) `;\n }\n const query = this.substituteQuery();\n const semicolon = query.endsWith(\";\") ? \"\" : \";\";\n\n const preamble = finalQuery.length;\n finalQuery += `${query}${semicolon}`;\n return { query: finalQuery, preamble };\n }\n\n private substituteQuery() {\n let query = this.query;\n if (this.limitSubstitution !== undefined) {\n query = query.replace(\n /limit\\s+\\$\\d+/g,\n `limit ${this.limitSubstitution}`,\n );\n }\n for (const [key, value] of Object.entries(this.parameters)) {\n query = query.replaceAll(`\\\\$${key}`, value.toString());\n }\n return query;\n }\n}\n\nexport type Parameter = `$${string}`;\n"],"mappings":";;;AAOA,IAAa,uBAAb,MAAa,qBAAqB;CAShC,YAAY,OAAuB;AAAf,OAAA,QAAA;wBARH,YAAmC,EAAE,CAAC;wBAC/C,mBAA2B,MAAM;wBACjC,gBAAyB,EAAE,CAAC;wBAC5B,aAAY,EAAE;wBACd,cAAwC,EAAE,CAAC;wBAE3C,qBAAA,KAAA,EAA2B;;CAInC,IAAI,WAAmB;AACrB,SAAO,KAAK;;CAGd,OAAO,YAAY,YAAoB,MAAqB;AAC1D,MAAI,KACF,QAAO,IAAI,qBACT,iBAAiB,KAAK,OAAO,WAAW,GACzC;AAEH,SAAO,IAAI,qBAAqB,mBAAmB,WAAW,GAAG;;CAGnE,OAAO,SAAsC,QAAiB,MAAY;EACxE,MAAM,gBAAgB,UAAU;AAChC,MAAI,MACF,MAAK,SAAS,iBAAiB;MAE/B,MAAK,SAAS,iBAAiB;AAEjC,SAAO;;CAGT,UAAU,OAAqB;AAC7B,OAAK,QAAQ;AACb,SAAO;;CAGT,aAAmB;AACjB,OAAK,kBAAkB;AACvB,SAAO;;CAGT,QAAQ,OAAuB;AAC7B,OAAK,eAAe;AACpB,SAAO;;CAGT,aAAa,YAAuC;AAClD,SAAO,OAAO,KAAK,YAAY,WAAW;AAC1C,SAAO;;CAGT,aAAa,OAAe;AAC1B,OAAK,oBAAoB;AACzB,SAAO;;CAGT,QAAgB;EACd,IAAI,WAAW,KAAK,qBAAqB;AACzC,cAAY,KAAK,iBAAiB,CAAC;AACnC,MAAI,KAAK,gBACP,aAAY;AAEd,SAAO;;;CAIT,aAAa;EACX,MAAM,WAAW,KAAK,qBAAqB;EAC3C,MAAM,UAAU,KAAK,iBAAiB;AACtC,OAAK,YAAY,QAAQ;AACzB,MAAI,KAAK,gBACP,SAAQ,SAAS;AAEnB,SAAO;GAAE;GAAU,OAAO,QAAQ;GAAO;;CAG3C,sBAA8B;EAC5B,IAAI,WAAW;AACf,OAAK,MAAM,OAAO,KAAK,UAAU;GAC/B,MAAM,QAAQ,KAAK,SAAS;AAC5B,eAAY,aAAa,IAAI,GAAG,MAAM;;AAExC,SAAO;;CAGT,kBAA0B;EACxB,IAAI,aAAa;AACjB,MAAI,KAAK,aAAa,SAAS,EAC7B,eAAc,YAAY,KAAK,aAAa,KAAK,KAAK,CAAC;EAEzD,MAAM,QAAQ,KAAK,iBAAiB;EACpC,MAAM,YAAY,MAAM,SAAS,IAAI,GAAG,KAAK;EAE7C,MAAM,WAAW,WAAW;AAC5B,gBAAc,GAAG,QAAQ;AACzB,SAAO;GAAE,OAAO;GAAY;GAAU;;CAGxC,kBAA0B;EACxB,IAAI,QAAQ,KAAK;AACjB,MAAI,KAAK,sBAAsB,KAAA,EAC7B,SAAQ,MAAM,QACZ,kBACA,SAAS,KAAK,oBACf;AAEH,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,WAAW,CACxD,SAAQ,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,CAAC;AAEzD,SAAO"}
1
+ {"version":3,"file":"builder.mjs","names":[],"sources":["../../src/sql/builder.ts"],"sourcesContent":["import { PgIdentifier } from \"./pg-identifier\";\n\nexport type PostgresQueryBuilderCommand =\n | \"bitmapscan\"\n | \"indexscan\"\n | \"seqscan\";\n\nexport class PostgresQueryBuilder {\n private readonly commands: Record<string, string> = {};\n private isIntrospection: boolean = false;\n private explainFlags: string[] = [];\n private _preamble = 0;\n private parameters: Record<Parameter, number> = {};\n // substitution for `limit $1` -> `limit 5`\n private limitSubstitution?: number;\n\n constructor(private query: string) {}\n\n get preamble(): number {\n return this._preamble;\n }\n\n static createIndex(definition: string, name?: PgIdentifier) {\n if (name) {\n return new PostgresQueryBuilder(\n `create index \"${name}\" on ${definition};`,\n );\n }\n return new PostgresQueryBuilder(`create index on ${definition};`);\n }\n\n enable(command: PostgresQueryBuilderCommand, value: boolean = true): this {\n const commandString = `enable_${command}`;\n if (value) {\n this.commands[commandString] = \"on\";\n } else {\n this.commands[commandString] = \"off\";\n }\n return this;\n }\n\n withQuery(query: string): this {\n this.query = query;\n return this;\n }\n\n introspect(): this {\n this.isIntrospection = true;\n return this;\n }\n\n explain(flags: string[]): this {\n this.explainFlags = flags;\n return this;\n }\n\n parameterize(parameters: Record<Parameter, number>) {\n Object.assign(this.parameters, parameters);\n return this;\n }\n\n replaceLimit(limit: number) {\n this.limitSubstitution = limit;\n return this;\n }\n\n build(): string {\n let commands = this.generateSetCommands();\n commands += this.generateExplain().query;\n if (this.isIntrospection) {\n commands += \" -- @qd_introspection\";\n }\n return commands;\n }\n\n /** Return the \"set a=b\" parts of the command in the query separate from the explain select ... part */\n buildParts() {\n const commands = this.generateSetCommands();\n const explain = this.generateExplain();\n this._preamble = explain.preamble;\n if (this.isIntrospection) {\n explain.query += \" -- @qd_introspection\";\n }\n return { commands, query: explain.query };\n }\n\n private generateSetCommands() {\n let commands = \"\";\n for (const key in this.commands) {\n const value = this.commands[key];\n commands += `set local ${key}=${value};\\n`;\n }\n return commands;\n }\n\n private generateExplain() {\n let finalQuery = \"\";\n if (this.explainFlags.length > 0) {\n finalQuery += `explain (${this.explainFlags.join(\", \")}) `;\n }\n const query = this.substituteQuery();\n const semicolon = query.endsWith(\";\") ? \"\" : \";\";\n\n const preamble = finalQuery.length;\n finalQuery += `${query}${semicolon}`;\n return { query: finalQuery, preamble };\n }\n\n private substituteQuery() {\n let query = this.query;\n if (this.limitSubstitution !== undefined) {\n query = query.replace(\n /(limit)\\s+\\$\\d+/gi,\n `$1 ${this.limitSubstitution}`,\n );\n }\n for (const [key, value] of Object.entries(this.parameters)) {\n query = query.replaceAll(`\\\\$${key}`, value.toString());\n }\n return query;\n }\n}\n\nexport type Parameter = `$${string}`;\n"],"mappings":";;;AAOA,IAAa,uBAAb,MAAa,qBAAqB;CAShC,YAAY,OAAuB;AAAf,OAAA,QAAA;wBARH,YAAmC,EAAE,CAAC;wBAC/C,mBAA2B,MAAM;wBACjC,gBAAyB,EAAE,CAAC;wBAC5B,aAAY,EAAE;wBACd,cAAwC,EAAE,CAAC;wBAE3C,qBAAA,KAAA,EAA2B;;CAInC,IAAI,WAAmB;AACrB,SAAO,KAAK;;CAGd,OAAO,YAAY,YAAoB,MAAqB;AAC1D,MAAI,KACF,QAAO,IAAI,qBACT,iBAAiB,KAAK,OAAO,WAAW,GACzC;AAEH,SAAO,IAAI,qBAAqB,mBAAmB,WAAW,GAAG;;CAGnE,OAAO,SAAsC,QAAiB,MAAY;EACxE,MAAM,gBAAgB,UAAU;AAChC,MAAI,MACF,MAAK,SAAS,iBAAiB;MAE/B,MAAK,SAAS,iBAAiB;AAEjC,SAAO;;CAGT,UAAU,OAAqB;AAC7B,OAAK,QAAQ;AACb,SAAO;;CAGT,aAAmB;AACjB,OAAK,kBAAkB;AACvB,SAAO;;CAGT,QAAQ,OAAuB;AAC7B,OAAK,eAAe;AACpB,SAAO;;CAGT,aAAa,YAAuC;AAClD,SAAO,OAAO,KAAK,YAAY,WAAW;AAC1C,SAAO;;CAGT,aAAa,OAAe;AAC1B,OAAK,oBAAoB;AACzB,SAAO;;CAGT,QAAgB;EACd,IAAI,WAAW,KAAK,qBAAqB;AACzC,cAAY,KAAK,iBAAiB,CAAC;AACnC,MAAI,KAAK,gBACP,aAAY;AAEd,SAAO;;;CAIT,aAAa;EACX,MAAM,WAAW,KAAK,qBAAqB;EAC3C,MAAM,UAAU,KAAK,iBAAiB;AACtC,OAAK,YAAY,QAAQ;AACzB,MAAI,KAAK,gBACP,SAAQ,SAAS;AAEnB,SAAO;GAAE;GAAU,OAAO,QAAQ;GAAO;;CAG3C,sBAA8B;EAC5B,IAAI,WAAW;AACf,OAAK,MAAM,OAAO,KAAK,UAAU;GAC/B,MAAM,QAAQ,KAAK,SAAS;AAC5B,eAAY,aAAa,IAAI,GAAG,MAAM;;AAExC,SAAO;;CAGT,kBAA0B;EACxB,IAAI,aAAa;AACjB,MAAI,KAAK,aAAa,SAAS,EAC7B,eAAc,YAAY,KAAK,aAAa,KAAK,KAAK,CAAC;EAEzD,MAAM,QAAQ,KAAK,iBAAiB;EACpC,MAAM,YAAY,MAAM,SAAS,IAAI,GAAG,KAAK;EAE7C,MAAM,WAAW,WAAW;AAC5B,gBAAc,GAAG,QAAQ;AACzB,SAAO;GAAE,OAAO;GAAY;GAAU;;CAGxC,kBAA0B;EACxB,IAAI,QAAQ,KAAK;AACjB,MAAI,KAAK,sBAAsB,KAAA,EAC7B,SAAQ,MAAM,QACZ,qBACA,MAAM,KAAK,oBACZ;AAEH,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,WAAW,CACxD,SAAQ,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,CAAC;AAEzD,SAAO"}
@@ -42,6 +42,7 @@ interface ServerApi {
42
42
  log(line: string, process?: string): Promise<void>;
43
43
  ping(): Promise<void>;
44
44
  getRepoConfig(repo: string, branch: string): Promise<RepoConfig>;
45
+ getProductionStats(): Promise<ExportedStats[] | null>;
45
46
  }
46
47
  interface ClientApi {
47
48
  repull(): Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-server.d.cts","names":[],"sources":["../src/websocket-server.ts"],"mappings":";;;;;;;KAIY,eAAA;EACV,UAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA,EAAS,KAAA;IACP,IAAA;IACA,KAAA;IACA,OAAA;EAAA;EAEF,cAAA;AAAA;AAAA,KAGU,iBAAA;EAEN,IAAA;EACA,aAAA;EACA,YAAA;AAAA;EAGA,IAAA;AAAA;AAAA,KAGM,UAAA;EACV,WAAA;EACA,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,uBAAA;EACA,gBAAA;AAAA;AAAA,UAGe,SAAA;EACf,SAAA,CAAU,OAAA,EAAS,cAAA,KAAmB,OAAA;EACtC,SAAA,CAAU,KAAA,EAAO,aAAA,KAAkB,OAAA;EACnC,UAAA,CAAW,MAAA,YAAkB,OAAA;EAC7B,kBAAA,CAAmB,KAAA,EAAO,UAAA,GAAa,OAAA;EACvC,oBAAA,CAAqB,QAAA,EAAU,iBAAA,GAAoB,OAAA;EACnD,GAAA,CAAI,IAAA,UAAc,OAAA,YAAmB,OAAA;EACrC,IAAA,IAAQ,OAAA;EACR,aAAA,CAAc,IAAA,UAAc,MAAA,WAAiB,OAAA,CAAQ,UAAA;AAAA;AAAA,UAGtC,SAAA;EACf,MAAA,IAAU,OAAA;EACV,cAAA,IAAkB,OAAA;EAClB,gBAAA,CAAiB,KAAA,EAAO,aAAA,KAAkB,OAAA;EAC1C,SAAA,CAAU,SAAA,WAAoB,OAAA;EAC9B,QAAA,CAAS,KAAA,EAAO,eAAA,GAAkB,OAAA;EAClC,QAAA,CAAS,KAAA,WAAgB,OAAA;EAGzB,UAAA,IAAc,OAAA;AAAA;AAAA,KAGJ,cAAA;EACN,IAAA;EAAoB,WAAA;AAAA;EACpB,IAAA;EAAY,MAAA;EAAgB,GAAA;EAAa,KAAA;AAAA;AAAA,UAE9B,wBAAA;EACf,YAAA,CACE,KAAA,UACA,MAAA,EAAQ,OAAA,CAAQ,SAAA,GAChB,IAAA,EAAM,cAAA,GACL,OAAA,CAAQ,SAAA;AAAA"}
1
+ {"version":3,"file":"websocket-server.d.cts","names":[],"sources":["../src/websocket-server.ts"],"mappings":";;;;;;;KAIY,eAAA;EACV,UAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA,EAAS,KAAA;IACP,IAAA;IACA,KAAA;IACA,OAAA;EAAA;EAEF,cAAA;AAAA;AAAA,KAGU,iBAAA;EAEN,IAAA;EACA,aAAA;EACA,YAAA;AAAA;EAGA,IAAA;AAAA;AAAA,KAGM,UAAA;EACV,WAAA;EACA,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,uBAAA;EACA,gBAAA;AAAA;AAAA,UAGe,SAAA;EACf,SAAA,CAAU,OAAA,EAAS,cAAA,KAAmB,OAAA;EACtC,SAAA,CAAU,KAAA,EAAO,aAAA,KAAkB,OAAA;EACnC,UAAA,CAAW,MAAA,YAAkB,OAAA;EAC7B,kBAAA,CAAmB,KAAA,EAAO,UAAA,GAAa,OAAA;EACvC,oBAAA,CAAqB,QAAA,EAAU,iBAAA,GAAoB,OAAA;EACnD,GAAA,CAAI,IAAA,UAAc,OAAA,YAAmB,OAAA;EACrC,IAAA,IAAQ,OAAA;EACR,aAAA,CAAc,IAAA,UAAc,MAAA,WAAiB,OAAA,CAAQ,UAAA;EAIrD,kBAAA,IAAsB,OAAA,CAAQ,aAAA;AAAA;AAAA,UAGf,SAAA;EACf,MAAA,IAAU,OAAA;EACV,cAAA,IAAkB,OAAA;EAClB,gBAAA,CAAiB,KAAA,EAAO,aAAA,KAAkB,OAAA;EAC1C,SAAA,CAAU,SAAA,WAAoB,OAAA;EAC9B,QAAA,CAAS,KAAA,EAAO,eAAA,GAAkB,OAAA;EAClC,QAAA,CAAS,KAAA,WAAgB,OAAA;EAGzB,UAAA,IAAc,OAAA;AAAA;AAAA,KAGJ,cAAA;EACN,IAAA;EAAoB,WAAA;AAAA;EACpB,IAAA;EAAY,MAAA;EAAgB,GAAA;EAAa,KAAA;AAAA;AAAA,UAE9B,wBAAA;EACf,YAAA,CACE,KAAA,UACA,MAAA,EAAQ,OAAA,CAAQ,SAAA,GAChB,IAAA,EAAM,cAAA,GACL,OAAA,CAAQ,SAAA;AAAA"}
@@ -42,6 +42,7 @@ interface ServerApi {
42
42
  log(line: string, process?: string): Promise<void>;
43
43
  ping(): Promise<void>;
44
44
  getRepoConfig(repo: string, branch: string): Promise<RepoConfig>;
45
+ getProductionStats(): Promise<ExportedStats[] | null>;
45
46
  }
46
47
  interface ClientApi {
47
48
  repull(): Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-server.d.mts","names":[],"sources":["../src/websocket-server.ts"],"mappings":";;;;;;;KAIY,eAAA;EACV,UAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA,EAAS,KAAA;IACP,IAAA;IACA,KAAA;IACA,OAAA;EAAA;EAEF,cAAA;AAAA;AAAA,KAGU,iBAAA;EAEN,IAAA;EACA,aAAA;EACA,YAAA;AAAA;EAGA,IAAA;AAAA;AAAA,KAGM,UAAA;EACV,WAAA;EACA,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,uBAAA;EACA,gBAAA;AAAA;AAAA,UAGe,SAAA;EACf,SAAA,CAAU,OAAA,EAAS,cAAA,KAAmB,OAAA;EACtC,SAAA,CAAU,KAAA,EAAO,aAAA,KAAkB,OAAA;EACnC,UAAA,CAAW,MAAA,YAAkB,OAAA;EAC7B,kBAAA,CAAmB,KAAA,EAAO,UAAA,GAAa,OAAA;EACvC,oBAAA,CAAqB,QAAA,EAAU,iBAAA,GAAoB,OAAA;EACnD,GAAA,CAAI,IAAA,UAAc,OAAA,YAAmB,OAAA;EACrC,IAAA,IAAQ,OAAA;EACR,aAAA,CAAc,IAAA,UAAc,MAAA,WAAiB,OAAA,CAAQ,UAAA;AAAA;AAAA,UAGtC,SAAA;EACf,MAAA,IAAU,OAAA;EACV,cAAA,IAAkB,OAAA;EAClB,gBAAA,CAAiB,KAAA,EAAO,aAAA,KAAkB,OAAA;EAC1C,SAAA,CAAU,SAAA,WAAoB,OAAA;EAC9B,QAAA,CAAS,KAAA,EAAO,eAAA,GAAkB,OAAA;EAClC,QAAA,CAAS,KAAA,WAAgB,OAAA;EAGzB,UAAA,IAAc,OAAA;AAAA;AAAA,KAGJ,cAAA;EACN,IAAA;EAAoB,WAAA;AAAA;EACpB,IAAA;EAAY,MAAA;EAAgB,GAAA;EAAa,KAAA;AAAA;AAAA,UAE9B,wBAAA;EACf,YAAA,CACE,KAAA,UACA,MAAA,EAAQ,OAAA,CAAQ,SAAA,GAChB,IAAA,EAAM,cAAA,GACL,OAAA,CAAQ,SAAA;AAAA"}
1
+ {"version":3,"file":"websocket-server.d.mts","names":[],"sources":["../src/websocket-server.ts"],"mappings":";;;;;;;KAIY,eAAA;EACV,UAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA,EAAS,KAAA;IACP,IAAA;IACA,KAAA;IACA,OAAA;EAAA;EAEF,cAAA;AAAA;AAAA,KAGU,iBAAA;EAEN,IAAA;EACA,aAAA;EACA,YAAA;AAAA;EAGA,IAAA;AAAA;AAAA,KAGM,UAAA;EACV,WAAA;EACA,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,uBAAA;EACA,gBAAA;AAAA;AAAA,UAGe,SAAA;EACf,SAAA,CAAU,OAAA,EAAS,cAAA,KAAmB,OAAA;EACtC,SAAA,CAAU,KAAA,EAAO,aAAA,KAAkB,OAAA;EACnC,UAAA,CAAW,MAAA,YAAkB,OAAA;EAC7B,kBAAA,CAAmB,KAAA,EAAO,UAAA,GAAa,OAAA;EACvC,oBAAA,CAAqB,QAAA,EAAU,iBAAA,GAAoB,OAAA;EACnD,GAAA,CAAI,IAAA,UAAc,OAAA,YAAmB,OAAA;EACrC,IAAA,IAAQ,OAAA;EACR,aAAA,CAAc,IAAA,UAAc,MAAA,WAAiB,OAAA,CAAQ,UAAA;EAIrD,kBAAA,IAAsB,OAAA,CAAQ,aAAA;AAAA;AAAA,UAGf,SAAA;EACf,MAAA,IAAU,OAAA;EACV,cAAA,IAAkB,OAAA;EAClB,gBAAA,CAAiB,KAAA,EAAO,aAAA,KAAkB,OAAA;EAC1C,SAAA,CAAU,SAAA,WAAoB,OAAA;EAC9B,QAAA,CAAS,KAAA,EAAO,eAAA,GAAkB,OAAA;EAClC,QAAA,CAAS,KAAA,WAAgB,OAAA;EAGzB,UAAA,IAAc,OAAA;AAAA;AAAA,KAGJ,cAAA;EACN,IAAA;EAAoB,WAAA;AAAA;EACpB,IAAA;EAAY,MAAA;EAAgB,GAAA;EAAa,KAAA;AAAA;AAAA,UAE9B,wBAAA;EACf,YAAA,CACE,KAAA,UACA,MAAA,EAAQ,OAAA,CAAQ,SAAA,GAChB,IAAA,EAAM,cAAA,GACL,OAAA,CAAQ,SAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@query-doctor/core",
3
- "version": "0.10.3",
3
+ "version": "0.10.4",
4
4
  "private": false,
5
5
  "description": "Core logic for Query Doctor",
6
6
  "license": "",