@backstage/integration 2.1.0 → 2.1.1

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,11 @@
1
1
  # @backstage/integration
2
2
 
3
+ ## 2.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - a49804f: Fixed handling of GitLab URLs for instances configured with a relative base path.
8
+
3
9
  ## 2.1.0
4
10
 
5
11
  ### Minor Changes
@@ -45,7 +45,12 @@ function extractProjectPath(target, config$1) {
45
45
  let repo = url.pathname.split("/-/blob/")[0].split("/blob/")[0];
46
46
  const relativePath = config.getGitLabIntegrationRelativePath(config$1);
47
47
  if (relativePath) {
48
- repo = repo.replace(relativePath, "");
48
+ if (!repo.startsWith(`${relativePath}/`)) {
49
+ throw new Error(
50
+ `Failed extracting project path from ${url.pathname}. Url path must start with ${relativePath}/.`
51
+ );
52
+ }
53
+ repo = repo.slice(relativePath.length);
49
54
  }
50
55
  return repo.replace(/^\//, "");
51
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"core.cjs.js","sources":["../../src/gitlab/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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 getGitLabIntegrationRelativePath,\n GitLabIntegrationConfig,\n} from './config';\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://gitlab.example.com/a/b/blob/master/c.yaml\n * to: https://gitlab.com/api/v4/projects/a%2Fb/repository/files/c.yaml/raw?ref=master\n * -or-\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @param token - An optional auth token (not used in path extraction, kept for compatibility)\n * @public\n */\nexport function getGitLabFileFetchUrl(\n url: string,\n config: GitLabIntegrationConfig,\n _token?: string,\n): Promise<string> {\n // Use project path directly instead of making an API call to get project ID\n // Note: _token parameter kept for backward compatibility but not used for path extraction\n const projectPath = extractProjectPath(url, config);\n return Promise.resolve(buildProjectUrl(url, projectPath, config).toString());\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @param token - An optional auth token to use for communicating with GitLab. By default uses the integration token\n * @public\n */\nexport function getGitLabRequestOptions(\n config: GitLabIntegrationConfig,\n token?: string,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n const accessToken = token || config.token;\n if (accessToken) {\n // OAuth, Personal, Project, and Group access tokens can all be passed via\n // a bearer authorization header\n // https://docs.gitlab.com/api/rest/authentication/#personalprojectgroup-access-tokens\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n return { headers };\n}\n\n// Converts\n// from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n// to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\nfunction buildProjectUrl(\n target: string,\n projectPathOrID: string | Number,\n config: GitLabIntegrationConfig,\n): URL {\n try {\n const url = new URL(target);\n\n const branchAndFilePath = url.pathname\n .split('/blob/')\n .slice(1)\n .join('/blob/');\n const [branch, ...filePath] = branchAndFilePath.split('/');\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n const projectIdentifier = encodeURIComponent(String(projectPathOrID));\n\n url.pathname = [\n ...(relativePath ? [relativePath] : []),\n 'api/v4/projects',\n projectIdentifier,\n 'repository/files',\n encodeURIComponent(decodeURIComponent(filePath.join('/'))),\n 'raw',\n ].join('/');\n\n url.search = `?ref=${branch}`;\n\n return url;\n } catch (e) {\n throw new Error(`Incorrect url: ${target}, ${e}`);\n }\n}\n\n/**\n * Extracts the project path from a GitLab URL\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: groupA/teams/teamA/subgroupA/repoA\n */\nexport function extractProjectPath(\n target: string,\n config: GitLabIntegrationConfig,\n): string {\n const url = new URL(target);\n\n if (!url.pathname.includes('/blob/')) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must include /blob/.`,\n );\n }\n\n let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0];\n\n // Get gitlab relative path\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n // Check relative path exist and replace it if it's the case.\n if (relativePath) {\n repo = repo.replace(relativePath, '');\n }\n\n // Remove leading slash\n return repo.replace(/^\\//, '');\n}\n"],"names":["config","getGitLabIntegrationRelativePath"],"mappings":";;;;AAuCO,SAAS,qBAAA,CACd,GAAA,EACA,MAAA,EACA,MAAA,EACiB;AAGjB,EAAA,MAAM,WAAA,GAAc,kBAAA,CAAmB,GAAA,EAAK,MAAM,CAAA;AAClD,EAAA,OAAO,OAAA,CAAQ,QAAQ,eAAA,CAAgB,GAAA,EAAK,aAAa,MAAM,CAAA,CAAE,UAAU,CAAA;AAC7E;AASO,SAAS,uBAAA,CACd,QACA,KAAA,EACqC;AACrC,EAAA,MAAM,UAAkC,EAAC;AAEzC,EAAA,MAAM,WAAA,GAAc,SAAS,MAAA,CAAO,KAAA;AACpC,EAAA,IAAI,WAAA,EAAa;AAIf,IAAA,OAAA,CAAQ,aAAA,GAAgB,UAAU,WAAW,CAAA,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,EAAE,OAAA,EAAQ;AACnB;AAKA,SAAS,eAAA,CACP,MAAA,EACA,eAAA,EACAA,QAAA,EACK;AACL,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAE1B,IAAA,MAAM,iBAAA,GAAoB,GAAA,CAAI,QAAA,CAC3B,KAAA,CAAM,QAAQ,EACd,KAAA,CAAM,CAAC,CAAA,CACP,IAAA,CAAK,QAAQ,CAAA;AAChB,IAAA,MAAM,CAAC,MAAA,EAAQ,GAAG,QAAQ,CAAA,GAAI,iBAAA,CAAkB,MAAM,GAAG,CAAA;AACzD,IAAA,MAAM,YAAA,GAAeC,wCAAiCD,QAAM,CAAA;AAE5D,IAAA,MAAM,iBAAA,GAAoB,kBAAA,CAAmB,MAAA,CAAO,eAAe,CAAC,CAAA;AAEpE,IAAA,GAAA,CAAI,QAAA,GAAW;AAAA,MACb,GAAI,YAAA,GAAe,CAAC,YAAY,IAAI,EAAC;AAAA,MACrC,iBAAA;AAAA,MACA,iBAAA;AAAA,MACA,kBAAA;AAAA,MACA,mBAAmB,kBAAA,CAAmB,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAAA,MACzD;AAAA,KACF,CAAE,KAAK,GAAG,CAAA;AAEV,IAAA,GAAA,CAAI,MAAA,GAAS,QAAQ,MAAM,CAAA,CAAA;AAE3B,IAAA,OAAO,GAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,MAAM,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAClD;AACF;AAOO,SAAS,kBAAA,CACd,QACAA,QAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAE1B,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AACpC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,oCAAA,EAAuC,IAAI,QAAQ,CAAA,+BAAA;AAAA,KACrD;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,GAAO,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,CAAE,CAAC,CAAA,CAAE,KAAA,CAAM,QAAQ,CAAA,CAAE,CAAC,CAAA;AAG9D,EAAA,MAAM,YAAA,GAAeC,wCAAiCD,QAAM,CAAA;AAG5D,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAA;AAAA,EACtC;AAGA,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC/B;;;;;;"}
1
+ {"version":3,"file":"core.cjs.js","sources":["../../src/gitlab/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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 getGitLabIntegrationRelativePath,\n GitLabIntegrationConfig,\n} from './config';\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://gitlab.example.com/a/b/blob/master/c.yaml\n * to: https://gitlab.com/api/v4/projects/a%2Fb/repository/files/c.yaml/raw?ref=master\n * -or-\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @param token - An optional auth token (not used in path extraction, kept for compatibility)\n * @public\n */\nexport function getGitLabFileFetchUrl(\n url: string,\n config: GitLabIntegrationConfig,\n _token?: string,\n): Promise<string> {\n // Use project path directly instead of making an API call to get project ID\n // Note: _token parameter kept for backward compatibility but not used for path extraction\n const projectPath = extractProjectPath(url, config);\n return Promise.resolve(buildProjectUrl(url, projectPath, config).toString());\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @param token - An optional auth token to use for communicating with GitLab. By default uses the integration token\n * @public\n */\nexport function getGitLabRequestOptions(\n config: GitLabIntegrationConfig,\n token?: string,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n const accessToken = token || config.token;\n if (accessToken) {\n // OAuth, Personal, Project, and Group access tokens can all be passed via\n // a bearer authorization header\n // https://docs.gitlab.com/api/rest/authentication/#personalprojectgroup-access-tokens\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n return { headers };\n}\n\n// Converts\n// from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n// to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\nfunction buildProjectUrl(\n target: string,\n projectPathOrID: string | Number,\n config: GitLabIntegrationConfig,\n): URL {\n try {\n const url = new URL(target);\n\n const branchAndFilePath = url.pathname\n .split('/blob/')\n .slice(1)\n .join('/blob/');\n const [branch, ...filePath] = branchAndFilePath.split('/');\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n const projectIdentifier = encodeURIComponent(String(projectPathOrID));\n\n url.pathname = [\n ...(relativePath ? [relativePath] : []),\n 'api/v4/projects',\n projectIdentifier,\n 'repository/files',\n encodeURIComponent(decodeURIComponent(filePath.join('/'))),\n 'raw',\n ].join('/');\n\n url.search = `?ref=${branch}`;\n\n return url;\n } catch (e) {\n throw new Error(`Incorrect url: ${target}, ${e}`);\n }\n}\n\n/**\n * Extracts the project path from a GitLab URL\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: groupA/teams/teamA/subgroupA/repoA\n */\nexport function extractProjectPath(\n target: string,\n config: GitLabIntegrationConfig,\n): string {\n const url = new URL(target);\n\n if (!url.pathname.includes('/blob/')) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must include /blob/.`,\n );\n }\n\n let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0];\n\n // Get gitlab relative path\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n // Check relative path exists and remove it if it's the case.\n if (relativePath) {\n if (!repo.startsWith(`${relativePath}/`)) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must start with ${relativePath}/.`,\n );\n }\n repo = repo.slice(relativePath.length);\n }\n\n // Remove leading slash\n return repo.replace(/^\\//, '');\n}\n"],"names":["config","getGitLabIntegrationRelativePath"],"mappings":"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"}
@@ -43,7 +43,12 @@ function extractProjectPath(target, config) {
43
43
  let repo = url.pathname.split("/-/blob/")[0].split("/blob/")[0];
44
44
  const relativePath = getGitLabIntegrationRelativePath(config);
45
45
  if (relativePath) {
46
- repo = repo.replace(relativePath, "");
46
+ if (!repo.startsWith(`${relativePath}/`)) {
47
+ throw new Error(
48
+ `Failed extracting project path from ${url.pathname}. Url path must start with ${relativePath}/.`
49
+ );
50
+ }
51
+ repo = repo.slice(relativePath.length);
47
52
  }
48
53
  return repo.replace(/^\//, "");
49
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"core.esm.js","sources":["../../src/gitlab/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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 getGitLabIntegrationRelativePath,\n GitLabIntegrationConfig,\n} from './config';\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://gitlab.example.com/a/b/blob/master/c.yaml\n * to: https://gitlab.com/api/v4/projects/a%2Fb/repository/files/c.yaml/raw?ref=master\n * -or-\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @param token - An optional auth token (not used in path extraction, kept for compatibility)\n * @public\n */\nexport function getGitLabFileFetchUrl(\n url: string,\n config: GitLabIntegrationConfig,\n _token?: string,\n): Promise<string> {\n // Use project path directly instead of making an API call to get project ID\n // Note: _token parameter kept for backward compatibility but not used for path extraction\n const projectPath = extractProjectPath(url, config);\n return Promise.resolve(buildProjectUrl(url, projectPath, config).toString());\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @param token - An optional auth token to use for communicating with GitLab. By default uses the integration token\n * @public\n */\nexport function getGitLabRequestOptions(\n config: GitLabIntegrationConfig,\n token?: string,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n const accessToken = token || config.token;\n if (accessToken) {\n // OAuth, Personal, Project, and Group access tokens can all be passed via\n // a bearer authorization header\n // https://docs.gitlab.com/api/rest/authentication/#personalprojectgroup-access-tokens\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n return { headers };\n}\n\n// Converts\n// from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n// to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\nfunction buildProjectUrl(\n target: string,\n projectPathOrID: string | Number,\n config: GitLabIntegrationConfig,\n): URL {\n try {\n const url = new URL(target);\n\n const branchAndFilePath = url.pathname\n .split('/blob/')\n .slice(1)\n .join('/blob/');\n const [branch, ...filePath] = branchAndFilePath.split('/');\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n const projectIdentifier = encodeURIComponent(String(projectPathOrID));\n\n url.pathname = [\n ...(relativePath ? [relativePath] : []),\n 'api/v4/projects',\n projectIdentifier,\n 'repository/files',\n encodeURIComponent(decodeURIComponent(filePath.join('/'))),\n 'raw',\n ].join('/');\n\n url.search = `?ref=${branch}`;\n\n return url;\n } catch (e) {\n throw new Error(`Incorrect url: ${target}, ${e}`);\n }\n}\n\n/**\n * Extracts the project path from a GitLab URL\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: groupA/teams/teamA/subgroupA/repoA\n */\nexport function extractProjectPath(\n target: string,\n config: GitLabIntegrationConfig,\n): string {\n const url = new URL(target);\n\n if (!url.pathname.includes('/blob/')) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must include /blob/.`,\n );\n }\n\n let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0];\n\n // Get gitlab relative path\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n // Check relative path exist and replace it if it's the case.\n if (relativePath) {\n repo = repo.replace(relativePath, '');\n }\n\n // Remove leading slash\n return repo.replace(/^\\//, '');\n}\n"],"names":[],"mappings":";;AAuCO,SAAS,qBAAA,CACd,GAAA,EACA,MAAA,EACA,MAAA,EACiB;AAGjB,EAAA,MAAM,WAAA,GAAc,kBAAA,CAAmB,GAAA,EAAK,MAAM,CAAA;AAClD,EAAA,OAAO,OAAA,CAAQ,QAAQ,eAAA,CAAgB,GAAA,EAAK,aAAa,MAAM,CAAA,CAAE,UAAU,CAAA;AAC7E;AASO,SAAS,uBAAA,CACd,QACA,KAAA,EACqC;AACrC,EAAA,MAAM,UAAkC,EAAC;AAEzC,EAAA,MAAM,WAAA,GAAc,SAAS,MAAA,CAAO,KAAA;AACpC,EAAA,IAAI,WAAA,EAAa;AAIf,IAAA,OAAA,CAAQ,aAAA,GAAgB,UAAU,WAAW,CAAA,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,EAAE,OAAA,EAAQ;AACnB;AAKA,SAAS,eAAA,CACP,MAAA,EACA,eAAA,EACA,MAAA,EACK;AACL,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAE1B,IAAA,MAAM,iBAAA,GAAoB,GAAA,CAAI,QAAA,CAC3B,KAAA,CAAM,QAAQ,EACd,KAAA,CAAM,CAAC,CAAA,CACP,IAAA,CAAK,QAAQ,CAAA;AAChB,IAAA,MAAM,CAAC,MAAA,EAAQ,GAAG,QAAQ,CAAA,GAAI,iBAAA,CAAkB,MAAM,GAAG,CAAA;AACzD,IAAA,MAAM,YAAA,GAAe,iCAAiC,MAAM,CAAA;AAE5D,IAAA,MAAM,iBAAA,GAAoB,kBAAA,CAAmB,MAAA,CAAO,eAAe,CAAC,CAAA;AAEpE,IAAA,GAAA,CAAI,QAAA,GAAW;AAAA,MACb,GAAI,YAAA,GAAe,CAAC,YAAY,IAAI,EAAC;AAAA,MACrC,iBAAA;AAAA,MACA,iBAAA;AAAA,MACA,kBAAA;AAAA,MACA,mBAAmB,kBAAA,CAAmB,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAAA,MACzD;AAAA,KACF,CAAE,KAAK,GAAG,CAAA;AAEV,IAAA,GAAA,CAAI,MAAA,GAAS,QAAQ,MAAM,CAAA,CAAA;AAE3B,IAAA,OAAO,GAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,MAAM,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAClD;AACF;AAOO,SAAS,kBAAA,CACd,QACA,MAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAE1B,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,EAAG;AACpC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,oCAAA,EAAuC,IAAI,QAAQ,CAAA,+BAAA;AAAA,KACrD;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,GAAO,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,CAAE,CAAC,CAAA,CAAE,KAAA,CAAM,QAAQ,CAAA,CAAE,CAAC,CAAA;AAG9D,EAAA,MAAM,YAAA,GAAe,iCAAiC,MAAM,CAAA;AAG5D,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAA;AAAA,EACtC;AAGA,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC/B;;;;"}
1
+ {"version":3,"file":"core.esm.js","sources":["../../src/gitlab/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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 getGitLabIntegrationRelativePath,\n GitLabIntegrationConfig,\n} from './config';\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://gitlab.example.com/a/b/blob/master/c.yaml\n * to: https://gitlab.com/api/v4/projects/a%2Fb/repository/files/c.yaml/raw?ref=master\n * -or-\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @param token - An optional auth token (not used in path extraction, kept for compatibility)\n * @public\n */\nexport function getGitLabFileFetchUrl(\n url: string,\n config: GitLabIntegrationConfig,\n _token?: string,\n): Promise<string> {\n // Use project path directly instead of making an API call to get project ID\n // Note: _token parameter kept for backward compatibility but not used for path extraction\n const projectPath = extractProjectPath(url, config);\n return Promise.resolve(buildProjectUrl(url, projectPath, config).toString());\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @param token - An optional auth token to use for communicating with GitLab. By default uses the integration token\n * @public\n */\nexport function getGitLabRequestOptions(\n config: GitLabIntegrationConfig,\n token?: string,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n const accessToken = token || config.token;\n if (accessToken) {\n // OAuth, Personal, Project, and Group access tokens can all be passed via\n // a bearer authorization header\n // https://docs.gitlab.com/api/rest/authentication/#personalprojectgroup-access-tokens\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n return { headers };\n}\n\n// Converts\n// from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n// to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FteamA%2FsubgroupA%2FrepoA/repository/files/filepath/raw?ref=branch\nfunction buildProjectUrl(\n target: string,\n projectPathOrID: string | Number,\n config: GitLabIntegrationConfig,\n): URL {\n try {\n const url = new URL(target);\n\n const branchAndFilePath = url.pathname\n .split('/blob/')\n .slice(1)\n .join('/blob/');\n const [branch, ...filePath] = branchAndFilePath.split('/');\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n const projectIdentifier = encodeURIComponent(String(projectPathOrID));\n\n url.pathname = [\n ...(relativePath ? [relativePath] : []),\n 'api/v4/projects',\n projectIdentifier,\n 'repository/files',\n encodeURIComponent(decodeURIComponent(filePath.join('/'))),\n 'raw',\n ].join('/');\n\n url.search = `?ref=${branch}`;\n\n return url;\n } catch (e) {\n throw new Error(`Incorrect url: ${target}, ${e}`);\n }\n}\n\n/**\n * Extracts the project path from a GitLab URL\n * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath\n * to: groupA/teams/teamA/subgroupA/repoA\n */\nexport function extractProjectPath(\n target: string,\n config: GitLabIntegrationConfig,\n): string {\n const url = new URL(target);\n\n if (!url.pathname.includes('/blob/')) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must include /blob/.`,\n );\n }\n\n let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0];\n\n // Get gitlab relative path\n const relativePath = getGitLabIntegrationRelativePath(config);\n\n // Check relative path exists and remove it if it's the case.\n if (relativePath) {\n if (!repo.startsWith(`${relativePath}/`)) {\n throw new Error(\n `Failed extracting project path from ${url.pathname}. Url path must start with ${relativePath}/.`,\n );\n }\n repo = repo.slice(relativePath.length);\n }\n\n // Remove leading slash\n return repo.replace(/^\\//, '');\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/integration",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Helpers for managing integrations towards external systems",
5
5
  "backstage": {
6
6
  "role": "common-library"