@backstage-community/plugin-copilot-backend 0.15.1 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @backstage-community/plugin-copilot-backend
2
2
 
3
+ ## 0.15.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 53e4a3b: fixes sql for engagement-metrics with the change from null to empty string.
8
+
9
+ ## 0.15.2
10
+
11
+ ### Patch Changes
12
+
13
+ - 1b7adc8: Fixed a mismatch between the backend requiring copilot.host and the config declaration stating it was optional.
14
+
3
15
  ## 0.15.1
4
16
 
5
17
  ### Patch Changes
package/config.d.ts CHANGED
@@ -37,6 +37,6 @@ export interface Config {
37
37
  /**
38
38
  * The host for GitHub Copilot integration.
39
39
  */
40
- host?: string;
40
+ host: string;
41
41
  };
42
42
  }
@@ -112,7 +112,7 @@ class DatabaseHandler {
112
112
  return await this.db("seats").where("type", type).where("team_name", teamName ?? "").whereBetween("day", [startDate, endDate]).orderBy("day", "asc");
113
113
  }
114
114
  async getEngagementMetrics(startDate, endDate, type, teamName) {
115
- let query = this.db("copilot_metrics as cm").select(
115
+ const query = this.db("copilot_metrics as cm").select(
116
116
  "cm.day",
117
117
  "cm.type",
118
118
  "cm.team_name",
@@ -135,47 +135,30 @@ class DatabaseHandler {
135
135
  "CAST(MIN(dotcom_prs.total_engaged_users) AS INTEGER) as dotcom_prs_engaged_users"
136
136
  )
137
137
  ).leftJoin("ide_completions", (join) => {
138
- join.on("ide_completions.day", "=", "cm.day").andOn("ide_completions.type", "=", "cm.type");
139
- if (teamName) {
140
- join.andOn(
141
- "ide_completions.team_name",
142
- "=",
143
- this.db.raw("?", [teamName])
144
- );
145
- } else {
146
- join.andOnNull("ide_completions.team_name");
147
- }
138
+ join.on("ide_completions.day", "=", "cm.day").andOn("ide_completions.type", "=", "cm.type").andOn(
139
+ "ide_completions.team_name",
140
+ "=",
141
+ this.db.raw("?", [teamName ?? ""])
142
+ );
148
143
  }).leftJoin("ide_chats", (join) => {
149
- join.on("ide_chats.day", "=", "cm.day").andOn("ide_chats.type", "=", "cm.type");
150
- if (teamName) {
151
- join.andOn("ide_chats.team_name", "=", this.db.raw("?", [teamName]));
152
- } else {
153
- join.andOnNull("ide_chats.team_name");
154
- }
144
+ join.on("ide_chats.day", "=", "cm.day").andOn("ide_chats.type", "=", "cm.type").andOn(
145
+ "ide_chats.team_name",
146
+ "=",
147
+ this.db.raw("?", [teamName ?? ""])
148
+ );
155
149
  }).leftJoin("dotcom_chats", (join) => {
156
- join.on("dotcom_chats.day", "=", "cm.day").andOn("dotcom_chats.type", "=", "cm.type");
157
- if (teamName) {
158
- join.andOn(
159
- "dotcom_chats.team_name",
160
- "=",
161
- this.db.raw("?", [teamName])
162
- );
163
- } else {
164
- join.andOnNull("dotcom_chats.team_name");
165
- }
150
+ join.on("dotcom_chats.day", "=", "cm.day").andOn("dotcom_chats.type", "=", "cm.type").andOn(
151
+ "dotcom_chats.team_name",
152
+ "=",
153
+ this.db.raw("?", [teamName ?? ""])
154
+ );
166
155
  }).leftJoin("dotcom_prs", (join) => {
167
- join.on("dotcom_prs.day", "=", "cm.day").andOn("dotcom_prs.type", "=", "cm.type");
168
- if (teamName) {
169
- join.andOn("dotcom_prs.team_name", "=", this.db.raw("?", [teamName]));
170
- } else {
171
- join.andOnNull("dotcom_prs.team_name");
172
- }
173
- }).where("cm.type", type).whereBetween("cm.day", [startDate, endDate]).groupBy("cm.day", "cm.type", "cm.team_name").orderBy("cm.day", "asc");
174
- if (teamName) {
175
- query = query.where("cm.team_name", teamName);
176
- } else {
177
- query = query.whereNull("cm.team_name");
178
- }
156
+ join.on("dotcom_prs.day", "=", "cm.day").andOn("dotcom_prs.type", "=", "cm.type").andOn(
157
+ "dotcom_prs.team_name",
158
+ "=",
159
+ this.db.raw("?", [teamName ?? ""])
160
+ );
161
+ }).where("cm.type", type).where("cm.team_name", teamName ?? "").whereBetween("cm.day", [startDate, endDate]).groupBy("cm.day", "cm.type", "cm.team_name").orderBy("cm.day", "asc");
179
162
  return await query;
