@backstage-community/plugin-copilot-backend 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @backstage-community/plugin-copilot-backend
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 53e7191: Backstage version bump to v1.34.2
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [53e7191]
12
+ - @backstage-community/plugin-copilot-common@0.4.0
13
+
3
14
  ## 0.2.0
4
15
 
5
16
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"GithubClient.cjs.js","sources":["../../src/client/GithubClient.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 { ResponseError } from '@backstage/errors';\nimport { Config } from '@backstage/config';\nimport { Metric, TeamInfo } from '@backstage-community/plugin-copilot-common';\nimport fetch from 'node-fetch';\nimport { getGithubInfo, GithubInfo } from '../utils/GithubUtils';\n\ninterface GithubApi {\n fetchEnterpriseCopilotUsage: () => Promise<Metric[]>;\n fetchEnterpriseTeamCopilotUsage: (teamId: string) => Promise<Metric[]>;\n fetchEnterpriseTeams: () => Promise<TeamInfo[]>;\n fetchOrganizationCopilotUsage: () => Promise<Metric[]>;\n fetchOrganizationTeamCopilotUsage: (teamId: string) => Promise<Metric[]>;\n fetchOrganizationTeams: () => Promise<TeamInfo[]>;\n}\n\nexport class GithubClient implements GithubApi {\n constructor(private readonly props: GithubInfo) {}\n\n static async fromConfig(config: Config) {\n const info = await getGithubInfo(config);\n return new GithubClient(info);\n }\n\n async fetchEnterpriseCopilotUsage(): Promise<Metric[]> {\n const path = `/enterprises/${this.props.enterprise}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchEnterpriseTeamCopilotUsage(teamId: string): Promise<Metric[]> {\n const path = `/enterprises/${this.props.enterprise}/team/${teamId}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchEnterpriseTeams(): Promise<TeamInfo[]> {\n const path = `/enterprises/${this.props.enterprise}/teams`;\n return this.get(path);\n }\n\n async fetchOrganizationCopilotUsage(): Promise<Metric[]> {\n const path = `/orgs/${this.props.organization}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchOrganizationTeamCopilotUsage(teamId: string): Promise<Metric[]> {\n const path = `/orgs/${this.props.organization}/team/${teamId}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchOrganizationTeams(): Promise<TeamInfo[]> {\n const path = `/orgs/${this.props.organization}/teams`;\n return this.get(path);\n }\n\n private async get<T>(path: string): Promise<T> {\n const response = await fetch(`${this.props.apiBaseUrl}${path}`, {\n headers: {\n ...this.props.credentials.headers,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n"],"names":["getGithubInfo","fetch","ResponseError"],"mappings":";;;;;;;;;;AA+BO,MAAM,YAAkC,CAAA;AAAA,EAC7C,YAA6B,KAAmB,EAAA;AAAnB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA,CAAA;AAAA,GAAoB;AAAA,EAEjD,aAAa,WAAW,MAAgB,EAAA;AACtC,IAAM,MAAA,IAAA,GAAO,MAAMA,yBAAA,CAAc,MAAM,CAAA,CAAA;AACvC,IAAO,OAAA,IAAI,aAAa,IAAI,CAAA,CAAA;AAAA,GAC9B;AAAA,EAEA,MAAM,2BAAiD,GAAA;AACrD,IAAA,MAAM,IAAO,GAAA,CAAA,aAAA,EAAgB,IAAK,CAAA,KAAA,CAAM,UAAU,CAAA,cAAA,CAAA,CAAA;AAClD,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAM,gCAAgC,MAAmC,EAAA;AACvE,IAAA,MAAM,OAAO,CAAgB,aAAA,EAAA,IAAA,CAAK,KAAM,CAAA,UAAU,SAAS,MAAM,CAAA,cAAA,CAAA,CAAA;AACjE,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAM,oBAA4C,GAAA;AAChD,IAAA,MAAM,IAAO,GAAA,CAAA,aAAA,EAAgB,IAAK,CAAA,KAAA,CAAM,UAAU,CAAA,MAAA,CAAA,CAAA;AAClD,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAM,6BAAmD,GAAA;AACvD,IAAA,MAAM,IAAO,GAAA,CAAA,MAAA,EAAS,IAAK,CAAA,KAAA,CAAM,YAAY,CAAA,cAAA,CAAA,CAAA;AAC7C,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAM,kCAAkC,MAAmC,EAAA;AACzE,IAAA,MAAM,OAAO,CAAS,MAAA,EAAA,IAAA,CAAK,KAAM,CAAA,YAAY,SAAS,MAAM,CAAA,cAAA,CAAA,CAAA;AAC5D,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAM,sBAA8C,GAAA;AAClD,IAAA,MAAM,IAAO,GAAA,CAAA,MAAA,EAAS,IAAK,CAAA,KAAA,CAAM,YAAY,CAAA,MAAA,CAAA,CAAA;AAC7C,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA,CAAA;AAAA,GACtB;AAAA,EAEA,MAAc,IAAO,IAA0B,EAAA;AAC7C,IAAM,MAAA,QAAA,GAAW,MAAMC,sBAAM,CAAA,CAAA,EAAG,KAAK,KAAM,CAAA,UAAU,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA;AAAA,MAC9D,OAAS,EAAA;AAAA,QACP,GAAG,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,OAAA;AAAA,QAC1B,MAAQ,EAAA,6BAAA;AAAA,QACR,sBAAwB,EAAA,YAAA;AAAA,OAC1B;AAAA,KACD,CAAA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAMC,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAA,OAAO,SAAS,IAAK,EAAA,CAAA;AAAA,GACvB;AACF;;;;"}
1
+ {"version":3,"file":"GithubClient.cjs.js","sources":["../../src/client/GithubClient.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 { ResponseError } from '@backstage/errors';\nimport { Config } from '@backstage/config';\nimport { Metric, TeamInfo } from '@backstage-community/plugin-copilot-common';\nimport fetch from 'node-fetch';\nimport { getGithubInfo, GithubInfo } from '../utils/GithubUtils';\n\ninterface GithubApi {\n fetchEnterpriseCopilotUsage: () => Promise<Metric[]>;\n fetchEnterpriseTeamCopilotUsage: (teamId: string) => Promise<Metric[]>;\n fetchEnterpriseTeams: () => Promise<TeamInfo[]>;\n fetchOrganizationCopilotUsage: () => Promise<Metric[]>;\n fetchOrganizationTeamCopilotUsage: (teamId: string) => Promise<Metric[]>;\n fetchOrganizationTeams: () => Promise<TeamInfo[]>;\n}\n\nexport class GithubClient implements GithubApi {\n constructor(private readonly props: GithubInfo) {}\n\n static async fromConfig(config: Config) {\n const info = await getGithubInfo(config);\n return new GithubClient(info);\n }\n\n async fetchEnterpriseCopilotUsage(): Promise<Metric[]> {\n const path = `/enterprises/${this.props.enterprise}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchEnterpriseTeamCopilotUsage(teamId: string): Promise<Metric[]> {\n const path = `/enterprises/${this.props.enterprise}/team/${teamId}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchEnterpriseTeams(): Promise<TeamInfo[]> {\n const path = `/enterprises/${this.props.enterprise}/teams`;\n return this.get(path);\n }\n\n async fetchOrganizationCopilotUsage(): Promise<Metric[]> {\n const path = `/orgs/${this.props.organization}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchOrganizationTeamCopilotUsage(teamId: string): Promise<Metric[]> {\n const path = `/orgs/${this.props.organization}/team/${teamId}/copilot/usage`;\n return this.get(path);\n }\n\n async fetchOrganizationTeams(): Promise<TeamInfo[]> {\n const path = `/orgs/${this.props.organization}/teams`;\n return this.get(path);\n }\n\n private async get<T>(path: string): Promise<T> {\n const response = await fetch(`${this.props.apiBaseUrl}${path}`, {\n headers: {\n ...this.props.credentials.headers,\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n"],"names":["getGithubInfo","fetch","ResponseError"],"mappings":";;;;;;;;;;AA+BO,MAAM,YAAkC,CAAA;AAAA,EAC7C,YAA6B,KAAmB,EAAA;AAAnB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA;AAAoB,EAEjD,aAAa,WAAW,MAAgB,EAAA;AACtC,IAAM,MAAA,IAAA,GAAO,MAAMA,yBAAA,CAAc,MAAM,CAAA;AACvC,IAAO,OAAA,IAAI,aAAa,IAAI,CAAA;AAAA;AAC9B,EAEA,MAAM,2BAAiD,GAAA;AACrD,IAAA,MAAM,IAAO,GAAA,CAAA,aAAA,EAAgB,IAAK,CAAA,KAAA,CAAM,UAAU,CAAA,cAAA,CAAA;AAClD,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAM,gCAAgC,MAAmC,EAAA;AACvE,IAAA,MAAM,OAAO,CAAgB,aAAA,EAAA,IAAA,CAAK,KAAM,CAAA,UAAU,SAAS,MAAM,CAAA,cAAA,CAAA;AACjE,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAM,oBAA4C,GAAA;AAChD,IAAA,MAAM,IAAO,GAAA,CAAA,aAAA,EAAgB,IAAK,CAAA,KAAA,CAAM,UAAU,CAAA,MAAA,CAAA;AAClD,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAM,6BAAmD,GAAA;AACvD,IAAA,MAAM,IAAO,GAAA,CAAA,MAAA,EAAS,IAAK,CAAA,KAAA,CAAM,YAAY,CAAA,cAAA,CAAA;AAC7C,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAM,kCAAkC,MAAmC,EAAA;AACzE,IAAA,MAAM,OAAO,CAAS,MAAA,EAAA,IAAA,CAAK,KAAM,CAAA,YAAY,SAAS,MAAM,CAAA,cAAA,CAAA;AAC5D,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAM,sBAA8C,GAAA;AAClD,IAAA,MAAM,IAAO,GAAA,CAAA,MAAA,EAAS,IAAK,CAAA,KAAA,CAAM,YAAY,CAAA,MAAA,CAAA;AAC7C,IAAO,OAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA;AACtB,EAEA,MAAc,IAAO,IAA0B,EAAA;AAC7C,IAAM,MAAA,QAAA,GAAW,MAAMC,sBAAM,CAAA,CAAA,EAAG,KAAK,KAAM,CAAA,UAAU,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA;AAAA,MAC9D,OAAS,EAAA;AAAA,QACP,GAAG,IAAK,CAAA,KAAA,CAAM,WAAY,CAAA,OAAA;AAAA,QAC1B,MAAQ,EAAA,6BAAA;AAAA,QACR,sBAAwB,EAAA;AAAA;AAC1B,KACD,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAMC,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,OAAO,SAAS,IAAK,EAAA;AAAA;AAEzB;;;;"}
@@ -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} from '@backstage-community/plugin-copilot-common';\nimport { Knex } from 'knex';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage-community/plugin-copilot-backend',\n 'migrations',\n);\n\ntype Options = {\n database: DatabaseService;\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 getTeams(\n type: MetricsType,\n startDate: string,\n endDate: string,\n ): Promise<Array<string | undefined>> {\n const result = await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .whereBetween('day', [startDate, endDate])\n .whereNotNull('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 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 ?? null)\n .orderBy('day', 'desc')\n .first('day');\n return query ? query.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 console.log(startDate, endDate, type, teamName);\n if (teamName) {\n return await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName)\n .whereBetween('day', [startDate, endDate]);\n }\n return this.db<MetricDbRow>('metrics')\n .where('type', type)\n .whereNull('team_name')\n .whereBetween('day', [startDate, endDate]);\n }\n}\n"],"names":["resolvePackagePath"],"mappings":";;;;AA2BA,MAAM,aAAgB,GAAAA,mCAAA;AAAA,EACpB,6CAAA;AAAA,EACA,YAAA;AACF,CAAA,CAAA;AAUO,MAAM,eAAgB,CAAA;AAAA,EAcnB,YAA6B,EAAU,EAAA;AAAV,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA,CAAA;AAAA,GAAW;AAAA,EAbhD,aAAa,OAAO,OAA4C,EAAA;AAC9D,IAAM,MAAA,EAAE,UAAa,GAAA,OAAA,CAAA;AACrB,IAAM,MAAA,MAAA,GAAS,MAAM,QAAA,CAAS,SAAU,EAAA,CAAA;AAExC,IAAI,IAAA,CAAC,QAAS,CAAA,UAAA,EAAY,IAAM,EAAA;AAC9B,MAAM,MAAA,MAAA,CAAO,QAAQ,MAAO,CAAA;AAAA,QAC1B,SAAW,EAAA,aAAA;AAAA,OACZ,CAAA,CAAA;AAAA,KACH;AAEA,IAAO,OAAA,IAAI,gBAAgB,MAAM,CAAA,CAAA;AAAA,GACnC;AAAA,EAIA,MAAM,eAAe,IAAqD,EAAA;AACxE,IAAA,MAAM,QAAQ,IAAK,CAAA,EAAA,CAAgB,SAAS,CAAE,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAAA;AAEhE,IAAM,MAAA,OAAA,GAAU,MAAM,KAAM,CAAA,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAE,MAAM,KAAK,CAAA,CAAA;AAC7D,IAAM,MAAA,OAAA,GAAU,MAAM,KAAM,CAAA,OAAA,CAAQ,OAAO,MAAM,CAAA,CAAE,MAAM,KAAK,CAAA,CAAA;AAE9D,IAAA,IAAI,CAAC,OAAS,EAAA,GAAA,IAAO,CAAC,OAAA,EAAS,KAAY,OAAA,KAAA,CAAA,CAAA;AAE3C,IAAA,OAAO,EAAE,OAAS,EAAA,OAAA,CAAQ,GAAK,EAAA,OAAA,EAAS,QAAQ,GAAI,EAAA,CAAA;AAAA,GACtD;AAAA,EAEA,MAAM,QAAA,CACJ,IACA,EAAA,SAAA,EACA,OACoC,EAAA;AACpC,IAAA,MAAM,MAAS,GAAA,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CAAA,CAChD,KAAM,CAAA,MAAA,EAAQ,IAAI,CAAA,CAClB,YAAa,CAAA,KAAA,EAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CACxC,CAAA,YAAA,CAAa,WAAW,CAAA,CACxB,QAAS,CAAA,WAAW,CACpB,CAAA,OAAA,CAAQ,WAAa,EAAA,KAAK,CAC1B,CAAA,MAAA,CAAO,WAAW,CAAA,CAAA;AAErB,IAAA,OAAO,MAAO,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,CAAA,CAAA;AAAA,GACpC;AAAA,EAEA,MAAM,YAAY,OAAuC,EAAA;AACvD,IAAA,MAAM,IAAK,CAAA,EAAA,CAAkB,SAAS,CAAA,CACnC,OAAO,OAAO,CAAA,CACd,UAAW,CAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,WAAW,CAAC,EACvC,MAAO,EAAA,CAAA;AAAA,GACZ;AAAA,EAEA,MAAM,2BACJ,CAAA,IAAA,EACA,QAC6B,EAAA;AAC7B,IAAI,IAAA;AACF,MAAM,MAAA,KAAA,GAAQ,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CAC/C,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,MAAM,WAAa,EAAA,QAAA,IAAY,IAAI,CACnC,CAAA,OAAA,CAAQ,OAAO,MAAM,CAAA,CACrB,MAAM,KAAK,CAAA,CAAA;AACd,MAAO,OAAA,KAAA,GAAQ,MAAM,GAAM,GAAA,KAAA,CAAA,CAAA;AAAA,aACpB,CAAG,EAAA;AACV,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,GACF;AAAA,EAEA,MAAM,UAAA,CACJ,SACA,EAAA,OAAA,EACA,MACA,QACwB,EAAA;AACxB,IAAA,OAAA,CAAQ,GAAI,CAAA,SAAA,EAAW,OAAS,EAAA,IAAA,EAAM,QAAQ,CAAA,CAAA;AAC9C,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,OAAO,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CACxC,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,KAAM,CAAA,WAAA,EAAa,QAAQ,CAC3B,CAAA,YAAA,CAAa,OAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CAAA,CAAA;AAAA,KAC7C;AACA,IAAA,OAAO,KAAK,EAAgB,CAAA,SAAS,CAClC,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,SAAU,CAAA,WAAW,EACrB,YAAa,CAAA,KAAA,EAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CAAA,CAAA;AAAA,GAC7C;AACF;;;;"}
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} from '@backstage-community/plugin-copilot-common';\nimport { Knex } from 'knex';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage-community/plugin-copilot-backend',\n 'migrations',\n);\n\ntype Options = {\n database: DatabaseService;\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 getTeams(\n type: MetricsType,\n startDate: string,\n endDate: string,\n ): Promise<Array<string | undefined>> {\n const result = await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .whereBetween('day', [startDate, endDate])\n .whereNotNull('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 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 ?? null)\n .orderBy('day', 'desc')\n .first('day');\n return query ? query.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 console.log(startDate, endDate, type, teamName);\n if (teamName) {\n return await this.db<MetricDbRow>('metrics')\n .where('type', type)\n .where('team_name', teamName)\n .whereBetween('day', [startDate, endDate]);\n }\n return this.db<MetricDbRow>('metrics')\n .where('type', type)\n .whereNull('team_name')\n .whereBetween('day', [startDate, endDate]);\n }\n}\n"],"names":["resolvePackagePath"],"mappings":";;;;AA2BA,MAAM,aAAgB,GAAAA,mCAAA;AAAA,EACpB,6CAAA;AAAA,EACA;AACF,CAAA;AAUO,MAAM,eAAgB,CAAA;AAAA,EAcnB,YAA6B,EAAU,EAAA;AAAV,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AAAA;AAAW,EAbhD,aAAa,OAAO,OAA4C,EAAA;AAC9D,IAAM,MAAA,EAAE,UAAa,GAAA,OAAA;AACrB,IAAM,MAAA,MAAA,GAAS,MAAM,QAAA,CAAS,SAAU,EAAA;AAExC,IAAI,IAAA,CAAC,QAAS,CAAA,UAAA,EAAY,IAAM,EAAA;AAC9B,MAAM,MAAA,MAAA,CAAO,QAAQ,MAAO,CAAA;AAAA,QAC1B,SAAW,EAAA;AAAA,OACZ,CAAA;AAAA;AAGH,IAAO,OAAA,IAAI,gBAAgB,MAAM,CAAA;AAAA;AACnC,EAIA,MAAM,eAAe,IAAqD,EAAA;AACxE,IAAA,MAAM,QAAQ,IAAK,CAAA,EAAA,CAAgB,SAAS,CAAE,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA;AAEhE,IAAM,MAAA,OAAA,GAAU,MAAM,KAAM,CAAA,OAAA,CAAQ,OAAO,KAAK,CAAA,CAAE,MAAM,KAAK,CAAA;AAC7D,IAAM,MAAA,OAAA,GAAU,MAAM,KAAM,CAAA,OAAA,CAAQ,OAAO,MAAM,CAAA,CAAE,MAAM,KAAK,CAAA;AAE9D,IAAA,IAAI,CAAC,OAAS,EAAA,GAAA,IAAO,CAAC,OAAA,EAAS,KAAY,OAAA,KAAA,CAAA;AAE3C,IAAA,OAAO,EAAE,OAAS,EAAA,OAAA,CAAQ,GAAK,EAAA,OAAA,EAAS,QAAQ,GAAI,EAAA;AAAA;AACtD,EAEA,MAAM,QAAA,CACJ,IACA,EAAA,SAAA,EACA,OACoC,EAAA;AACpC,IAAA,MAAM,MAAS,GAAA,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CAAA,CAChD,KAAM,CAAA,MAAA,EAAQ,IAAI,CAAA,CAClB,YAAa,CAAA,KAAA,EAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CACxC,CAAA,YAAA,CAAa,WAAW,CAAA,CACxB,QAAS,CAAA,WAAW,CACpB,CAAA,OAAA,CAAQ,WAAa,EAAA,KAAK,CAC1B,CAAA,MAAA,CAAO,WAAW,CAAA;AAErB,IAAA,OAAO,MAAO,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,CAAA;AAAA;AACpC,EAEA,MAAM,YAAY,OAAuC,EAAA;AACvD,IAAA,MAAM,IAAK,CAAA,EAAA,CAAkB,SAAS,CAAA,CACnC,OAAO,OAAO,CAAA,CACd,UAAW,CAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,WAAW,CAAC,EACvC,MAAO,EAAA;AAAA;AACZ,EAEA,MAAM,2BACJ,CAAA,IAAA,EACA,QAC6B,EAAA;AAC7B,IAAI,IAAA;AACF,MAAM,MAAA,KAAA,GAAQ,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CAC/C,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,MAAM,WAAa,EAAA,QAAA,IAAY,IAAI,CACnC,CAAA,OAAA,CAAQ,OAAO,MAAM,CAAA,CACrB,MAAM,KAAK,CAAA;AACd,MAAO,OAAA,KAAA,GAAQ,MAAM,GAAM,GAAA,KAAA,CAAA;AAAA,aACpB,CAAG,EAAA;AACV,MAAO,OAAA,KAAA,CAAA;AAAA;AACT;AACF,EAEA,MAAM,UAAA,CACJ,SACA,EAAA,OAAA,EACA,MACA,QACwB,EAAA;AACxB,IAAA,OAAA,CAAQ,GAAI,CAAA,SAAA,EAAW,OAAS,EAAA,IAAA,EAAM,QAAQ,CAAA;AAC9C,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,OAAO,MAAM,IAAK,CAAA,EAAA,CAAgB,SAAS,CACxC,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,KAAM,CAAA,WAAA,EAAa,QAAQ,CAC3B,CAAA,YAAA,CAAa,OAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CAAA;AAAA;AAE7C,IAAA,OAAO,KAAK,EAAgB,CAAA,SAAS,CAClC,CAAA,KAAA,CAAM,QAAQ,IAAI,CAAA,CAClB,SAAU,CAAA,WAAW,EACrB,YAAa,CAAA,KAAA,EAAO,CAAC,SAAA,EAAW,OAAO,CAAC,CAAA;AAAA;AAE/C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.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 */\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouterFromConfig } from './service/router';\n\n/**\n * Backend plugin for Copilot.\n *\n * @public\n */\nexport const copilotPlugin = createBackendPlugin({\n pluginId: 'copilot',\n register(env) {\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n database: coreServices.database,\n scheduler: coreServices.scheduler,\n config: coreServices.rootConfig,\n },\n async init({ httpRouter, logger, database, scheduler, config }) {\n httpRouter.use(\n await createRouterFromConfig({\n logger,\n database,\n scheduler,\n config,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","createRouterFromConfig"],"mappings":";;;;;AA0BO,MAAM,gBAAgBA,oCAAoB,CAAA;AAAA,EAC/C,QAAU,EAAA,SAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,YAAYC,6BAAa,CAAA,UAAA;AAAA,QACzB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,QAAQA,6BAAa,CAAA,UAAA;AAAA,OACvB;AAAA,MACA,MAAM,KAAK,EAAE,UAAA,EAAY,QAAQ,QAAU,EAAA,SAAA,EAAW,QAAU,EAAA;AAC9D,QAAW,UAAA,CAAA,GAAA;AAAA,UACT,MAAMC,6BAAuB,CAAA;AAAA,YAC3B,MAAA;AAAA,YACA,QAAA;AAAA,YACA,SAAA;AAAA,YACA,MAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AACA,QAAA,UAAA,CAAW,aAAc,CAAA;AAAA,UACvB,IAAM,EAAA,SAAA;AAAA,UACN,KAAO,EAAA,iBAAA;AAAA,SACR,CAAA,CAAA;AAAA,OACH;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.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 */\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouterFromConfig } from './service/router';\n\n/**\n * Backend plugin for Copilot.\n *\n * @public\n */\nexport const copilotPlugin = createBackendPlugin({\n pluginId: 'copilot',\n register(env) {\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n database: coreServices.database,\n scheduler: coreServices.scheduler,\n config: coreServices.rootConfig,\n },\n async init({ httpRouter, logger, database, scheduler, config }) {\n httpRouter.use(\n await createRouterFromConfig({\n logger,\n database,\n scheduler,\n config,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","createRouterFromConfig"],"mappings":";;;;;AA0BO,MAAM,gBAAgBA,oCAAoB,CAAA;AAAA,EAC/C,QAAU,EAAA,SAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,YAAYC,6BAAa,CAAA,UAAA;AAAA,QACzB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,QAAQA,6BAAa,CAAA;AAAA,OACvB;AAAA,MACA,MAAM,KAAK,EAAE,UAAA,EAAY,QAAQ,QAAU,EAAA,SAAA,EAAW,QAAU,EAAA;AAC9D,QAAW,UAAA,CAAA,GAAA;AAAA,UACT,MAAMC,6BAAuB,CAAA;AAAA,YAC3B,MAAA;AAAA,YACA,QAAA;AAAA,YACA,SAAA;AAAA,YACA;AAAA,WACD;AAAA,SACH;AACA,QAAA,UAAA,CAAW,aAAc,CAAA;AAAA,UACvB,IAAM,EAAA,SAAA;AAAA,UACN,KAAO,EAAA;AAAA,SACR,CAAA;AAAA;AACH,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.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 */\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n DatabaseService,\n LoggerService,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n SchedulerService,\n SchedulerServiceTaskScheduleDefinition,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\nimport { Metric } from '@backstage-community/plugin-copilot-common';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport TaskManagement from '../task/TaskManagement';\nimport { GithubClient } from '../client/GithubClient';\nimport { validateQuery } from './validation/validateQuery';\nimport {\n MetricsQuery,\n metricsQuerySchema,\n PeriodRangeQuery,\n periodRangeQuerySchema,\n TeamQuery,\n teamQuerySchema,\n} from './validation/schema';\n\n/**\n * Options for configuring the Copilot plugin.\n *\n * @public\n */\nexport interface PluginOptions {\n /**\n * Schedule configuration for the plugin.\n */\n schedule?: SchedulerServiceTaskScheduleDefinition;\n}\n\n/**\n * Options for configuring the router used by the Copilot plugin.\n *\n * @public\n */\nexport interface RouterOptions {\n /**\n * Logger service for the router.\n */\n logger: LoggerService;\n\n /**\n * Database service for the router.\n */\n database: DatabaseService;\n\n /**\n * Scheduler service for the router.\n */\n scheduler: SchedulerService;\n\n /**\n * Configuration for the router.\n */\n config: Config;\n}\n\nconst defaultSchedule: SchedulerServiceTaskScheduleDefinition = {\n frequency: { cron: '0 2 * * *' },\n timeout: { minutes: 15 },\n initialDelay: { minutes: 1 },\n scope: 'local',\n};\n\n/**\n * Creates an Express router configured based on the provided router options and plugin options.\n *\n * This function initializes the router with the appropriate middleware and routes based on the\n * configuration and options provided. It also schedules tasks if scheduling options are provided.\n *\n * @param routerOptions - Options for configuring the router, including services and configuration.\n * @returns A promise that resolves to an Express router instance.\n *\n * @public\n */\nexport async function createRouterFromConfig(routerOptions: RouterOptions) {\n const { config } = routerOptions;\n const pluginOptions: PluginOptions = {\n schedule: defaultSchedule,\n };\n if (config && config.has('copilot.schedule')) {\n pluginOptions.schedule =\n readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config.getConfig('copilot.schedule'),\n );\n }\n return createRouter(routerOptions, pluginOptions);\n}\n\n/** @private */\nasync function createRouter(\n routerOptions: RouterOptions,\n pluginOptions: PluginOptions,\n): Promise<express.Router> {\n const { logger, database, scheduler, config } = routerOptions;\n const { schedule } = pluginOptions;\n\n const db = await DatabaseHandler.create({ database });\n const api = await GithubClient.fromConfig(config);\n\n await scheduler.scheduleTask({\n id: 'copilot-metrics',\n ...(schedule ?? defaultSchedule),\n fn: async () =>\n await TaskManagement.create({ db, logger, api, config }).runAsync(),\n });\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n router.get(\n '/metrics',\n validateQuery(metricsQuerySchema),\n async (req, res) => {\n const { startDate, endDate, type, team } = req.query as MetricsQuery;\n\n const result = await db.getMetrics(startDate, endDate, type, team);\n\n const metrics: Metric[] = result.map(metric => ({\n ...metric,\n breakdown: JSON.parse(metric.breakdown),\n }));\n\n return res.json(metrics);\n },\n );\n\n router.get(\n '/metrics/period-range',\n validateQuery(periodRangeQuerySchema),\n async (req, res) => {\n const { type } = req.query as PeriodRangeQuery;\n const result = await db.getPeriodRange(type);\n\n if (!result) {\n throw new NotFoundError();\n }\n\n return res.json(result);\n },\n );\n\n router.get('/teams', validateQuery(teamQuerySchema), async (req, res) => {\n const { type, startDate, endDate } = req.query as TeamQuery;\n\n const result = await db.getTeams(type, startDate, endDate);\n\n if (!result) {\n throw new NotFoundError();\n }\n\n return res.json(result);\n });\n\n router.use(MiddlewareFactory.create({ config, logger }).error);\n return router;\n}\n"],"names":["readSchedulerServiceTaskScheduleDefinitionFromConfig","DatabaseHandler","GithubClient","TaskManagement","Router","express","validateQuery","metricsQuerySchema","periodRangeQuerySchema","NotFoundError","teamQuerySchema","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;;;;AAgFA,MAAM,eAA0D,GAAA;AAAA,EAC9D,SAAA,EAAW,EAAE,IAAA,EAAM,WAAY,EAAA;AAAA,EAC/B,OAAA,EAAS,EAAE,OAAA,EAAS,EAAG,EAAA;AAAA,EACvB,YAAA,EAAc,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,EAC3B,KAAO,EAAA,OAAA;AACT,CAAA,CAAA;AAaA,eAAsB,uBAAuB,aAA8B,EAAA;AACzE,EAAM,MAAA,EAAE,QAAW,GAAA,aAAA,CAAA;AACnB,EAAA,MAAM,aAA+B,GAAA;AAAA,IACnC,QAAU,EAAA,eAAA;AAAA,GACZ,CAAA;AACA,EAAA,IAAI,MAAU,IAAA,MAAA,CAAO,GAAI,CAAA,kBAAkB,CAAG,EAAA;AAC5C,IAAA,aAAA,CAAc,QACZ,GAAAA,qEAAA;AAAA,MACE,MAAA,CAAO,UAAU,kBAAkB,CAAA;AAAA,KACrC,CAAA;AAAA,GACJ;AACA,EAAO,OAAA,YAAA,CAAa,eAAe,aAAa,CAAA,CAAA;AAClD,CAAA;AAGA,eAAe,YAAA,CACb,eACA,aACyB,EAAA;AACzB,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAU,EAAA,SAAA,EAAW,QAAW,GAAA,aAAA,CAAA;AAChD,EAAM,MAAA,EAAE,UAAa,GAAA,aAAA,CAAA;AAErB,EAAA,MAAM,KAAK,MAAMC,+BAAA,CAAgB,MAAO,CAAA,EAAE,UAAU,CAAA,CAAA;AACpD,EAAA,MAAM,GAAM,GAAA,MAAMC,yBAAa,CAAA,UAAA,CAAW,MAAM,CAAA,CAAA;AAEhD,EAAA,MAAM,UAAU,YAAa,CAAA;AAAA,IAC3B,EAAI,EAAA,iBAAA;AAAA,IACJ,GAAI,QAAY,IAAA,eAAA;AAAA,IAChB,EAAI,EAAA,YACF,MAAMC,sBAAA,CAAe,MAAO,CAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,GAAK,EAAA,MAAA,EAAQ,CAAA,CAAE,QAAS,EAAA;AAAA,GACrE,CAAA,CAAA;AAED,EAAA,MAAM,SAASC,uBAAO,EAAA,CAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,wBAAQ,CAAA,IAAA,EAAM,CAAA,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAI,CAAA,SAAA,EAAW,CAAC,CAAA,EAAG,QAAa,KAAA;AACrC,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA,CAAA;AACnB,IAAA,QAAA,CAAS,IAAK,CAAA,EAAE,MAAQ,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,GAC/B,CAAA,CAAA;AAED,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,UAAA;AAAA,IACAC,4BAAcC,yBAAkB,CAAA;AAAA,IAChC,OAAO,KAAK,GAAQ,KAAA;AAClB,MAAA,MAAM,EAAE,SAAW,EAAA,OAAA,EAAS,IAAM,EAAA,IAAA,KAAS,GAAI,CAAA,KAAA,CAAA;AAE/C,MAAA,MAAM,SAAS,MAAM,EAAA,CAAG,WAAW,SAAW,EAAA,OAAA,EAAS,MAAM,IAAI,CAAA,CAAA;AAEjE,MAAM,MAAA,OAAA,GAAoB,MAAO,CAAA,GAAA,CAAI,CAAW,MAAA,MAAA;AAAA,QAC9C,GAAG,MAAA;AAAA,QACH,SAAW,EAAA,IAAA,CAAK,KAAM,CAAA,MAAA,CAAO,SAAS,CAAA;AAAA,OACtC,CAAA,CAAA,CAAA;AAEF,MAAO,OAAA,GAAA,CAAI,KAAK,OAAO,CAAA,CAAA;AAAA,KACzB;AAAA,GACF,CAAA;AAEA,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,uBAAA;AAAA,IACAD,4BAAcE,6BAAsB,CAAA;AAAA,IACpC,OAAO,KAAK,GAAQ,KAAA;AAClB,MAAM,MAAA,EAAE,IAAK,EAAA,GAAI,GAAI,CAAA,KAAA,CAAA;AACrB,MAAA,MAAM,MAAS,GAAA,MAAM,EAAG,CAAA,cAAA,CAAe,IAAI,CAAA,CAAA;AAE3C,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,MAAM,IAAIC,oBAAc,EAAA,CAAA;AAAA,OAC1B;AAEA,MAAO,OAAA,GAAA,CAAI,KAAK,MAAM,CAAA,CAAA;AAAA,KACxB;AAAA,GACF,CAAA;AAEA,EAAA,MAAA,CAAO,IAAI,QAAU,EAAAH,2BAAA,CAAcI,sBAAe,CAAG,EAAA,OAAO,KAAK,GAAQ,KAAA;AACvE,IAAA,MAAM,EAAE,IAAA,EAAM,SAAW,EAAA,OAAA,KAAY,GAAI,CAAA,KAAA,CAAA;AAEzC,IAAA,MAAM,SAAS,MAAM,EAAA,CAAG,QAAS,CAAA,IAAA,EAAM,WAAW,OAAO,CAAA,CAAA;AAEzD,IAAA,IAAI,CAAC,MAAQ,EAAA;AACX,MAAA,MAAM,IAAID,oBAAc,EAAA,CAAA;AAAA,KAC1B;AAEA,IAAO,OAAA,GAAA,CAAI,KAAK,MAAM,CAAA,CAAA;AAAA,GACvB,CAAA,CAAA;AAED,EAAO,MAAA,CAAA,GAAA,CAAIE,iCAAkB,MAAO,CAAA,EAAE,QAAQ,MAAO,EAAC,EAAE,KAAK,CAAA,CAAA;AAC7D,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.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 */\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n DatabaseService,\n LoggerService,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n SchedulerService,\n SchedulerServiceTaskScheduleDefinition,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\nimport { Metric } from '@backstage-community/plugin-copilot-common';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport TaskManagement from '../task/TaskManagement';\nimport { GithubClient } from '../client/GithubClient';\nimport { validateQuery } from './validation/validateQuery';\nimport {\n MetricsQuery,\n metricsQuerySchema,\n PeriodRangeQuery,\n periodRangeQuerySchema,\n TeamQuery,\n teamQuerySchema,\n} from './validation/schema';\n\n/**\n * Options for configuring the Copilot plugin.\n *\n * @public\n */\nexport interface PluginOptions {\n /**\n * Schedule configuration for the plugin.\n */\n schedule?: SchedulerServiceTaskScheduleDefinition;\n}\n\n/**\n * Options for configuring the router used by the Copilot plugin.\n *\n * @public\n */\nexport interface RouterOptions {\n /**\n * Logger service for the router.\n */\n logger: LoggerService;\n\n /**\n * Database service for the router.\n */\n database: DatabaseService;\n\n /**\n * Scheduler service for the router.\n */\n scheduler: SchedulerService;\n\n /**\n * Configuration for the router.\n */\n config: Config;\n}\n\nconst defaultSchedule: SchedulerServiceTaskScheduleDefinition = {\n frequency: { cron: '0 2 * * *' },\n timeout: { minutes: 15 },\n initialDelay: { minutes: 1 },\n scope: 'local',\n};\n\n/**\n * Creates an Express router configured based on the provided router options and plugin options.\n *\n * This function initializes the router with the appropriate middleware and routes based on the\n * configuration and options provided. It also schedules tasks if scheduling options are provided.\n *\n * @param routerOptions - Options for configuring the router, including services and configuration.\n * @returns A promise that resolves to an Express router instance.\n *\n * @public\n */\nexport async function createRouterFromConfig(routerOptions: RouterOptions) {\n const { config } = routerOptions;\n const pluginOptions: PluginOptions = {\n schedule: defaultSchedule,\n };\n if (config && config.has('copilot.schedule')) {\n pluginOptions.schedule =\n readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config.getConfig('copilot.schedule'),\n );\n }\n return createRouter(routerOptions, pluginOptions);\n}\n\n/** @private */\nasync function createRouter(\n routerOptions: RouterOptions,\n pluginOptions: PluginOptions,\n): Promise<express.Router> {\n const { logger, database, scheduler, config } = routerOptions;\n const { schedule } = pluginOptions;\n\n const db = await DatabaseHandler.create({ database });\n const api = await GithubClient.fromConfig(config);\n\n await scheduler.scheduleTask({\n id: 'copilot-metrics',\n ...(schedule ?? defaultSchedule),\n fn: async () =>\n await TaskManagement.create({ db, logger, api, config }).runAsync(),\n });\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n router.get(\n '/metrics',\n validateQuery(metricsQuerySchema),\n async (req, res) => {\n const { startDate, endDate, type, team } = req.query as MetricsQuery;\n\n const result = await db.getMetrics(startDate, endDate, type, team);\n\n const metrics: Metric[] = result.map(metric => ({\n ...metric,\n breakdown: JSON.parse(metric.breakdown),\n }));\n\n return res.json(metrics);\n },\n );\n\n router.get(\n '/metrics/period-range',\n validateQuery(periodRangeQuerySchema),\n async (req, res) => {\n const { type } = req.query as PeriodRangeQuery;\n const result = await db.getPeriodRange(type);\n\n if (!result) {\n throw new NotFoundError();\n }\n\n return res.json(result);\n },\n );\n\n router.get('/teams', validateQuery(teamQuerySchema), async (req, res) => {\n const { type, startDate, endDate } = req.query as TeamQuery;\n\n const result = await db.getTeams(type, startDate, endDate);\n\n if (!result) {\n throw new NotFoundError();\n }\n\n return res.json(result);\n });\n\n router.use(MiddlewareFactory.create({ config, logger }).error);\n return router;\n}\n"],"names":["readSchedulerServiceTaskScheduleDefinitionFromConfig","DatabaseHandler","GithubClient","TaskManagement","Router","express","validateQuery","metricsQuerySchema","periodRangeQuerySchema","NotFoundError","teamQuerySchema","MiddlewareFactory"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.cjs.js","sources":["../../../src/service/validation/schema.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 */\nimport { z } from 'zod';\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\n\nconst metricsTypeSchema = z.enum(['enterprise', 'organization']);\n\nconst isoDateSchema = z.string().refine(date => !isNaN(Date.parse(date)), {\n message: 'Invalid date format',\n});\n\nexport type MetricsQuery = {\n startDate: string;\n endDate: string;\n type: MetricsType;\n team?: string;\n};\n\nexport type PeriodRangeQuery = {\n type: MetricsType;\n};\n\nexport type TeamQuery = {\n type: MetricsType;\n startDate: string;\n endDate: string;\n};\n\nexport const metricsQuerySchema = z.object({\n startDate: isoDateSchema,\n endDate: isoDateSchema,\n type: metricsTypeSchema,\n team: z.string().optional(),\n});\n\nexport const periodRangeQuerySchema = z.object({\n type: metricsTypeSchema,\n});\n\nexport const teamQuerySchema = z.object({\n startDate: isoDateSchema,\n endDate: isoDateSchema,\n type: metricsTypeSchema,\n});\n"],"names":["z"],"mappings":";;;;AAkBA,MAAM,oBAAoBA,KAAE,CAAA,IAAA,CAAK,CAAC,YAAA,EAAc,cAAc,CAAC,CAAA,CAAA;AAE/D,MAAM,aAAgB,GAAAA,KAAA,CAAE,MAAO,EAAA,CAAE,MAAO,CAAA,CAAA,IAAA,KAAQ,CAAC,KAAA,CAAM,IAAK,CAAA,KAAA,CAAM,IAAI,CAAC,CAAG,EAAA;AAAA,EACxE,OAAS,EAAA,qBAAA;AACX,CAAC,CAAA,CAAA;AAmBY,MAAA,kBAAA,GAAqBA,MAAE,MAAO,CAAA;AAAA,EACzC,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA,aAAA;AAAA,EACT,IAAM,EAAA,iBAAA;AAAA,EACN,IAAM,EAAAA,KAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAC5B,CAAC,EAAA;AAEY,MAAA,sBAAA,GAAyBA,MAAE,MAAO,CAAA;AAAA,EAC7C,IAAM,EAAA,iBAAA;AACR,CAAC,EAAA;AAEY,MAAA,eAAA,GAAkBA,MAAE,MAAO,CAAA;AAAA,EACtC,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA,aAAA;AAAA,EACT,IAAM,EAAA,iBAAA;AACR,CAAC;;;;;;"}
1
+ {"version":3,"file":"schema.cjs.js","sources":["../../../src/service/validation/schema.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 */\nimport { z } from 'zod';\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\n\nconst metricsTypeSchema = z.enum(['enterprise', 'organization']);\n\nconst isoDateSchema = z.string().refine(date => !isNaN(Date.parse(date)), {\n message: 'Invalid date format',\n});\n\nexport type MetricsQuery = {\n startDate: string;\n endDate: string;\n type: MetricsType;\n team?: string;\n};\n\nexport type PeriodRangeQuery = {\n type: MetricsType;\n};\n\nexport type TeamQuery = {\n type: MetricsType;\n startDate: string;\n endDate: string;\n};\n\nexport const metricsQuerySchema = z.object({\n startDate: isoDateSchema,\n endDate: isoDateSchema,\n type: metricsTypeSchema,\n team: z.string().optional(),\n});\n\nexport const periodRangeQuerySchema = z.object({\n type: metricsTypeSchema,\n});\n\nexport const teamQuerySchema = z.object({\n startDate: isoDateSchema,\n endDate: isoDateSchema,\n type: metricsTypeSchema,\n});\n"],"names":["z"],"mappings":";;;;AAkBA,MAAM,oBAAoBA,KAAE,CAAA,IAAA,CAAK,CAAC,YAAA,EAAc,cAAc,CAAC,CAAA;AAE/D,MAAM,aAAgB,GAAAA,KAAA,CAAE,MAAO,EAAA,CAAE,MAAO,CAAA,CAAA,IAAA,KAAQ,CAAC,KAAA,CAAM,IAAK,CAAA,KAAA,CAAM,IAAI,CAAC,CAAG,EAAA;AAAA,EACxE,OAAS,EAAA;AACX,CAAC,CAAA;AAmBY,MAAA,kBAAA,GAAqBA,MAAE,MAAO,CAAA;AAAA,EACzC,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA,aAAA;AAAA,EACT,IAAM,EAAA,iBAAA;AAAA,EACN,IAAM,EAAAA,KAAA,CAAE,MAAO,EAAA,CAAE,QAAS;AAC5B,CAAC;AAEY,MAAA,sBAAA,GAAyBA,MAAE,MAAO,CAAA;AAAA,EAC7C,IAAM,EAAA;AACR,CAAC;AAEY,MAAA,eAAA,GAAkBA,MAAE,MAAO,CAAA;AAAA,EACtC,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA,aAAA;AAAA,EACT,IAAM,EAAA;AACR,CAAC;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"validateQuery.cjs.js","sources":["../../../src/service/validation/validateQuery.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 */\nimport { InputError } from '@backstage/errors';\nimport { NextFunction, Request, Response } from 'express';\nimport { ZodSchema } from 'zod';\n\nexport function validateQuery(schema: ZodSchema) {\n return (req: Request, _res: Response, next: NextFunction) => {\n const { error, data } = schema.safeParse(req.query);\n\n if (error) {\n throw new InputError(error.errors[0].message, error);\n }\n\n req.query = data;\n\n return next();\n };\n}\n"],"names":["InputError"],"mappings":";;;;AAmBO,SAAS,cAAc,MAAmB,EAAA;AAC/C,EAAO,OAAA,CAAC,GAAc,EAAA,IAAA,EAAgB,IAAuB,KAAA;AAC3D,IAAA,MAAM,EAAE,KAAO,EAAA,IAAA,KAAS,MAAO,CAAA,SAAA,CAAU,IAAI,KAAK,CAAA,CAAA;AAElD,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,MAAM,IAAIA,iBAAW,CAAA,KAAA,CAAM,OAAO,CAAC,CAAA,CAAE,SAAS,KAAK,CAAA,CAAA;AAAA,KACrD;AAEA,IAAA,GAAA,CAAI,KAAQ,GAAA,IAAA,CAAA;AAEZ,IAAA,OAAO,IAAK,EAAA,CAAA;AAAA,GACd,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"validateQuery.cjs.js","sources":["../../../src/service/validation/validateQuery.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 */\nimport { InputError } from '@backstage/errors';\nimport { NextFunction, Request, Response } from 'express';\nimport { ZodSchema } from 'zod';\n\nexport function validateQuery(schema: ZodSchema) {\n return (req: Request, _res: Response, next: NextFunction) => {\n const { error, data } = schema.safeParse(req.query);\n\n if (error) {\n throw new InputError(error.errors[0].message, error);\n }\n\n req.query = data;\n\n return next();\n };\n}\n"],"names":["InputError"],"mappings":";;;;AAmBO,SAAS,cAAc,MAAmB,EAAA;AAC/C,EAAO,OAAA,CAAC,GAAc,EAAA,IAAA,EAAgB,IAAuB,KAAA;AAC3D,IAAA,MAAM,EAAE,KAAO,EAAA,IAAA,KAAS,MAAO,CAAA,SAAA,CAAU,IAAI,KAAK,CAAA;AAElD,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,MAAM,IAAIA,iBAAW,CAAA,KAAA,CAAM,OAAO,CAAC,CAAA,CAAE,SAAS,KAAK,CAAA;AAAA;AAGrD,IAAA,GAAA,CAAI,KAAQ,GAAA,IAAA;AAEZ,IAAA,OAAO,IAAK,EAAA;AAAA,GACd;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnterpriseTask.cjs.js","sources":["../../src/task/EnterpriseTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const metrics = await api.fetchEnterpriseCopilotUsage();\n logger.info(\n `[discoverEnterpriseMetrics] Fetched ${metrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type);\n logger.info(`[discoverEnterpriseMetrics] Found last day: ${lastDay}`);\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverEnterpriseMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n '[discoverEnterpriseMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info('[discoverEnterpriseMetrics] No new metrics found to insert');\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,yBAA0B,CAAA;AAAA,EAC9C,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA,MAAA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,oBAAoB,CAAG,EAAA;AACnD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,2EAAA;AAAA,KACF,CAAA;AACA,IAAA,OAAA;AAAA,GACF;AAEA,EAAA,MAAM,IAAoB,GAAA,YAAA,CAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,GAAA,CAAI,2BAA4B,EAAA,CAAA;AACtD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,oCAAA,EAAuC,QAAQ,MAAM,CAAA,QAAA,CAAA;AAAA,KACvD,CAAA;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,EAAG,CAAA,2BAAA,CAA4B,IAAI,CAAA,CAAA;AACzD,IAAO,MAAA,CAAA,IAAA,CAAK,CAA+C,4CAAA,EAAA,OAAO,CAAE,CAAA,CAAA,CAAA;AAEpE,IAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AACpD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,kCAAA,EAAqC,WAAW,MAAM,CAAA,sBAAA,CAAA;AAAA,KACxD,CAAA;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,MAAM,MAAAC,+BAAA;AAAA,QACJC,qCAAA,CAAwB,YAAY,IAAI,CAAA;AAAA,QACxC,EAAA;AAAA,QACA,OAAO,KAAyB,KAAA;AAC9B,UAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA,CAAA;AAAA,SAC5B;AAAA,OACF,CAAA;AACA,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,oEAAA;AAAA,OACF,CAAA;AAAA,KACK,MAAA;AACL,MAAA,MAAA,CAAO,KAAK,4DAA4D,CAAA,CAAA;AAAA,KAC1E;AAAA,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,0FAA0F,KAAK,CAAA,CAAA;AAAA,KACjG,CAAA;AACA,IAAM,MAAA,KAAA,CAAA;AAAA,GACR;AACF;;;;"}
1
+ {"version":3,"file":"EnterpriseTask.cjs.js","sources":["../../src/task/EnterpriseTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const metrics = await api.fetchEnterpriseCopilotUsage();\n logger.info(\n `[discoverEnterpriseMetrics] Fetched ${metrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type);\n logger.info(`[discoverEnterpriseMetrics] Found last day: ${lastDay}`);\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverEnterpriseMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n '[discoverEnterpriseMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info('[discoverEnterpriseMetrics] No new metrics found to insert');\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,yBAA0B,CAAA;AAAA,EAC9C,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,oBAAoB,CAAG,EAAA;AACnD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,YAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,GAAA,CAAI,2BAA4B,EAAA;AACtD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,oCAAA,EAAuC,QAAQ,MAAM,CAAA,QAAA;AAAA,KACvD;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,EAAG,CAAA,2BAAA,CAA4B,IAAI,CAAA;AACzD,IAAO,MAAA,CAAA,IAAA,CAAK,CAA+C,4CAAA,EAAA,OAAO,CAAE,CAAA,CAAA;AAEpE,IAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,kCAAA,EAAqC,WAAW,MAAM,CAAA,sBAAA;AAAA,KACxD;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,MAAM,MAAAC,+BAAA;AAAA,QACJC,qCAAA,CAAwB,YAAY,IAAI,CAAA;AAAA,QACxC,EAAA;AAAA,QACA,OAAO,KAAyB,KAAA;AAC9B,UAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,OACF;AACA,MAAO,MAAA,CAAA,IAAA;AAAA,QACL;AAAA,OACF;AAAA,KACK,MAAA;AACL,MAAA,MAAA,CAAO,KAAK,4DAA4D,CAAA;AAAA;AAC1E,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,0FAA0F,KAAK,CAAA;AAAA,KACjG;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnterpriseTeamTask.cjs.js","sources":["../../src/task/EnterpriseTeamTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseTeamMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const teams = await api.fetchEnterpriseTeams();\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchEnterpriseTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverEnterpriseTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverEnterpriseTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,6BAA8B,CAAA;AAAA,EAClD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA,MAAA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,oBAAoB,CAAG,EAAA;AACnD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,+EAAA;AAAA,KACF,CAAA;AACA,IAAA,OAAA;AAAA,GACF;AAEA,EAAA,MAAM,IAAoB,GAAA,YAAA,CAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,oBAAqB,EAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,wCAAA,EAA2C,MAAM,MAAM,CAAA,MAAA,CAAA;AAAA,KACzD,CAAA;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,2DAAA,EAA8D,KAAK,IAAI,CAAA,CAAA;AAAA,SACzE,CAAA;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,+BAAA,CAAgC,KAAK,IAAI,CAAA,CAAA;AACnE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA,CAAA;AAAA,SAC1F,CAAA;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA;AAAA,SAC5F,CAAA;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAyC,sCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA,CAAA;AAAA,SAC9F,CAAA;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA,CAAA;AAAA,aAC5B;AAAA,WACF,CAAA;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,2EAAA,EAA8E,KAAK,IAAI,CAAA,kBAAA,CAAA;AAAA,WACzF,CAAA;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,8DAAA,EAAiE,KAAK,IAAI,CAAA,UAAA,CAAA;AAAA,WAC5E,CAAA;AAAA,SACF;AAAA,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA;AAAA,SAC1F,CAAA;AAAA,OACF;AAAA,KACF;AAAA,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,yDAAyD,KAAK,CAAA,CAAA;AAAA,KAChE,CAAA;AACA,IAAM,MAAA,KAAA,CAAA;AAAA,GACR;AACF;;;;"}
1
+ {"version":3,"file":"EnterpriseTeamTask.cjs.js","sources":["../../src/task/EnterpriseTeamTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseTeamMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const teams = await api.fetchEnterpriseTeams();\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchEnterpriseTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverEnterpriseTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverEnterpriseTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,6BAA8B,CAAA;AAAA,EAClD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,oBAAoB,CAAG,EAAA;AACnD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,YAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,oBAAqB,EAAA;AAC7C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,wCAAA,EAA2C,MAAM,MAAM,CAAA,MAAA;AAAA,KACzD;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,2DAAA,EAA8D,KAAK,IAAI,CAAA;AAAA,SACzE;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,+BAAA,CAAgC,KAAK,IAAI,CAAA;AACnE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA;AAAA,SAC1F;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA;AAAA,SAC5F;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAyC,sCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA;AAAA,SAC9F;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,WACF;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,2EAAA,EAA8E,KAAK,IAAI,CAAA,kBAAA;AAAA,WACzF;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,8DAAA,EAAiE,KAAK,IAAI,CAAA,UAAA;AAAA,WAC5E;AAAA;AACF,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,SAC1F;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,yDAAyD,KAAK,CAAA;AAAA,KAChE;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationTask.cjs.js","sources":["../../src/task/OrganizationTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const metrics = await api.fetchOrganizationCopilotUsage();\n logger.info(\n `[discoverOrganizationMetrics] Fetched ${metrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type);\n logger.info(`[discoverOrganizationMetrics] Found last day: ${lastDay}`);\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n '[discoverOrganizationMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info(\n '[discoverOrganizationMetrics] No new metrics found to insert',\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,2BAA4B,CAAA;AAAA,EAChD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA,MAAA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,+EAAA;AAAA,KACF,CAAA;AACA,IAAA,OAAA;AAAA,GACF;AAEA,EAAA,MAAM,IAAoB,GAAA,cAAA,CAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,GAAA,CAAI,6BAA8B,EAAA,CAAA;AACxD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,sCAAA,EAAyC,QAAQ,MAAM,CAAA,QAAA,CAAA;AAAA,KACzD,CAAA;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,EAAG,CAAA,2BAAA,CAA4B,IAAI,CAAA,CAAA;AACzD,IAAO,MAAA,CAAA,IAAA,CAAK,CAAiD,8CAAA,EAAA,OAAO,CAAE,CAAA,CAAA,CAAA;AAEtE,IAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AACpD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,oCAAA,EAAuC,WAAW,MAAM,CAAA,sBAAA,CAAA;AAAA,KAC1D,CAAA;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,MAAM,MAAAC,+BAAA;AAAA,QACJC,qCAAA,CAAwB,YAAY,IAAI,CAAA;AAAA,QACxC,EAAA;AAAA,QACA,OAAO,KAAyB,KAAA;AAC9B,UAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA,CAAA;AAAA,SAC5B;AAAA,OACF,CAAA;AACA,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,sEAAA;AAAA,OACF,CAAA;AAAA,KACK,MAAA;AACL,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,8DAAA;AAAA,OACF,CAAA;AAAA,KACF;AAAA,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,4FAA4F,KAAK,CAAA,CAAA;AAAA,KACnG,CAAA;AACA,IAAM,MAAA,KAAA,CAAA;AAAA,GACR;AACF;;;;"}
1
+ {"version":3,"file":"OrganizationTask.cjs.js","sources":["../../src/task/OrganizationTask.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 */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const metrics = await api.fetchOrganizationCopilotUsage();\n logger.info(\n `[discoverOrganizationMetrics] Fetched ${metrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type);\n logger.info(`[discoverOrganizationMetrics] Found last day: ${lastDay}`);\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n '[discoverOrganizationMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info(\n '[discoverOrganizationMetrics] No new metrics found to insert',\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,2BAA4B,CAAA;AAAA,EAChD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,cAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,GAAA,CAAI,6BAA8B,EAAA;AACxD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,sCAAA,EAAyC,QAAQ,MAAM,CAAA,QAAA;AAAA,KACzD;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,EAAG,CAAA,2BAAA,CAA4B,IAAI,CAAA;AACzD,IAAO,MAAA,CAAA,IAAA,CAAK,CAAiD,8CAAA,EAAA,OAAO,CAAE,CAAA,CAAA;AAEtE,IAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,oCAAA,EAAuC,WAAW,MAAM,CAAA,sBAAA;AAAA,KAC1D;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,MAAM,MAAAC,+BAAA;AAAA,QACJC,qCAAA,CAAwB,YAAY,IAAI,CAAA;AAAA,QACxC,EAAA;AAAA,QACA,OAAO,KAAyB,KAAA;AAC9B,UAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,OACF;AACA,MAAO,MAAA,CAAA,IAAA;AAAA,QACL;AAAA,OACF;AAAA,KACK,MAAA;AACL,MAAO,MAAA,CAAA,IAAA;AAAA,QACL;AAAA,OACF;AAAA;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,4FAA4F,KAAK,CAAA;AAAA,KACnG;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationTeamTask.cjs.js","sources":["../../src/task/OrganizationTeamTask.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 { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationTeamMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const teams = await api.fetchOrganizationTeams();\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchOrganizationTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverOrganizationTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverOrganizationTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAyBA,eAAsB,+BAAgC,CAAA;AAAA,EACpD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA,MAAA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,mFAAA;AAAA,KACF,CAAA;AACA,IAAA,OAAA;AAAA,GACF;AAEA,EAAA,MAAM,IAAoB,GAAA,cAAA,CAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,sBAAuB,EAAA,CAAA;AAC/C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,0CAAA,EAA6C,MAAM,MAAM,CAAA,MAAA,CAAA;AAAA,KAC3D,CAAA;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA;AAAA,SAC3E,CAAA;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,iCAAA,CAAkC,KAAK,IAAI,CAAA,CAAA;AACrE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA6C,0CAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA,CAAA;AAAA,SAC5F,CAAA;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA;AAAA,SAC9F,CAAA;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA,CAAA;AAAA,SAChG,CAAA;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA,CAAA;AAAA,aAC5B;AAAA,WACF,CAAA;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,6EAAA,EAAgF,KAAK,IAAI,CAAA,kBAAA,CAAA;AAAA,WAC3F,CAAA;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,gEAAA,EAAmE,KAAK,IAAI,CAAA,UAAA,CAAA;AAAA,WAC9E,CAAA;AAAA,SACF;AAAA,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA;AAAA,SAC5F,CAAA;AAAA,OACF;AAAA,KACF;AAAA,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,2DAA2D,KAAK,CAAA,CAAA;AAAA,KAClE,CAAA;AACA,IAAM,MAAA,KAAA,CAAA;AAAA,GACR;AACF;;;;"}
1
+ {"version":3,"file":"OrganizationTeamTask.cjs.js","sources":["../../src/task/OrganizationTeamTask.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 { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationTeamMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const teams = await api.fetchOrganizationTeams();\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchOrganizationTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverOrganizationTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverOrganizationTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAyBA,eAAsB,+BAAgC,CAAA;AAAA,EACpD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,cAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,sBAAuB,EAAA;AAC/C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,0CAAA,EAA6C,MAAM,MAAM,CAAA,MAAA;AAAA,KAC3D;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA;AAAA,SAC3E;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,iCAAA,CAAkC,KAAK,IAAI,CAAA;AACrE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA6C,0CAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA;AAAA,SAC5F;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA;AAAA,SAC9F;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA;AAAA,SAChG;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,WACF;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,6EAAA,EAAgF,KAAK,IAAI,CAAA,kBAAA;AAAA,WAC3F;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,gEAAA,EAAmE,KAAK,IAAI,CAAA,UAAA;AAAA,WAC9E;AAAA;AACF,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,SAC5F;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,2DAA2D,KAAK,CAAA;AAAA,KAClE;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"TaskManagement.cjs.js","sources":["../../src/task/TaskManagement.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 */\nimport { Config } from '@backstage/config';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { GithubClient } from '../client/GithubClient';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport { discoverOrganizationMetrics } from './OrganizationTask';\nimport { discoverOrganizationTeamMetrics } from './OrganizationTeamTask';\nimport { discoverEnterpriseMetrics } from './EnterpriseTask';\nimport { discoverEnterpriseTeamMetrics } from './EnterpriseTeamTask';\n\nexport type TaskOptions = {\n api: GithubClient;\n config: Config;\n logger: LoggerService;\n db: DatabaseHandler;\n};\n\nexport default class TaskManagement {\n private readonly tasks: Array<() => Promise<void>>;\n\n constructor(private readonly options: TaskOptions) {\n this.tasks = [\n () => discoverOrganizationMetrics(this.options),\n () => discoverOrganizationTeamMetrics(this.options),\n () => discoverEnterpriseMetrics(this.options),\n () => discoverEnterpriseTeamMetrics(this.options),\n ];\n }\n\n static create(options: TaskOptions) {\n return new TaskManagement(options);\n }\n\n async runAsync() {\n this.options.logger.info(\n `[TaskManagement] Starting processing of ${this.tasks.length} tasks`,\n );\n\n const taskPromises = this.tasks.map(async task => {\n try {\n await task();\n } catch (e) {\n this.options.logger.warn(\n `[TaskManagement] Failed to process task: ${e.message}`,\n );\n }\n });\n\n await Promise.all(taskPromises);\n\n this.options.logger.info(\n `[TaskManagement] Completed processing of all tasks`,\n );\n }\n}\n"],"names":["discoverOrganizationMetrics","discoverOrganizationTeamMetrics","discoverEnterpriseMetrics","discoverEnterpriseTeamMetrics"],"mappings":";;;;;;;;;AA+BA,MAAqB,cAAe,CAAA;AAAA,EAGlC,YAA6B,OAAsB,EAAA;AAAtB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AAC3B,IAAA,IAAA,CAAK,KAAQ,GAAA;AAAA,MACX,MAAMA,4CAA4B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C,MAAMC,oDAAgC,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAClD,MAAMC,wCAA0B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC5C,MAAMC,gDAA8B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KAClD,CAAA;AAAA,GACF;AAAA,EATiB,KAAA,CAAA;AAAA,EAWjB,OAAO,OAAO,OAAsB,EAAA;AAClC,IAAO,OAAA,IAAI,eAAe,OAAO,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,MAAM,QAAW,GAAA;AACf,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,wCAAA,EAA2C,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,MAAA,CAAA;AAAA,KAC9D,CAAA;AAEA,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,OAAM,IAAQ,KAAA;AAChD,MAAI,IAAA;AACF,QAAA,MAAM,IAAK,EAAA,CAAA;AAAA,eACJ,CAAG,EAAA;AACV,QAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,UAClB,CAAA,yCAAA,EAA4C,EAAE,OAAO,CAAA,CAAA;AAAA,SACvD,CAAA;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AAED,IAAM,MAAA,OAAA,CAAQ,IAAI,YAAY,CAAA,CAAA;AAE9B,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,kDAAA,CAAA;AAAA,KACF,CAAA;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"TaskManagement.cjs.js","sources":["../../src/task/TaskManagement.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 */\nimport { Config } from '@backstage/config';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { GithubClient } from '../client/GithubClient';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport { discoverOrganizationMetrics } from './OrganizationTask';\nimport { discoverOrganizationTeamMetrics } from './OrganizationTeamTask';\nimport { discoverEnterpriseMetrics } from './EnterpriseTask';\nimport { discoverEnterpriseTeamMetrics } from './EnterpriseTeamTask';\n\nexport type TaskOptions = {\n api: GithubClient;\n config: Config;\n logger: LoggerService;\n db: DatabaseHandler;\n};\n\nexport default class TaskManagement {\n private readonly tasks: Array<() => Promise<void>>;\n\n constructor(private readonly options: TaskOptions) {\n this.tasks = [\n () => discoverOrganizationMetrics(this.options),\n () => discoverOrganizationTeamMetrics(this.options),\n () => discoverEnterpriseMetrics(this.options),\n () => discoverEnterpriseTeamMetrics(this.options),\n ];\n }\n\n static create(options: TaskOptions) {\n return new TaskManagement(options);\n }\n\n async runAsync() {\n this.options.logger.info(\n `[TaskManagement] Starting processing of ${this.tasks.length} tasks`,\n );\n\n const taskPromises = this.tasks.map(async task => {\n try {\n await task();\n } catch (e) {\n this.options.logger.warn(\n `[TaskManagement] Failed to process task: ${e.message}`,\n );\n }\n });\n\n await Promise.all(taskPromises);\n\n this.options.logger.info(\n `[TaskManagement] Completed processing of all tasks`,\n );\n }\n}\n"],"names":["discoverOrganizationMetrics","discoverOrganizationTeamMetrics","discoverEnterpriseMetrics","discoverEnterpriseTeamMetrics"],"mappings":";;;;;;;;;AA+BA,MAAqB,cAAe,CAAA;AAAA,EAGlC,YAA6B,OAAsB,EAAA;AAAtB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAC3B,IAAA,IAAA,CAAK,KAAQ,GAAA;AAAA,MACX,MAAMA,4CAA4B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C,MAAMC,oDAAgC,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAClD,MAAMC,wCAA0B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC5C,MAAMC,gDAA8B,CAAA,IAAA,CAAK,OAAO;AAAA,KAClD;AAAA;AACF,EATiB,KAAA;AAAA,EAWjB,OAAO,OAAO,OAAsB,EAAA;AAClC,IAAO,OAAA,IAAI,eAAe,OAAO,CAAA;AAAA;AACnC,EAEA,MAAM,QAAW,GAAA;AACf,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,wCAAA,EAA2C,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,MAAA;AAAA,KAC9D;AAEA,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,OAAM,IAAQ,KAAA;AAChD,MAAI,IAAA;AACF,QAAA,MAAM,IAAK,EAAA;AAAA,eACJ,CAAG,EAAA;AACV,QAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,UAClB,CAAA,yCAAA,EAA4C,EAAE,OAAO,CAAA;AAAA,SACvD;AAAA;AACF,KACD,CAAA;AAED,IAAM,MAAA,OAAA,CAAQ,IAAI,YAAY,CAAA;AAE9B,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,kDAAA;AAAA,KACF;AAAA;AAEJ;;;;"}
@@ -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 { GithubCredentials, ScmIntegrations } from '@backstage/integration';\n\nexport type GithubInfo = {\n credentials: GithubCredentials;\n apiBaseUrl: string;\n enterprise?: string;\n organization?: string;\n};\n\nexport const getGithubInfo = async (config: Config): Promise<GithubInfo> => {\n const integrations = ScmIntegrations.fromConfig(config);\n\n const host = config.getString('copilot.host');\n const enterprise = config.getOptionalString('copilot.enterprise');\n const organization = config.getOptionalString('copilot.organization');\n\n if (!host) {\n throw new Error('The host configuration is missing from the config.');\n }\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 apiBaseUrl = githubConfig.apiBaseUrl ?? 'https://api.github.com';\n\n const credentials: GithubCredentials = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n\n return {\n apiBaseUrl,\n credentials,\n enterprise,\n organization,\n };\n};\n"],"names":["ScmIntegrations"],"mappings":";;;;AA0Ba,MAAA,aAAA,GAAgB,OAAO,MAAwC,KAAA;AAC1E,EAAM,MAAA,YAAA,GAAeA,2BAAgB,CAAA,UAAA,CAAW,MAAM,CAAA,CAAA;AAEtD,EAAM,MAAA,IAAA,GAAO,MAAO,CAAA,SAAA,CAAU,cAAc,CAAA,CAAA;AAC5C,EAAM,MAAA,UAAA,GAAa,MAAO,CAAA,iBAAA,CAAkB,oBAAoB,CAAA,CAAA;AAChE,EAAM,MAAA,YAAA,GAAe,MAAO,CAAA,iBAAA,CAAkB,sBAAsB,CAAA,CAAA;AAEpE,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAM,MAAA,IAAI,MAAM,oDAAoD,CAAA,CAAA;AAAA,GACtE;AAEA,EAAA,MAAM,YAAe,GAAA,YAAA,CAAa,MAAO,CAAA,MAAA,CAAO,IAAI,CAAG,EAAA,MAAA,CAAA;AAEvD,EAAA,IAAI,CAAC,YAAc,EAAA;AACjB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,kCAAkC,IAAI,CAAA,2BAAA,CAAA;AAAA,KACxC,CAAA;AAAA,GACF;AAEA,EAAM,MAAA,UAAA,GAAa,aAAa,UAAc,IAAA,wBAAA,CAAA;AAE9C,EAAA,MAAM,WAAiC,GAAA;AAAA,IACrC,IAAM,EAAA,OAAA;AAAA,IACN,SAAS,EAAE,aAAA,EAAe,CAAU,OAAA,EAAA,YAAA,CAAa,KAAK,CAAG,CAAA,EAAA;AAAA,IACzD,OAAO,YAAa,CAAA,KAAA;AAAA,GACtB,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
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 { GithubCredentials, ScmIntegrations } from '@backstage/integration';\n\nexport type GithubInfo = {\n credentials: GithubCredentials;\n apiBaseUrl: string;\n enterprise?: string;\n organization?: string;\n};\n\nexport const getGithubInfo = async (config: Config): Promise<GithubInfo> => {\n const integrations = ScmIntegrations.fromConfig(config);\n\n const host = config.getString('copilot.host');\n const enterprise = config.getOptionalString('copilot.enterprise');\n const organization = config.getOptionalString('copilot.organization');\n\n if (!host) {\n throw new Error('The host configuration is missing from the config.');\n }\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 apiBaseUrl = githubConfig.apiBaseUrl ?? 'https://api.github.com';\n\n const credentials: GithubCredentials = {\n type: 'token',\n headers: { Authorization: `Bearer ${githubConfig.token}` },\n token: githubConfig.token,\n };\n\n return {\n apiBaseUrl,\n credentials,\n enterprise,\n organization,\n };\n};\n"],"names":["ScmIntegrations"],"mappings":";;;;AA0Ba,MAAA,aAAA,GAAgB,OAAO,MAAwC,KAAA;AAC1E,EAAM,MAAA,YAAA,GAAeA,2BAAgB,CAAA,UAAA,CAAW,MAAM,CAAA;AAEtD,EAAM,MAAA,IAAA,GAAO,MAAO,CAAA,SAAA,CAAU,cAAc,CAAA;AAC5C,EAAM,MAAA,UAAA,GAAa,MAAO,CAAA,iBAAA,CAAkB,oBAAoB,CAAA;AAChE,EAAM,MAAA,YAAA,GAAe,MAAO,CAAA,iBAAA,CAAkB,sBAAsB,CAAA;AAEpE,EAAA,IAAI,CAAC,IAAM,EAAA;AACT,IAAM,MAAA,IAAI,MAAM,oDAAoD,CAAA;AAAA;AAGtE,EAAA,MAAM,YAAe,GAAA,YAAA,CAAa,MAAO,CAAA,MAAA,CAAO,IAAI,CAAG,EAAA,MAAA;AAEvD,EAAA,IAAI,CAAC,YAAc,EAAA;AACjB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,kCAAkC,IAAI,CAAA,2BAAA;AAAA,KACxC;AAAA;AAGF,EAAM,MAAA,UAAA,GAAa,aAAa,UAAc,IAAA,wBAAA;AAE9C,EAAA,MAAM,WAAiC,GAAA;AAAA,IACrC,IAAM,EAAA,OAAA;AAAA,IACN,SAAS,EAAE,aAAA,EAAe,CAAU,OAAA,EAAA,YAAA,CAAa,KAAK,CAAG,CAAA,EAAA;AAAA,IACzD,OAAO,YAAa,CAAA;AAAA,GACtB;AAEA,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"batchInsert.cjs.js","sources":["../../src/utils/batchInsert.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 */\nexport async function batchInsertInChunks<T>(\n data: T[],\n chunkSize: number,\n batchInsertFunc: (chunk: T[]) => Promise<void>,\n): Promise<void> {\n for (let i = 0; i < data.length; i += chunkSize) {\n const chunk = data.slice(i, i + chunkSize);\n await batchInsertFunc(chunk);\n }\n}\n"],"names":[],"mappings":";;AAesB,eAAA,mBAAA,CACpB,IACA,EAAA,SAAA,EACA,eACe,EAAA;AACf,EAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,IAAK,CAAA,MAAA,EAAQ,KAAK,SAAW,EAAA;AAC/C,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,EAAG,IAAI,SAAS,CAAA,CAAA;AACzC,IAAA,MAAM,gBAAgB,KAAK,CAAA,CAAA;AAAA,GAC7B;AACF;;;;"}
1
+ {"version":3,"file":"batchInsert.cjs.js","sources":["../../src/utils/batchInsert.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 */\nexport async function batchInsertInChunks<T>(\n data: T[],\n chunkSize: number,\n batchInsertFunc: (chunk: T[]) => Promise<void>,\n): Promise<void> {\n for (let i = 0; i < data.length; i += chunkSize) {\n const chunk = data.slice(i, i + chunkSize);\n await batchInsertFunc(chunk);\n }\n}\n"],"names":[],"mappings":";;AAesB,eAAA,mBAAA,CACpB,IACA,EAAA,SAAA,EACA,eACe,EAAA;AACf,EAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,IAAK,CAAA,MAAA,EAAQ,KAAK,SAAW,EAAA;AAC/C,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,EAAG,IAAI,SAAS,CAAA;AACzC,IAAA,MAAM,gBAAgB,KAAK,CAAA;AAAA;AAE/B;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"metricHelpers.cjs.js","sources":["../../src/utils/metricHelpers.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 */\nimport { DateTime } from 'luxon';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport {\n Metric,\n MetricsType,\n} from '@backstage-community/plugin-copilot-common';\n\nexport function filterNewMetrics(\n metrics: Metric[],\n lastDay?: string,\n): Metric[] {\n return metrics\n .sort(\n (a, b) =>\n DateTime.fromISO(a.day).toMillis() - DateTime.fromISO(b.day).toMillis(),\n )\n .filter(metric => {\n const metricDate = DateTime.fromISO(metric.day);\n\n const lastDayDate = lastDay\n ? DateTime.fromJSDate(new Date(lastDay))\n : null;\n\n return !lastDay || (lastDayDate?.isValid && metricDate > lastDayDate);\n });\n}\n\nexport function prepareMetricsForInsert(\n metrics: Metric[],\n type: MetricsType,\n team_name?: string,\n): MetricDbRow[] {\n return metrics.map(({ breakdown, ...rest }) => ({\n ...rest,\n type,\n team_name,\n breakdown: JSON.stringify(breakdown),\n })) as MetricDbRow[];\n}\n"],"names":["DateTime"],"mappings":";;;;AAsBgB,SAAA,gBAAA,CACd,SACA,OACU,EAAA;AACV,EAAA,OAAO,OACJ,CAAA,IAAA;AAAA,IACC,CAAC,CAAA,EAAG,CACF,KAAAA,cAAA,CAAS,QAAQ,CAAE,CAAA,GAAG,CAAE,CAAA,QAAA,KAAaA,cAAS,CAAA,OAAA,CAAQ,CAAE,CAAA,GAAG,EAAE,QAAS,EAAA;AAAA,GAC1E,CACC,OAAO,CAAU,MAAA,KAAA;AAChB,IAAA,MAAM,UAAa,GAAAA,cAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,GAAG,CAAA,CAAA;AAE9C,IAAM,MAAA,WAAA,GAAc,UAChBA,cAAS,CAAA,UAAA,CAAW,IAAI,IAAK,CAAA,OAAO,CAAC,CACrC,GAAA,IAAA,CAAA;AAEJ,IAAA,OAAO,CAAC,OAAA,IAAY,WAAa,EAAA,OAAA,IAAW,UAAa,GAAA,WAAA,CAAA;AAAA,GAC1D,CAAA,CAAA;AACL,CAAA;AAEgB,SAAA,uBAAA,CACd,OACA,EAAA,IAAA,EACA,SACe,EAAA;AACf,EAAA,OAAO,QAAQ,GAAI,CAAA,CAAC,EAAE,SAAW,EAAA,GAAG,MAAY,MAAA;AAAA,IAC9C,GAAG,IAAA;AAAA,IACH,IAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,EAAW,IAAK,CAAA,SAAA,CAAU,SAAS,CAAA;AAAA,GACnC,CAAA,CAAA,CAAA;AACJ;;;;;"}
1
+ {"version":3,"file":"metricHelpers.cjs.js","sources":["../../src/utils/metricHelpers.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 */\nimport { DateTime } from 'luxon';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport {\n Metric,\n MetricsType,\n} from '@backstage-community/plugin-copilot-common';\n\nexport function filterNewMetrics(\n metrics: Metric[],\n lastDay?: string,\n): Metric[] {\n return metrics\n .sort(\n (a, b) =>\n DateTime.fromISO(a.day).toMillis() - DateTime.fromISO(b.day).toMillis(),\n )\n .filter(metric => {\n const metricDate = DateTime.fromISO(metric.day);\n\n const lastDayDate = lastDay\n ? DateTime.fromJSDate(new Date(lastDay))\n : null;\n\n return !lastDay || (lastDayDate?.isValid && metricDate > lastDayDate);\n });\n}\n\nexport function prepareMetricsForInsert(\n metrics: Metric[],\n type: MetricsType,\n team_name?: string,\n): MetricDbRow[] {\n return metrics.map(({ breakdown, ...rest }) => ({\n ...rest,\n type,\n team_name,\n breakdown: JSON.stringify(breakdown),\n })) as MetricDbRow[];\n}\n"],"names":["DateTime"],"mappings":";;;;AAsBgB,SAAA,gBAAA,CACd,SACA,OACU,EAAA;AACV,EAAA,OAAO,OACJ,CAAA,IAAA;AAAA,IACC,CAAC,CAAA,EAAG,CACF,KAAAA,cAAA,CAAS,QAAQ,CAAE,CAAA,GAAG,CAAE,CAAA,QAAA,KAAaA,cAAS,CAAA,OAAA,CAAQ,CAAE,CAAA,GAAG,EAAE,QAAS;AAAA,GAC1E,CACC,OAAO,CAAU,MAAA,KAAA;AAChB,IAAA,MAAM,UAAa,GAAAA,cAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,GAAG,CAAA;AAE9C,IAAM,MAAA,WAAA,GAAc,UAChBA,cAAS,CAAA,UAAA,CAAW,IAAI,IAAK,CAAA,OAAO,CAAC,CACrC,GAAA,IAAA;AAEJ,IAAA,OAAO,CAAC,OAAA,IAAY,WAAa,EAAA,OAAA,IAAW,UAAa,GAAA,WAAA;AAAA,GAC1D,CAAA;AACL;AAEgB,SAAA,uBAAA,CACd,OACA,EAAA,IAAA,EACA,SACe,EAAA;AACf,EAAA,OAAO,QAAQ,GAAI,CAAA,CAAC,EAAE,SAAW,EAAA,GAAG,MAAY,MAAA;AAAA,IAC9C,GAAG,IAAA;AAAA,IACH,IAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,EAAW,IAAK,CAAA,SAAA,CAAU,SAAS;AAAA,GACnC,CAAA,CAAA;AACJ;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-copilot-backend",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "homepage": "https://backstage.io",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.cjs.js",
@@ -39,14 +39,14 @@
39
39
  "postpack": "backstage-cli package postpack"
40
40
  },
41
41
  "dependencies": {
42
- "@backstage-community/plugin-copilot-common": "^0.3.0",
43
- "@backstage/backend-app-api": "^1.0.1",
44
- "@backstage/backend-defaults": "^0.5.2",
45
- "@backstage/backend-plugin-api": "^1.0.1",
42
+ "@backstage-community/plugin-copilot-common": "^0.4.0",
43
+ "@backstage/backend-app-api": "^1.1.0",
44
+ "@backstage/backend-defaults": "^0.6.2",
45
+ "@backstage/backend-plugin-api": "^1.1.0",
46
46
  "@backstage/backend-tasks": "^0.6.1",
47
- "@backstage/config": "^1.2.0",
48
- "@backstage/errors": "^1.2.4",
49
- "@backstage/integration": "^1.15.1",
47
+ "@backstage/config": "^1.3.1",
48
+ "@backstage/errors": "^1.2.6",
49
+ "@backstage/integration": "^1.16.0",
50
50
  "@types/express": "*",
51
51
  "express": "^4.17.1",
52
52
  "express-promise-router": "^4.1.0",
@@ -58,15 +58,22 @@
58
58
  "zod": "^3.23.8"
59
59
  },
60
60
  "devDependencies": {
61
- "@backstage/backend-test-utils": "^1.0.2",
62
- "@backstage/cli": "^0.28.0",
63
- "@backstage/plugin-auth-backend": "^0.23.1",
64
- "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.1",
65
- "@backstage/test-utils": "^1.7.0",
61
+ "@backstage/backend-test-utils": "^1.2.0",
62
+ "@backstage/cli": "^0.29.4",
63
+ "@backstage/plugin-auth-backend": "^0.24.1",
64
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.3",
65
+ "@backstage/test-utils": "^1.7.3",
66
66
  "@types/node-fetch": "^2.6.11",
67
67
  "@types/supertest": "^2.0.8",
68
68
  "msw": "^1.0.0",
69
69
  "supertest": "^6.2.4"
70
70
  },
71
- "configSchema": "config.d.ts"
71
+ "configSchema": "config.d.ts",
72
+ "typesVersions": {
73
+ "*": {
74
+ "index": [
75
+ "dist/index.d.ts"
76
+ ]
77
+ }
78
+ }
72
79
  }