armpit
Version:
Another resource manager programming interface toolkit.
141 lines • 5.42 kB
JavaScript
import { $ as Execa$ } from "execa";
;
function isExecaResult(value) {
return !!(value && (value.command || value.stdout || value.stderr));
}
function ensureAzPrefix(templates) {
if (templates.length > 0 && !/^\s*az\s/i.test(templates[0])) {
const [firstCookedTemplate, ...remainingCookedTemplates] = templates;
const [firstRawTemplate, ...remainingRawTemplates] = templates.raw;
templates = Object.assign([`az ${firstCookedTemplate}`, ...remainingCookedTemplates], {
raw: [`az ${firstRawTemplate}`, ...remainingRawTemplates]
});
}
return templates;
}
function extractWrappedResponsePropertyName(response) {
let propName = null;
for (const key in response) {
if (Object.hasOwn(response, key)) {
if (propName == null) {
propName = key;
}
else {
// If there are multiple properties then it doesn't fit the shape of a wrapped response
return null;
}
}
}
if (propName) {
// Some create responses have {NewX:{}} or {newX:{}} wrappers
// around the actual response. This will detect if the
if (/^[Nn]ew[A-Za-z]+$/.test(propName)) {
return propName;
}
if (propName === "publicIp") {
return propName;
}
}
return null;
}
export function execaAzCliInvokerFactory(options) {
const env = {
...options.env,
AZURE_CORE_OUTPUT: "json", // request json by default
AZURE_CORE_ONLY_SHOW_ERRORS: "true", // the tools aren't always consistent so this is just simpler
AZURE_CORE_NO_COLOR: "true", // hopefully this reduces some noise in stderr and stdout
AZURE_CORE_LOGIN_EXPERIENCE_V2: "off", // these tools have their own way to select accounts
};
if (options.defaultResourceGroup != null) {
env.AZURE_DEFAULTS_GROUP = options.defaultResourceGroup;
}
if (options.defaultLocation != null) {
env.AZURE_DEFAULTS_LOCATION = options.defaultLocation;
}
const execaInvoker = Execa$({
env,
});
const invokerFnBuilder = (fnOptions) => {
return async (templates, ...expressions) => {
if (options.forceAzCommandPrefix) {
templates = ensureAzPrefix(templates);
}
// Expressions of nullish values are converted to Execa template expressions.
// Expressions with toString are converted to strings when needed.
function cleanExpression(e) {
if (e == null) {
return "";
}
switch (typeof e) {
case "number":
case "string":
return e;
case "object":
default:
if (Array.isArray(e)) {
return e.map(cleanExpression);
}
if (isExecaResult(e)) {
return e;
}
if (typeof e.toString === "function") {
return e.toString();
}
return e;
}
}
;
const execaExpressions = expressions.map(cleanExpression);
let invocationResult;
try {
invocationResult = await execaInvoker(templates, ...execaExpressions);
}
catch (invocationError) {
if (fnOptions.laxResultHandling) {
const stderr = invocationError?.stderr;
if (stderr && typeof stderr === "string" && /not\s*found/i.test(stderr)) {
return null;
}
}
throw invocationError;
}
const { stdout, stderr } = invocationResult;
if (stderr != null && stderr !== "") {
console.warn(stderr);
}
if (stdout == null || stdout === "") {
return null; // even for lax rules because what else should be done with a blank response from delete for example.
}
else if (typeof stdout === "string") {
return parseJson(stdout);
}
else if (Array.isArray(stdout)) {
return parseJson(stdout.join(""));
}
else {
throw new Error("Failed to parse invocation result");
}
function parseJson(value) {
if (value == null || value === "") {
return null; // empty result
}
let result = JSON.parse(value);
if (fnOptions.unwrapNewResults) {
const wrappedPropName = extractWrappedResponsePropertyName(result);
if (wrappedPropName != null) {
result = result[wrappedPropName];
}
}
return result;
}
};
};
const baseInvokerOptions = {
unwrapNewResults: true,
};
return {
strict: invokerFnBuilder({ ...baseInvokerOptions }),
lax: invokerFnBuilder({ ...baseInvokerOptions, laxResultHandling: true }),
};
}
//# sourceMappingURL=azCliUtils.js.map