@backstage/backend-defaults
Version:
Backend defaults used by Backstage backend apps
157 lines (150 loc) • 4.86 kB
JavaScript
;
var GoogleCloud = require('@google-cloud/storage');
var getRawBody = require('raw-body');
var integration = require('@backstage/integration');
var ReadUrlResponseFactory = require('./ReadUrlResponseFactory.cjs.js');
var _package = require('../../../package.json.cjs.js');
var errors = require('@backstage/errors');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
function _interopNamespaceCompat(e) {
if (e && typeof e === 'object' && 'default' in e) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var GoogleCloud__namespace = /*#__PURE__*/_interopNamespaceCompat(GoogleCloud);
var getRawBody__default = /*#__PURE__*/_interopDefaultCompat(getRawBody);
const GOOGLE_GCS_HOST = "storage.cloud.google.com";
const parseURL = (url) => {
const { host, pathname } = new URL(url);
if (host !== GOOGLE_GCS_HOST) {
throw new Error(`not a valid GCS URL: ${url}`);
}
const [, bucket, ...key] = pathname.split("/");
return {
host,
bucket,
key: key.join("/")
};
};
class GoogleGcsUrlReader {
static factory = ({ config, logger }) => {
if (!config.has("integrations.googleGcs")) {
return [];
}
const gcsConfig = integration.readGoogleGcsIntegrationConfig(
config.getConfig("integrations.googleGcs")
);
let storage;
if (!gcsConfig.clientEmail || !gcsConfig.privateKey) {
logger.info(
"googleGcs credentials not found in config. Using default credentials provider."
);
storage = new GoogleCloud__namespace.Storage({
userAgent: `backstage/backend-defaults.GoogleGcsUrlReader/${_package.default.version}`
});
} else {
storage = new GoogleCloud__namespace.Storage({
credentials: {
client_email: gcsConfig.clientEmail || void 0,
private_key: gcsConfig.privateKey || void 0
},
userAgent: `backstage/backend-defaults.GoogleGcsUrlReader/${_package.default.version}`
});
}
const reader = new GoogleGcsUrlReader(gcsConfig, storage);
const predicate = (url) => url.host === GOOGLE_GCS_HOST;
return [{ reader, predicate }];
};
integration;
storage;
constructor(integration, storage) {
this.integration = integration;
this.storage = storage;
}
readStreamFromUrl(url) {
const { bucket, key } = parseURL(url);
return this.storage.bucket(bucket).file(key).createReadStream();
}
async read(url) {
try {
return await getRawBody__default.default(this.readStreamFromUrl(url));
} catch (error) {
throw new Error(`unable to read gcs file from ${url}, ${error}`);
}
}
async readUrl(url, _options) {
const stream = this.readStreamFromUrl(url);
return ReadUrlResponseFactory.ReadUrlResponseFactory.fromReadable(stream);
}
async readTree() {
throw new Error("GcsUrlReader does not implement readTree");
}
async search(url, options) {
const { bucket, key: pattern } = parseURL(url);
if (!pattern?.match(/[*?]/)) {
try {
const data = await this.readUrl(url, options);
return {
files: [
{
url,
content: data.buffer,
lastModifiedAt: data.lastModifiedAt
}
],
etag: data.etag ?? ""
};
} catch (error) {
errors.assertError(error);
if (error.name === "NotFoundError") {
return {
files: [],
etag: ""
};
}
throw error;
}
}
if (!pattern.endsWith("*") || pattern.indexOf("*") !== pattern.length - 1) {
throw new Error("GcsUrlReader only supports prefix-based searches");
}
const [files] = await this.storage.bucket(bucket).getFiles({
autoPaginate: true,
prefix: pattern.split("*").join("")
});
return {
files: files.map((file) => {
const fullUrl = ["https:/", GOOGLE_GCS_HOST, bucket, file.name].join(
"/"
);
return {
url: fullUrl,
content: async () => {
const readResponse = await this.readUrl(fullUrl);
return readResponse.buffer();
}
};
}),
// TODO etag is not implemented yet.
etag: "NOT/IMPLEMENTED"
};
}
toString() {
const key = this.integration.privateKey;
return `googleGcs{host=${GOOGLE_GCS_HOST},authed=${Boolean(key)}}`;
}
}
exports.GoogleGcsUrlReader = GoogleGcsUrlReader;
//# sourceMappingURL=GoogleGcsUrlReader.cjs.js.map