180
163
  }
181
164
  async getMetricsV2(startDate, endDate, type, teamName) {
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseHandler.cjs.js","sources":["../../src/db/DatabaseHandler.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n resolvePackagePath,\n DatabaseService,\n} from '@backstage/backend-plugin-api';\nimport {\n Metric,\n MetricsType,\n PeriodRange,\n CopilotIdeCodeCompletions,\n CopilotIdeLanguages,\n CopilotMetrics,\n CopilotEditors,\n CopilotModels,\n CopilotLanguages,\n CopilotChats,\n CopilotChatEditors,\n CopilotChatModels,\n EngagementMetrics,\n SeatAnalysis,\n} from '@backstage-community/plugin-copilot-common';\nimport { Knex } from 'knex';\n\nexport const migrationsDir = resolvePackagePath(\n '@backstage-community/plugin-copilot-backend',\n 'migrations',\n);\n\ntype Options = {\n database: DatabaseService;\n};\n\nexport type Breakdown = {\n day: string;\n editor: string;\n language: string;\n lines_accepted: number;\n lines_suggested: number;\n suggestions_count: number;\n acceptances_count: number;\n active_users: number;\n};\n\nexport type CopilotMetricsDb = Omit<\n CopilotMetrics,\n | 'date'\n | 'copilot_ide_code_completions'\n | 'copilot_ide_chat'\n | 'copilot_dotcom_chat'\n | 'copilot_dotcom_pull_requests'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n};\n\nexport type CopilotIdeCodeCompletionsDb = Omit<\n CopilotIdeCodeCompletions,\n 'editors' | 'languages'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n};\n\nexport type CopilotIdeCodeCompletionsLanguageDb = Omit<\n CopilotIdeLanguages,\n 'day' | 'name' | 'language'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n language: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorsDb = Omit<\n CopilotEditors,\n 'day' | 'name' | 'models'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n};\n\nexport type CopilotIdeChatsDb = Omit<CopilotChats, 'day' | 'editors'> & {\n day: string;\n};\n\nexport type CopilotIdeChatsEditorsDb = Omit<\n CopilotChatEditors,\n 'day' | 'name' | 'models' | 'editor'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n};\n\nexport type CopilotIdeChatsEditorModelDb = Omit<\n CopilotChatModels,\n 'name' | 'day' | 'model' | 'editor'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorModelsDb = Omit<\n CopilotModels,\n 'day' | 'editor' | 'model' | 'name' | 'languages'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorModelLanguagesDb = Omit<\n CopilotLanguages,\n 'day' | 'editor' | 'model' | 'name' | 'language'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n language: string;\n};\n\nexport type MetricDbRow = Omit<Metric, 'breakdown'> & {\n breakdown: string;\n};\n\nexport class DatabaseHandler {\n static async create(options: Options): Promise<DatabaseHandler> {\n const { database } = options;\n const client = await database.getClient();\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new DatabaseHandler(client);\n }\n\n private constructor(private readonly db: Knex) {}\n\n async getPeriodRange(type: MetricsType): Promise<PeriodRange | undefined> {\n const query = this.db<MetricDbRow>('metrics').where('type', type);\n\n const minDate = await query.orderBy('day', 'asc').first('day');\n const maxDate = await query.orderBy('day', 'desc').first('day');\n\n if (!minDate?.day || !maxDate?.day) return undefined;\n\n return { minDate: minDate.day, maxDate: maxDate.day };\n }\n\n async getPeriodRangeV2(type: MetricsType): Promise<PeriodRange | undefined> {\n const query = this.db('copilot_metrics').where('type', type);\n\n const minDate = await query.orderBy('day', 'asc').first('day');\n const maxDate = await query.orderBy('day', 'desc').first('day');\n\n if (!minDate?.day || !maxDate?.day) return undefined;\n\n return { minDate: minDate.day, maxDate: maxDate.day };\n }\n\n async getTeams(\n type: MetricsType,\n startDate: string,\n endDate: string,\n ): Promise<Array<string | undefined>> {\n const result = await this.db<MetricDbRow>('copilot_metrics')\n .where('type', type)\n .whereBetween('day', [startDate, endDate])\n .whereNot('team_name', '')\n .distinct('team_name')\n .orderBy('team_name', 'asc')\n .select('team_name');\n\n return result.map(x => x.team_name);\n }\n\n async batchInsert(metrics: MetricDbRow[]): Promise<void> {\n await this.db<MetricDbRow[]>('metrics')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertMetrics(metrics: CopilotMetricsDb[]): Promise<void> {\n await this.db<CopilotMetricsDb[]>('copilot_metrics')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeCompletions(\n metrics: CopilotIdeCodeCompletionsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsDb[]>('ide_completions')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsLanguages(\n metrics: CopilotIdeCodeCompletionsLanguageDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsLanguageDb[]>(\n 'ide_completions_language_users',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'language'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditors(\n metrics: CopilotIdeCodeCompletionsEditorsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorsDb[]>(\n 'ide_completions_language_editors',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditorModels(\n metrics: CopilotIdeCodeCompletionsEditorModelsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorModelsDb[]>(\n 'ide_completions_language_editors_model',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditorModelLanguages(\n metrics: CopilotIdeCodeCompletionsEditorModelLanguagesDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorModelLanguagesDb[]>(\n 'ide_completions_language_editors_model_language',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model', 'language'])\n .ignore();\n }\n\n async batchInsertIdeChats(metrics: CopilotIdeChatsDb[]): Promise<void> {\n await this.db<CopilotIdeChatsDb[]>('ide_chats')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeChatEditors(\n metrics: CopilotIdeChatsEditorsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeChatsEditorsDb[]>('ide_chat_editors')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor'])\n .ignore();\n }\n\n async batchInsertIdeChatEditorModels(\n metrics: CopilotIdeChatsEditorModelDb[],\n ): Promise<void> {\n await this.db<CopilotIdeChatsEditorModelDb[]>('ide_chat_editors_model')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model'])\n .ignore();\n }\n\n async insertSeatAnalysys(metric: SeatAnalysis): Promise<void> {\n await this.db<SeatAnalysis>('seats')\n .insert(metric)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async getMostRecentDayFromMetrics(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'desc')\n .first('day');\n return query ? query.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getMostRecentDayFromMetricsV2(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = this.db('copilot_metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'desc')\n .first('day');\n const res = await query;\n return res ? res.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getEarliestDayFromMetricsV2(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = this.db('copilot_metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'asc')\n .first('day');\n const res = await query;\n return res ? res.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<MetricDbRow[]> {\n return await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .whereBetween('day', [startDate, endDate]);\n }\n\n async getSeatMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<SeatAnalysis[]> {\n return await this.db<SeatAnalysis>('seats')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .whereBetween('day', [startDate, endDate])\n .orderBy('day', 'asc');\n }\n\n async getEngagementMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<EngagementMetrics[]> {\n let query = this.db('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'cm.type',\n 'cm.team_name',\n this.db.raw(\n 'CAST(MIN(cm.total_active_users) AS INTEGER) as total_active_users',\n ),\n this.db.raw(\n 'CAST(MIN(cm.total_engaged_users) AS INTEGER) as total_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_completions.total_engaged_users) AS INTEGER) as ide_completions_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_chats.total_engaged_users) AS INTEGER) as ide_chats_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(dotcom_chats.total_engaged_users) AS INTEGER) as dotcom_chats_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(dotcom_prs.total_engaged_users) AS INTEGER) as dotcom_prs_engaged_users',\n ),\n )\n .leftJoin('ide_completions', join => {\n join\n .on('ide_completions.day', '=', 'cm.day')\n .andOn('ide_completions.type', '=', 'cm.type');\n if (teamName) {\n join.andOn(\n 'ide_completions.team_name',\n '=',\n this.db.raw('?', [teamName]),\n );\n } else {\n join.andOnNull('ide_completions.team_name');\n }\n })\n .leftJoin('ide_chats', join => {\n join\n .on('ide_chats.day', '=', 'cm.day')\n .andOn('ide_chats.type', '=', 'cm.type');\n if (teamName) {\n join.andOn('ide_chats.team_name', '=', this.db.raw('?', [teamName]));\n } else {\n join.andOnNull('ide_chats.team_name');\n }\n })\n .leftJoin('dotcom_chats', join => {\n join\n .on('dotcom_chats.day', '=', 'cm.day')\n .andOn('dotcom_chats.type', '=', 'cm.type');\n if (teamName) {\n join.andOn(\n 'dotcom_chats.team_name',\n '=',\n this.db.raw('?', [teamName]),\n );\n } else {\n join.andOnNull('dotcom_chats.team_name');\n }\n })\n .leftJoin('dotcom_prs', join => {\n join\n .on('dotcom_prs.day', '=', 'cm.day')\n .andOn('dotcom_prs.type', '=', 'cm.type');\n if (teamName) {\n join.andOn('dotcom_prs.team_name', '=', this.db.raw('?', [teamName]));\n } else {\n join.andOnNull('dotcom_prs.team_name');\n }\n })\n .where('cm.type', type)\n .whereBetween('cm.day', [startDate, endDate])\n .groupBy('cm.day', 'cm.type', 'cm.team_name')\n .orderBy('cm.day', 'asc');\n\n if (teamName) {\n query = query.where('cm.team_name', teamName);\n } else {\n query = query.whereNull('cm.team_name');\n }\n\n return await query;\n }\n\n async getMetricsV2(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<MetricDbRow[]> {\n const query = this.db('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'cm.type',\n 'cm.team_name',\n this.db.raw(\n 'CAST(MIN(cm.total_active_users) AS INTEGER) as total_active_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_chats.total_engaged_users) AS INTEGER) as total_active_chat_users',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_suggestions) AS INTEGER) as total_suggestions_count',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_acceptances) AS INTEGER) as total_acceptances_count',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_lines_suggested) AS INTEGER) as total_lines_suggested',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_lines_accepted) AS INTEGER) as total_lines_accepted',\n ),\n this.db.raw(\n 'CAST(SUM(icem.total_chats) AS INTEGER) as total_chat_turns',\n ),\n this.db.raw(\n 'CAST(SUM(icem.total_chat_copy_events) AS INTEGER) as total_chat_acceptances',\n ),\n this.db.raw(\"'' as breakdown\"),\n )\n .join('ide_completions', join => {\n join\n .on('ide_completions.day', '=', 'cm.day')\n .andOn('ide_completions.type', '=', 'cm.type')\n .andOn(\n 'ide_completions.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .join('ide_chats', join => {\n join\n .on('ide_chats.day', '=', 'cm.day')\n .andOn('ide_chats.type', '=', 'cm.type')\n .andOn(\n 'ide_chats.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .join(\n this.db.raw(\n `(SELECT day, type, team_name,\n SUM(total_code_suggestions) as total_code_suggestions, \n SUM(total_code_acceptances) as total_code_acceptances, \n SUM(total_code_lines_suggested) as total_code_lines_suggested, \n SUM(total_code_lines_accepted) as total_code_lines_accepted \n FROM ide_completions_language_editors_model_language GROUP BY day, type, team_name) \n as icelm`,\n ),\n join => {\n join\n .on('icelm.day', '=', 'cm.day')\n .andOn('icelm.type', '=', 'cm.type')\n .andOn('icelm.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .join(\n this.db.raw(\n `(SELECT day, type, team_name, SUM(total_chats) as total_chats, \n SUM(total_chat_copy_events) as total_chat_copy_events \n FROM ide_chat_editors_model GROUP BY day, type, team_name) as icem`,\n ),\n join => {\n join\n .on('icem.day', '=', 'cm.day')\n .andOn('icem.type', '=', 'cm.type')\n .andOn('icem.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .where('cm.type', type)\n .where('cm.team_name', teamName ?? '')\n .whereBetween('cm.day', [startDate, endDate])\n .groupBy('cm.day', 'cm.type', 'cm.team_name')\n .orderBy('cm.day', 'asc');\n\n return await query;\n }\n\n async getBreakdown(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<Breakdown[]> {\n const query = this.db<Breakdown>('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'icleml.editor as editor',\n 'icleml.language as language',\n this.db.raw(\n 'CAST(SUM(icleml.total_engaged_users) AS INTEGER) as active_users',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_lines_suggested) AS INTEGER) as lines_suggested',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_lines_accepted) AS INTEGER) as lines_accepted',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_suggestions) AS INTEGER) as suggestions_count',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_acceptances) AS INTEGER) as acceptances_count',\n ),\n )\n .join(\n 'ide_completions_language_editors_model_language as icleml',\n join => {\n join\n .on('icleml.day', '=', 'cm.day')\n .andOn('icleml.type', '=', 'cm.type')\n .andOn('icleml.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .whereBetween('cm.day', [startDate, endDate])\n .where('icleml.model', 'default')\n .where('cm.type', type)\n .where('cm.team_name', teamName ?? '')\n .groupBy('cm.day', 'icleml.editor', 'icleml.language')\n .orderBy('cm.day', 'asc');\n\n return await query;\n }\n}\n"],"names":["resolvePackagePath"],"mappings":"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"}
1
+ {"version":3,"file":"DatabaseHandler.cjs.js","sources":["../../src/db/DatabaseHandler.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n resolvePackagePath,\n DatabaseService,\n} from '@backstage/backend-plugin-api';\nimport {\n Metric,\n MetricsType,\n PeriodRange,\n CopilotIdeCodeCompletions,\n CopilotIdeLanguages,\n CopilotMetrics,\n CopilotEditors,\n CopilotModels,\n CopilotLanguages,\n CopilotChats,\n CopilotChatEditors,\n CopilotChatModels,\n EngagementMetrics,\n SeatAnalysis,\n} from '@backstage-community/plugin-copilot-common';\nimport { Knex } from 'knex';\n\nexport const migrationsDir = resolvePackagePath(\n '@backstage-community/plugin-copilot-backend',\n 'migrations',\n);\n\ntype Options = {\n database: DatabaseService;\n};\n\nexport type Breakdown = {\n day: string;\n editor: string;\n language: string;\n lines_accepted: number;\n lines_suggested: number;\n suggestions_count: number;\n acceptances_count: number;\n active_users: number;\n};\n\nexport type CopilotMetricsDb = Omit<\n CopilotMetrics,\n | 'date'\n | 'copilot_ide_code_completions'\n | 'copilot_ide_chat'\n | 'copilot_dotcom_chat'\n | 'copilot_dotcom_pull_requests'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n};\n\nexport type CopilotIdeCodeCompletionsDb = Omit<\n CopilotIdeCodeCompletions,\n 'editors' | 'languages'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n};\n\nexport type CopilotIdeCodeCompletionsLanguageDb = Omit<\n CopilotIdeLanguages,\n 'day' | 'name' | 'language'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n language: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorsDb = Omit<\n CopilotEditors,\n 'day' | 'name' | 'models'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n};\n\nexport type CopilotIdeChatsDb = Omit<CopilotChats, 'day' | 'editors'> & {\n day: string;\n};\n\nexport type CopilotIdeChatsEditorsDb = Omit<\n CopilotChatEditors,\n 'day' | 'name' | 'models' | 'editor'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n};\n\nexport type CopilotIdeChatsEditorModelDb = Omit<\n CopilotChatModels,\n 'name' | 'day' | 'model' | 'editor'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorModelsDb = Omit<\n CopilotModels,\n 'day' | 'editor' | 'model' | 'name' | 'languages'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n};\n\nexport type CopilotIdeCodeCompletionsEditorModelLanguagesDb = Omit<\n CopilotLanguages,\n 'day' | 'editor' | 'model' | 'name' | 'language'\n> & {\n day: string;\n /**\n * The type of the metrics data.\n * Can be 'enterprise', 'organization'.\n */\n type: MetricsType;\n\n /**\n * The name of the team, applicable when the metric is for a specific team.\n * When null, it indicates metrics for all teams, aggregated at the 'enterprise' or 'organization' level.\n */\n team_name?: string;\n editor: string;\n model: string;\n language: string;\n};\n\nexport type MetricDbRow = Omit<Metric, 'breakdown'> & {\n breakdown: string;\n};\n\nexport class DatabaseHandler {\n static async create(options: Options): Promise<DatabaseHandler> {\n const { database } = options;\n const client = await database.getClient();\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new DatabaseHandler(client);\n }\n\n private constructor(private readonly db: Knex) {}\n\n async getPeriodRange(type: MetricsType): Promise<PeriodRange | undefined> {\n const query = this.db<MetricDbRow>('metrics').where('type', type);\n\n const minDate = await query.orderBy('day', 'asc').first('day');\n const maxDate = await query.orderBy('day', 'desc').first('day');\n\n if (!minDate?.day || !maxDate?.day) return undefined;\n\n return { minDate: minDate.day, maxDate: maxDate.day };\n }\n\n async getPeriodRangeV2(type: MetricsType): Promise<PeriodRange | undefined> {\n const query = this.db('copilot_metrics').where('type', type);\n\n const minDate = await query.orderBy('day', 'asc').first('day');\n const maxDate = await query.orderBy('day', 'desc').first('day');\n\n if (!minDate?.day || !maxDate?.day) return undefined;\n\n return { minDate: minDate.day, maxDate: maxDate.day };\n }\n\n async getTeams(\n type: MetricsType,\n startDate: string,\n endDate: string,\n ): Promise<Array<string | undefined>> {\n const result = await this.db<MetricDbRow>('copilot_metrics')\n .where('type', type)\n .whereBetween('day', [startDate, endDate])\n .whereNot('team_name', '')\n .distinct('team_name')\n .orderBy('team_name', 'asc')\n .select('team_name');\n\n return result.map(x => x.team_name);\n }\n\n async batchInsert(metrics: MetricDbRow[]): Promise<void> {\n await this.db<MetricDbRow[]>('metrics')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertMetrics(metrics: CopilotMetricsDb[]): Promise<void> {\n await this.db<CopilotMetricsDb[]>('copilot_metrics')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeCompletions(\n metrics: CopilotIdeCodeCompletionsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsDb[]>('ide_completions')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsLanguages(\n metrics: CopilotIdeCodeCompletionsLanguageDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsLanguageDb[]>(\n 'ide_completions_language_users',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'language'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditors(\n metrics: CopilotIdeCodeCompletionsEditorsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorsDb[]>(\n 'ide_completions_language_editors',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditorModels(\n metrics: CopilotIdeCodeCompletionsEditorModelsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorModelsDb[]>(\n 'ide_completions_language_editors_model',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model'])\n .ignore();\n }\n\n async batchInsertIdeCompletionsEditorModelLanguages(\n metrics: CopilotIdeCodeCompletionsEditorModelLanguagesDb[],\n ): Promise<void> {\n await this.db<CopilotIdeCodeCompletionsEditorModelLanguagesDb[]>(\n 'ide_completions_language_editors_model_language',\n )\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model', 'language'])\n .ignore();\n }\n\n async batchInsertIdeChats(metrics: CopilotIdeChatsDb[]): Promise<void> {\n await this.db<CopilotIdeChatsDb[]>('ide_chats')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async batchInsertIdeChatEditors(\n metrics: CopilotIdeChatsEditorsDb[],\n ): Promise<void> {\n await this.db<CopilotIdeChatsEditorsDb[]>('ide_chat_editors')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor'])\n .ignore();\n }\n\n async batchInsertIdeChatEditorModels(\n metrics: CopilotIdeChatsEditorModelDb[],\n ): Promise<void> {\n await this.db<CopilotIdeChatsEditorModelDb[]>('ide_chat_editors_model')\n .insert(metrics)\n .onConflict(['day', 'type', 'team_name', 'editor', 'model'])\n .ignore();\n }\n\n async insertSeatAnalysys(metric: SeatAnalysis): Promise<void> {\n await this.db<SeatAnalysis>('seats')\n .insert(metric)\n .onConflict(['day', 'type', 'team_name'])\n .ignore();\n }\n\n async getMostRecentDayFromMetrics(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'desc')\n .first('day');\n return query ? query.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getMostRecentDayFromMetricsV2(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = this.db('copilot_metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'desc')\n .first('day');\n const res = await query;\n return res ? res.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getEarliestDayFromMetricsV2(\n type: MetricsType,\n teamName?: string,\n ): Promise<string | undefined> {\n try {\n const query = this.db('copilot_metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .orderBy('day', 'asc')\n .first('day');\n const res = await query;\n return res ? res.day : undefined;\n } catch (e) {\n return undefined;\n }\n }\n\n async getMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<MetricDbRow[]> {\n return await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .whereBetween('day', [startDate, endDate]);\n }\n\n async getSeatMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<SeatAnalysis[]> {\n return await this.db<SeatAnalysis>('seats')\n .where('type', type)\n .where('team_name', teamName ?? '')\n .whereBetween('day', [startDate, endDate])\n .orderBy('day', 'asc');\n }\n\n async getEngagementMetrics(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<EngagementMetrics[]> {\n const query = this.db('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'cm.type',\n 'cm.team_name',\n this.db.raw(\n 'CAST(MIN(cm.total_active_users) AS INTEGER) as total_active_users',\n ),\n this.db.raw(\n 'CAST(MIN(cm.total_engaged_users) AS INTEGER) as total_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_completions.total_engaged_users) AS INTEGER) as ide_completions_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_chats.total_engaged_users) AS INTEGER) as ide_chats_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(dotcom_chats.total_engaged_users) AS INTEGER) as dotcom_chats_engaged_users',\n ),\n this.db.raw(\n 'CAST(MIN(dotcom_prs.total_engaged_users) AS INTEGER) as dotcom_prs_engaged_users',\n ),\n )\n .leftJoin('ide_completions', join => {\n join\n .on('ide_completions.day', '=', 'cm.day')\n .andOn('ide_completions.type', '=', 'cm.type')\n .andOn(\n 'ide_completions.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .leftJoin('ide_chats', join => {\n join\n .on('ide_chats.day', '=', 'cm.day')\n .andOn('ide_chats.type', '=', 'cm.type')\n .andOn(\n 'ide_chats.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .leftJoin('dotcom_chats', join => {\n join\n .on('dotcom_chats.day', '=', 'cm.day')\n .andOn('dotcom_chats.type', '=', 'cm.type')\n .andOn(\n 'dotcom_chats.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .leftJoin('dotcom_prs', join => {\n join\n .on('dotcom_prs.day', '=', 'cm.day')\n .andOn('dotcom_prs.type', '=', 'cm.type')\n .andOn(\n 'dotcom_prs.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .where('cm.type', type)\n .where('cm.team_name', teamName ?? '')\n .whereBetween('cm.day', [startDate, endDate])\n .groupBy('cm.day', 'cm.type', 'cm.team_name')\n .orderBy('cm.day', 'asc');\n\n return await query;\n }\n\n async getMetricsV2(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<MetricDbRow[]> {\n const query = this.db('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'cm.type',\n 'cm.team_name',\n this.db.raw(\n 'CAST(MIN(cm.total_active_users) AS INTEGER) as total_active_users',\n ),\n this.db.raw(\n 'CAST(MIN(ide_chats.total_engaged_users) AS INTEGER) as total_active_chat_users',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_suggestions) AS INTEGER) as total_suggestions_count',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_acceptances) AS INTEGER) as total_acceptances_count',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_lines_suggested) AS INTEGER) as total_lines_suggested',\n ),\n this.db.raw(\n 'CAST(SUM(icelm.total_code_lines_accepted) AS INTEGER) as total_lines_accepted',\n ),\n this.db.raw(\n 'CAST(SUM(icem.total_chats) AS INTEGER) as total_chat_turns',\n ),\n this.db.raw(\n 'CAST(SUM(icem.total_chat_copy_events) AS INTEGER) as total_chat_acceptances',\n ),\n this.db.raw(\"'' as breakdown\"),\n )\n .join('ide_completions', join => {\n join\n .on('ide_completions.day', '=', 'cm.day')\n .andOn('ide_completions.type', '=', 'cm.type')\n .andOn(\n 'ide_completions.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .join('ide_chats', join => {\n join\n .on('ide_chats.day', '=', 'cm.day')\n .andOn('ide_chats.type', '=', 'cm.type')\n .andOn(\n 'ide_chats.team_name',\n '=',\n this.db.raw('?', [teamName ?? '']),\n );\n })\n .join(\n this.db.raw(\n `(SELECT day, type, team_name,\n SUM(total_code_suggestions) as total_code_suggestions, \n SUM(total_code_acceptances) as total_code_acceptances, \n SUM(total_code_lines_suggested) as total_code_lines_suggested, \n SUM(total_code_lines_accepted) as total_code_lines_accepted \n FROM ide_completions_language_editors_model_language GROUP BY day, type, team_name) \n as icelm`,\n ),\n join => {\n join\n .on('icelm.day', '=', 'cm.day')\n .andOn('icelm.type', '=', 'cm.type')\n .andOn('icelm.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .join(\n this.db.raw(\n `(SELECT day, type, team_name, SUM(total_chats) as total_chats, \n SUM(total_chat_copy_events) as total_chat_copy_events \n FROM ide_chat_editors_model GROUP BY day, type, team_name) as icem`,\n ),\n join => {\n join\n .on('icem.day', '=', 'cm.day')\n .andOn('icem.type', '=', 'cm.type')\n .andOn('icem.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .where('cm.type', type)\n .where('cm.team_name', teamName ?? '')\n .whereBetween('cm.day', [startDate, endDate])\n .groupBy('cm.day', 'cm.type', 'cm.team_name')\n .orderBy('cm.day', 'asc');\n\n return await query;\n }\n\n async getBreakdown(\n startDate: string,\n endDate: string,\n type: MetricsType,\n teamName?: string,\n ): Promise<Breakdown[]> {\n const query = this.db<Breakdown>('copilot_metrics as cm')\n .select(\n 'cm.day',\n 'icleml.editor as editor',\n 'icleml.language as language',\n this.db.raw(\n 'CAST(SUM(icleml.total_engaged_users) AS INTEGER) as active_users',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_lines_suggested) AS INTEGER) as lines_suggested',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_lines_accepted) AS INTEGER) as lines_accepted',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_suggestions) AS INTEGER) as suggestions_count',\n ),\n this.db.raw(\n 'CAST(SUM(icleml.total_code_acceptances) AS INTEGER) as acceptances_count',\n ),\n )\n .join(\n 'ide_completions_language_editors_model_language as icleml',\n join => {\n join\n .on('icleml.day', '=', 'cm.day')\n .andOn('icleml.type', '=', 'cm.type')\n .andOn('icleml.team_name', '=', this.db.raw('?', [teamName ?? '']));\n },\n )\n .whereBetween('cm.day', [startDate, endDate])\n .where('icleml.model', 'default')\n .where('cm.type', type)\n .where('cm.team_name', teamName ?? '')\n .groupBy('cm.day', 'icleml.editor', 'icleml.language')\n .orderBy('cm.day', 'asc');\n\n return await query;\n }\n}\n"],"names":["resolvePackagePath"],"mappings":"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"}
@@ -10,7 +10,7 @@ const getCopilotConfig = (config) => {
10
10
  const githubConfig = integrations.github.byHost(host)?.config;
11
11
  if (!githubConfig) {
12
12
  throw new Error(
13
- `GitHub configuration for host "${host}" is missing or incomplete. Please check the integretions configuration section.`
13
+ `GitHub configuration for host "${host}" is missing or incomplete. Please check the integrations configuration section.`
14
14
  );
15
15
  }
16
16
  if (enterprise && !githubConfig.token) {
@@ -1 +1 @@
1
- {"version":3,"file":"GithubUtils.cjs.js","sources":["../../src/utils/GithubUtils.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentials,\n ScmIntegrations,\n} from '@backstage/integration';\n\nexport type CopilotCredentials = {\n enterprise?: GithubCredentials;\n organization?: GithubCredentials;\n};\n\nexport type CopilotConfig = {\n host: string;\n enterprise?: string;\n organization?: string;\n apiBaseUrl: string;\n};\n\nexport const getCopilotConfig = (config: Config): CopilotConfig => {\n const host = config.getString('copilot.host');\n const enterprise = config.getOptionalString('copilot.enterprise');\n const organization = config.getOptionalString('copilot.organization');\n\n const integrations = ScmIntegrations.fromConfig(config);\n\n const githubConfig = integrations.github.byHost(host)?.config;\n\n if (!githubConfig) {\n throw new Error(\n `GitHub configuration for host \"${host}\" is missing or incomplete. Please check the integretions configuration section.`,\n );\n }\n\n if (enterprise && !githubConfig.token) {\n throw new Error(\n `Enterprise API for copilot only works with \"classic PAT\" tokens. No token is configured for \"${host}\" in the config.`,\n );\n }\n\n if (organization && !(githubConfig.token || githubConfig.apps)) {\n throw new Error(\n `Organization API for copilot works with both classic and fine grained PAT tokens or GitHub apps. No token or app is configured for \"${host}\" in the config.`,\n );\n }\n\n return {\n host,\n enterprise,\n organization,\n apiBaseUrl: githubConfig.apiBaseUrl ?? 'https://api.github.com',\n };\n};\n\nexport const getGithubCredentials = async (\n config: Config,\n copilotConfig: CopilotConfig,\n): Promise<CopilotCredentials> => {\n const integrations = ScmIntegrations.fromConfig(config);\n const { host, enterprise, organization } = copilotConfig;\n\n const githubConfig = integrations.github.byHost(host)?.config;\n\n if (!githubConfig) {\n throw new Error(\n `GitHub configuration for host \"${host}\" is missing or incomplete.`,\n );\n }\n\n const credentials: CopilotCredentials = {\n enterprise: undefined,\n organization: undefined,\n };\n\n if (enterprise) {\n if (!githubConfig.token) {\n throw new Error(\n `Enterprise API for copilot only works with \"classic PAT\" tokens. No token is configured for \"${host}\" in the config.`,\n );\n } else {\n credentials.enterprise = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n }\n }\n\n if (organization) {\n if (githubConfig.apps) {\n const githubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n credentials.organization = await githubCredentialsProvider.getCredentials(\n {\n url: `https://${host}/${organization}`,\n },\n );\n } else if (githubConfig.token) {\n credentials.organization = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n } else {\n throw new Error(\n `Organization API for copilot works with both classic and fine grained PAT tokens or GitHub apps. No token or app is configured for \"${host}\" in the config.`,\n );\n }\n }\n\n return credentials;\n};\n"],"names":["ScmIntegrations","DefaultGithubCredentialsProvider"],"mappings":"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"}
1
+ {"version":3,"file":"GithubUtils.cjs.js","sources":["../../src/utils/GithubUtils.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentials,\n ScmIntegrations,\n} from '@backstage/integration';\n\nexport type CopilotCredentials = {\n enterprise?: GithubCredentials;\n organization?: GithubCredentials;\n};\n\nexport type CopilotConfig = {\n host: string;\n enterprise?: string;\n organization?: string;\n apiBaseUrl: string;\n};\n\nexport const getCopilotConfig = (config: Config): CopilotConfig => {\n const host = config.getString('copilot.host');\n const enterprise = config.getOptionalString('copilot.enterprise');\n const organization = config.getOptionalString('copilot.organization');\n\n const integrations = ScmIntegrations.fromConfig(config);\n\n const githubConfig = integrations.github.byHost(host)?.config;\n\n if (!githubConfig) {\n throw new Error(\n `GitHub configuration for host \"${host}\" is missing or incomplete. Please check the integrations configuration section.`,\n );\n }\n\n if (enterprise && !githubConfig.token) {\n throw new Error(\n `Enterprise API for copilot only works with \"classic PAT\" tokens. No token is configured for \"${host}\" in the config.`,\n );\n }\n\n if (organization && !(githubConfig.token || githubConfig.apps)) {\n throw new Error(\n `Organization API for copilot works with both classic and fine grained PAT tokens or GitHub apps. No token or app is configured for \"${host}\" in the config.`,\n );\n }\n\n return {\n host,\n enterprise,\n organization,\n apiBaseUrl: githubConfig.apiBaseUrl ?? 'https://api.github.com',\n };\n};\n\nexport const getGithubCredentials = async (\n config: Config,\n copilotConfig: CopilotConfig,\n): Promise<CopilotCredentials> => {\n const integrations = ScmIntegrations.fromConfig(config);\n const { host, enterprise, organization } = copilotConfig;\n\n const githubConfig = integrations.github.byHost(host)?.config;\n\n if (!githubConfig) {\n throw new Error(\n `GitHub configuration for host \"${host}\" is missing or incomplete.`,\n );\n }\n\n const credentials: CopilotCredentials = {\n enterprise: undefined,\n organization: undefined,\n };\n\n if (enterprise) {\n if (!githubConfig.token) {\n throw new Error(\n `Enterprise API for copilot only works with \"classic PAT\" tokens. No token is configured for \"${host}\" in the config.`,\n );\n } else {\n credentials.enterprise = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n }\n }\n\n if (organization) {\n if (githubConfig.apps) {\n const githubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n credentials.organization = await githubCredentialsProvider.getCredentials(\n {\n url: `https://${host}/${organization}`,\n },\n );\n } else if (githubConfig.token) {\n credentials.organization = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n } else {\n throw new Error(\n `Organization API for copilot works with both classic and fine grained PAT tokens or GitHub apps. No token or app is configured for \"${host}\" in the config.`,\n );\n }\n }\n\n return credentials;\n};\n"],"names":["ScmIntegrations","DefaultGithubCredentialsProvider"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-copilot-backend",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "homepage": "https://backstage.io",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.cjs.js",