@graphql-hive/cli
Version:
A CLI util to manage and control your GraphQL Hive
139 lines • 4.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Config = exports.graphqlEndpoint = void 0;
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const path_1 = tslib_1.__importDefault(require("path"));
const zod_1 = require("zod");
const errors_1 = require("./errors");
const LegacyConfigModel = zod_1.z.object({
registry: zod_1.z.string().optional(),
token: zod_1.z.string().optional(),
});
const ConfigModel = zod_1.z.object({
registry: zod_1.z
.object({
endpoint: zod_1.z.string().url().optional(),
accessToken: zod_1.z.string().optional(),
headers: zod_1.z.record(zod_1.z.string()).optional(),
})
.optional(),
cdn: zod_1.z
.object({
endpoint: zod_1.z.string().url().optional(),
accessToken: zod_1.z.string().optional(),
})
.optional(),
});
exports.graphqlEndpoint = 'https://app.graphql-hive.com/graphql';
class Config {
constructor({ filepath, rootDir }) {
this.isExplicitFilepath = !!filepath;
if (filepath) {
this.filepath = filepath;
}
else {
this.filepath = path_1.default.join(rootDir, 'hive.json');
}
}
get(key) {
const map = this.read();
const parts = key.split('.');
let current = map;
for (const part of parts) {
if (current == null) {
return null;
}
current = current[part];
}
return current;
}
readSpace(content) {
// eslint-disable-next-line no-process-env
const space = process.env.HIVE_SPACE;
if (!content || typeof content !== 'object' || Array.isArray(content)) {
throw new errors_1.InvalidConfigError(this.filepath, 'Expected a JSON object.');
}
if (space) {
if (!(space in content)) {
throw new errors_1.InvalidConfigError(this.filepath, `The space "${space}" set with HIVE_SPACE does not exist.`);
}
return content[space];
}
if ('default' in content) {
return content['default'];
}
return content;
}
read() {
if (this.cache) {
return this.cache;
}
let rawContent;
try {
rawContent = fs_1.default.readFileSync(this.filepath, 'utf-8');
}
catch (error) {
if ((error === null || error === void 0 ? void 0 : error.code) === 'ENOENT' && !this.isExplicitFilepath) {
this.cache = emptyConfig();
return this.cache;
}
throw new errors_1.InvalidConfigError(this.filepath, error instanceof Error ? error.message : String(error));
}
let content;
try {
content = JSON.parse(rawContent);
}
catch (error) {
throw new errors_1.InvalidConfigError(this.filepath, `Invalid JSON. ${error instanceof Error ? error.message : String(error)}`);
}
const space = this.readSpace(content);
if (isLegacyConfig(space)) {
const legacyConfig = LegacyConfigModel.safeParse(space);
if (!legacyConfig.success) {
throw new errors_1.InvalidConfigError(this.filepath, formatConfigIssues(legacyConfig.error));
}
this.cache = Object.assign(Object.assign({}, emptyConfig()), { registry: {
endpoint: legacyConfig.data.registry,
accessToken: legacyConfig.data.token,
headers: undefined,
} });
return this.cache;
}
const config = ConfigModel.safeParse(space);
if (!config.success) {
throw new errors_1.InvalidConfigError(this.filepath, formatConfigIssues(config.error));
}
this.cache = config.data;
return this.cache;
}
}
exports.Config = Config;
function emptyConfig() {
return {
registry: {
endpoint: undefined,
accessToken: undefined,
headers: undefined,
},
cdn: {
endpoint: undefined,
accessToken: undefined,
},
};
}
/** The legacy format uses top-level "registry" (string) and "token" keys. */
function isLegacyConfig(content) {
if (!content || typeof content !== 'object') {
return false;
}
const { registry } = content;
return (typeof registry === 'string' ||
('token' in content && (registry === undefined || registry === null)));
}
function formatConfigIssues(error) {
return error.issues
.map(issue => `${issue.path.length ? `"${issue.path.join('.')}": ` : ''}${issue.message}`)
.join('; ');
}
//# sourceMappingURL=config.js.map