@spotify/backstage-plugin-search-backend-module-skill-exchange 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @spotify/backstage-plugin-search-backend-module-skill-exchange
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Upgraded Backstage to v1.29.1
8
+ - Updated dependencies
9
+ - @spotify/backstage-plugin-skill-exchange-common@0.1.3
10
+ - @spotify/backstage-plugin-skill-exchange-node@0.1.4
11
+
12
+ ## 0.1.4
13
+
14
+ ### Patch Changes
15
+
16
+ - Added additional plugin metadata to `package.json`.
17
+ - Upgraded Backstage to v1.28.2
18
+ - Updated dependencies
19
+ - @spotify/backstage-plugin-skill-exchange-node@0.1.3
20
+ - @spotify/backstage-plugin-skill-exchange-common@0.1.2
21
+
3
22
  ## 0.1.3
4
23
 
5
24
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var L=require("@backstage/backend-common"),d=require("@backstage/backend-plugin-api"),J=require("@backstage/plugin-catalog-node/alpha"),G=require("@backstage/plugin-search-backend-node/alpha"),U=require("@backstage/catalog-model"),H=require("@backstage/plugin-search-backend-node"),K=require("@spotify/backstage-plugin-skill-exchange-node"),j=(a,e,t)=>{if(!e.has(a))throw TypeError("Cannot "+t)},r=(a,e,t)=>(j(a,e,"read from private field"),t?t.call(a):e.get(a)),l=(a,e,t)=>{if(e.has(a))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(a):e.set(a,t)},c=(a,e,t,i)=>(j(a,e,"write to private field"),i?i.call(a,t):e.set(a,t),t),Q=(a,e,t,i)=>({set _(o){c(a,e,o,t)},get _(){return r(a,e,i)}}),V=(a,e,t)=>(j(a,e,"access private method"),t),g,w,b,P,m,S,u,N,B,_;const I=class extends H.DecoratorBase{constructor({cacheClient:e,catalogClient:t,logger:i,skillExchangeClient:o,auth:n}){super(),l(this,B),l(this,g,void 0),l(this,w,void 0),l(this,b,void 0),l(this,P,void 0),l(this,m,void 0),l(this,S,0),l(this,u,void 0),c(this,w,e),c(this,g,i),c(this,b,t),c(this,P,o),c(this,m,n)}async initialize(){c(this,S,0),c(this,u,await V(this,B,_).call(this)),r(this,g).info(`Found ${Object.keys(r(this,u)).length} skill profiles available for decorating`)}async getUserEntity(e){const t=`SkillProfileDecorator:${e}`,i=await r(this,w).get(t),{token:o}=await r(this,m).getPluginRequestToken({onBehalfOf:await r(this,m).getOwnServiceCredentials(),targetPluginId:"catalog"});if(i)return i;const n=await r(this,b).getEntityByRef(e,{token:o}).catch(h=>{r(this,g).error(`Error while retrieving entity with ref: ${e}`,h)});if(n)return await r(this,w).set(t,JSON.parse(JSON.stringify(n))),n}async decorate(e){var t,i,o,n,h,v,M;if(!r(this,u)||e.kind!=="User")return e;const C=((t=e.authorization)==null?void 0:t.resourceRef)||U.stringifyEntityRef({namespace:e.namespace,kind:e.kind,name:e.location.split("/").at(-1)}),y=await this.getUserEntity(C);if(!C||!y)return r(this,g).error(`Could not find user entity to decorate, skipping over this document ${C}`),e;const T=(o=(i=r(this,u)[C.toLowerCase()])==null?void 0:i.map(({name:s})=>s))!=null?o:[],E=(h=(n=y.relations)==null?void 0:n.filter(({type:s})=>s==="memberOf"))==null?void 0:h.map(({targetRef:s})=>U.parseEntityRef(s)).filter(({kind:s})=>s==="group").map(({name:s})=>s),W=[];return e.text&&W.push(e.text),T.length&&W.push(T.join(", ")),E!=null&&E.length&&W.push(E.join(", ")),e.text=W.join(" || "),e.displayName=(v=y.spec.profile)==null?void 0:v.displayName,e.picture=(M=y.spec.profile)==null?void 0:M.picture,e.name=y.metadata.name,e.skills=T,e.teams=E||[],Q(this,S)._++,e}async finalize(){c(this,u,void 0),r(this,g).info(`Decorated ${r(this,S)} documents with skill profile data`)}};g=new WeakMap,w=new WeakMap,b=new WeakMap,P=new WeakMap,m=new WeakMap,S=new WeakMap,u=new WeakMap,N=new WeakMap,B=new WeakSet,_=async function(){var a;const e=await r(this,P).doPost("/graphql",{query:r(I,N)});let t={};return e.ok?t=(((a=(await e.json()).data)==null?void 0:a.getPublicSelfReportedSkill)||[]).reduce((i,{user:o,skill:n})=>({...i,[o.toLowerCase()]:[...i[o.toLowerCase()]||[],n]}),t):r(this,g).error(`Error fetching self reported skills: ${await e.text()}`),t},l(I,N,`
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var g=require("@backstage/backend-common"),n=require("@backstage/backend-plugin-api"),f=require("@backstage/plugin-catalog-node/alpha"),p=require("@backstage/plugin-search-backend-node/alpha"),h=require("@backstage/catalog-model"),k=require("@backstage/plugin-search-backend-node"),y=require("@spotify/backstage-plugin-skill-exchange-node");class c extends k.DecoratorBase{#e;#t;#a;#s;#i;#r=0;#o;static#n=`
2
2
  query SelfReportedSkills {
3
3
  getPublicSelfReportedSkill {
4
4
  skill {
@@ -9,5 +9,5 @@
9
9
  user
10
10
  }
11
11
  }
12
- `);let X=I;var Y=Object.defineProperty,Z=(a,e,t)=>e in a?Y(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t,z=(a,e,t)=>(Z(a,typeof e!="symbol"?e+"":e,t),t),A=(a,e,t)=>{if(!e.has(a))throw TypeError("Cannot "+t)},p=(a,e,t)=>(A(a,e,"read from private field"),t?t.call(a):e.get(a)),f=(a,e,t)=>{if(e.has(a))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(a):e.set(a,t)},k=(a,e,t,i)=>(A(a,e,"write to private field"),i?i.call(a,t):e.set(a,t),t),x,$,R,q,D,O;const ee=class F{constructor({cache:e,config:t,logger:i,discovery:o,tokenManager:n,catalog:h,auth:v}){z(this,"types",["software-catalog"]),f(this,x,void 0),f(this,$,void 0),f(this,R,void 0),f(this,q,void 0),f(this,D,void 0),f(this,O,void 0),z(this,"discovery"),k(this,$,i),this.discovery=o,k(this,x,e.getClient({defaultTtl:60*60*1e3})),k(this,R,h),k(this,q,new K.SkillExchangeClient({config:t,discovery:o,tokenManager:n})),k(this,D,n),k(this,O,v)}static fromConfig(e,t){return new F({config:e,...t})}async getDecorator(){return new X({cacheClient:p(this,x),catalogClient:p(this,R),logger:p(this,$),skillExchangeClient:p(this,q),tokenManager:p(this,D),auth:p(this,O)})}};x=new WeakMap,$=new WeakMap,R=new WeakMap,q=new WeakMap,D=new WeakMap,O=new WeakMap;let te=ee;const ae=d.createBackendModule({pluginId:"search",moduleId:"skill-exchange",register(a){a.registerInit({deps:{config:d.coreServices.rootConfig,cache:d.coreServices.cache,discovery:d.coreServices.discovery,logger:d.coreServices.logger,tokenManager:d.coreServices.tokenManager,envScheduler:d.coreServices.scheduler,auth:d.coreServices.auth,catalog:J.catalogServiceRef,registry:G.searchIndexRegistryExtensionPoint},async init({registry:e,config:t,cache:i,discovery:o,logger:n,tokenManager:h,catalog:v,auth:M}){e.addDecorator({factory:te.fromConfig(t,{catalog:v,discovery:o,auth:M,tokenManager:h,logger:L.loggerToWinstonLogger(n),cache:L.cacheToPluginCacheManager(i)})})}})}});exports.default=ae;
12
+ `;constructor({cacheClient:e,catalogClient:t,logger:i,skillExchangeClient:a,auth:r}){super(),this.#t=e,this.#e=i,this.#a=t,this.#s=a,this.#i=r}async#c(){const e=await this.#s.doPost("/graphql",{query:c.#n});let t={};return e.ok?t=((await e.json()).data?.getPublicSelfReportedSkill||[]).reduce((i,{user:a,skill:r})=>({...i,[a.toLowerCase()]:[...i[a.toLowerCase()]||[],r]}),t):this.#e.error(`Error fetching self reported skills: ${await e.text()}`),t}async initialize(){this.#r=0,this.#o=await this.#c(),this.#e.info(`Found ${Object.keys(this.#o).length} skill profiles available for decorating`)}async getUserEntity(e){const t=`SkillProfileDecorator:${e}`,i=await this.#t.get(t),{token:a}=await this.#i.getPluginRequestToken({onBehalfOf:await this.#i.getOwnServiceCredentials(),targetPluginId:"catalog"});if(i)return i;const r=await this.#a.getEntityByRef(e,{token:a}).catch(o=>{this.#e.error(`Error while retrieving entity with ref: ${e}`,o)});if(r)return await this.#t.set(t,JSON.parse(JSON.stringify(r))),r}async decorate(e){if(!this.#o||e.kind!=="User")return e;const t=e.authorization?.resourceRef||h.stringifyEntityRef({namespace:e.namespace,kind:e.kind,name:e.location.split("/").at(-1)}),i=await this.getUserEntity(t);if(!t||!i)return this.#e.error(`Could not find user entity to decorate, skipping over this document ${t}`),e;const a=this.#o[t.toLowerCase()]?.map(({name:s})=>s)??[],r=i.relations?.filter(({type:s})=>s==="memberOf")?.map(({targetRef:s})=>h.parseEntityRef(s)).filter(({kind:s})=>s==="group").map(({name:s})=>s),o=[];return e.text&&o.push(e.text),a.length&&o.push(a.join(", ")),r?.length&&o.push(r.join(", ")),e.text=o.join(" || "),e.displayName=i.spec.profile?.displayName,e.picture=i.spec.profile?.picture,e.name=i.metadata.name,e.skills=a,e.teams=r||[],this.#r++,e}async finalize(){this.#o=void 0,this.#e.info(`Decorated ${this.#r} documents with skill profile data`)}}class l{types=["software-catalog"];#e;#t;#a;#s;#i;#r;discovery;static fromConfig(e,t){return new l({config:e,...t})}constructor({cache:e,config:t,logger:i,discovery:a,tokenManager:r,catalog:o,auth:s}){this.#t=i,this.discovery=a,this.#e=e.getClient({defaultTtl:60*60*1e3}),this.#a=o,this.#s=new y.SkillExchangeClient({config:t,discovery:a,tokenManager:r}),this.#i=r,this.#r=s}async getDecorator(){return new c({cacheClient:this.#e,catalogClient:this.#a,logger:this.#t,skillExchangeClient:this.#s,tokenManager:this.#i,auth:this.#r})}}const v=n.createBackendModule({pluginId:"search",moduleId:"skill-exchange",register(u){u.registerInit({deps:{config:n.coreServices.rootConfig,cache:n.coreServices.cache,discovery:n.coreServices.discovery,logger:n.coreServices.logger,tokenManager:n.coreServices.tokenManager,envScheduler:n.coreServices.scheduler,auth:n.coreServices.auth,catalog:f.catalogServiceRef,registry:p.searchIndexRegistryExtensionPoint},async init({registry:e,config:t,cache:i,discovery:a,logger:r,tokenManager:o,catalog:s,auth:d}){e.addDecorator({factory:l.fromConfig(t,{catalog:s,discovery:a,auth:d,tokenManager:o,logger:g.loggerToWinstonLogger(r),cache:g.cacheToPluginCacheManager(i)})})}})}});exports.default=v;
13
13
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
2
 
3
3
  /** @public */
4
- declare const searchModuleSkillExchange: () => _backstage_backend_plugin_api.BackendFeature;
4
+ declare const searchModuleSkillExchange: _backstage_backend_plugin_api.BackendFeatureCompat;
5
5
 
6
6
  export { searchModuleSkillExchange as default };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-search-backend-module-skill-exchange",
3
3
  "description": "The skill-exchange backend module for the search plugin.",
4
- "version": "0.1.3",
4
+ "version": "0.1.5",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "homepage": "https://backstage.spotify.com",
7
7
  "main": "dist/index.cjs.js",
@@ -11,7 +11,9 @@
11
11
  "types": "dist/index.d.ts"
12
12
  },
13
13
  "backstage": {
14
- "role": "backend-plugin-module"
14
+ "role": "backend-plugin-module",
15
+ "pluginId": "search",
16
+ "pluginPackage": "@backstage/plugin-search-backend"
15
17
  },
16
18
  "scripts": {
17
19
  "start": "backstage-cli package start",
@@ -23,21 +25,21 @@
23
25
  "postpack": "backstage-cli package postpack"
24
26
  },
25
27
  "dependencies": {
26
- "@backstage/backend-common": "^0.22.0",
27
- "@backstage/backend-plugin-api": "^0.6.18",
28
+ "@backstage/backend-common": "^0.23.3",
29
+ "@backstage/backend-plugin-api": "^0.7.0",
28
30
  "@backstage/catalog-client": "^1.6.5",
29
31
  "@backstage/catalog-model": "^1.5.0",
30
32
  "@backstage/config": "^1.2.0",
31
- "@backstage/plugin-catalog-node": "^1.12.0",
32
- "@backstage/plugin-search-backend-node": "^1.2.22",
33
- "@backstage/plugin-search-common": "^1.2.11",
34
- "@spotify/backstage-plugin-skill-exchange-common": "^0.1.1",
35
- "@spotify/backstage-plugin-skill-exchange-node": "^0.1.2",
33
+ "@backstage/plugin-catalog-node": "^1.12.4",
34
+ "@backstage/plugin-search-backend-node": "^1.2.27",
35
+ "@backstage/plugin-search-common": "^1.2.13",
36
+ "@spotify/backstage-plugin-skill-exchange-common": "^0.1.3",
37
+ "@spotify/backstage-plugin-skill-exchange-node": "^0.1.4",
36
38
  "winston": "^3.2.1"
37
39
  },
38
40
  "devDependencies": {
39
- "@backstage/backend-test-utils": "^0.3.8",
40
- "@backstage/cli": "^0.26.5",
41
+ "@backstage/backend-test-utils": "^0.4.4",
42
+ "@backstage/cli": "^0.26.11",
41
43
  "node-fetch": "^2.6.7"
42
44
  },
43
45
  "files": [