Refactored configuration loading function.
This commit is contained in:
36
package-lock.json
generated
36
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@slawek/sk-az-tools",
|
"name": "@slawek/sk-az-tools",
|
||||||
"version": "0.4.3",
|
"version": "0.4.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
@@ -16,7 +16,9 @@
|
|||||||
"@slawek/sk-tools": ">=0.1.0",
|
"@slawek/sk-tools": ">=0.1.0",
|
||||||
"azure-devops-node-api": "^15.1.2",
|
"azure-devops-node-api": "^15.1.2",
|
||||||
"minimatch": "^10.1.2",
|
"minimatch": "^10.1.2",
|
||||||
"open": "^10.1.0"
|
"open": "^10.1.0",
|
||||||
|
"semver": "^7.7.2",
|
||||||
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"sk-az-tools": "dist/cli.js"
|
"sk-az-tools": "dist/cli.js"
|
||||||
@@ -154,6 +156,15 @@
|
|||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@azure/identity/node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@azure/logger": {
|
"node_modules/@azure/logger": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz",
|
||||||
@@ -233,6 +244,15 @@
|
|||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@azure/msal-node/node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.28.6",
|
"version": "7.28.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||||
@@ -1576,12 +1596,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "8.3.2",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/esm/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wrappy": {
|
"node_modules/wrappy": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@slawek/sk-az-tools",
|
"name": "@slawek/sk-az-tools",
|
||||||
"version": "0.4.3",
|
"version": "0.4.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
"azure-devops-node-api": "^15.1.2",
|
"azure-devops-node-api": "^15.1.2",
|
||||||
"minimatch": "^10.1.2",
|
"minimatch": "^10.1.2",
|
||||||
"open": "^10.1.0",
|
"open": "^10.1.0",
|
||||||
"semver": "^7.7.2"
|
"semver": "^7.7.2",
|
||||||
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": ">=24.0.0",
|
"@types/node": ">=24.0.0",
|
||||||
|
|||||||
1
src/cli/commands/auth.ts
Normal file
1
src/cli/commands/auth.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { acquireResourceTokenFromLogin } from "../../azure/index.ts";
|
import { acquireResourceTokenFromLogin } from "../../azure/index.ts";
|
||||||
import { getDevOpsApiToken } from "../../devops/index.ts";
|
import { getDevOpsApiToken } from "../../devops/index.ts";
|
||||||
import { loadPublicConfig } from "../../index.ts";
|
import { loadConfig } from "../../index.ts";
|
||||||
|
|
||||||
import type { CommandValues } from "./types.ts";
|
import type { CommandValues } from "./types.ts";
|
||||||
|
|
||||||
@@ -19,13 +19,7 @@ export async function runGetTokenCommand(values: CommandValues): Promise<unknown
|
|||||||
throw new Error("--type is required for get-token (allowed: azurerm, devops)");
|
throw new Error("--type is required for get-token (allowed: azurerm, devops)");
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = await loadPublicConfig();
|
const config = await loadConfig("public-config");
|
||||||
if (!config.tenantId) {
|
|
||||||
throw new Error("tenantId is required");
|
|
||||||
}
|
|
||||||
if (!config.clientId) {
|
|
||||||
throw new Error("clientId is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokenType === "azurerm") {
|
if (tokenType === "azurerm") {
|
||||||
const result = await acquireResourceTokenFromLogin({
|
const result = await acquireResourceTokenFromLogin({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { login } from "../../azure/index.ts";
|
import { login } from "../../azure/index.ts";
|
||||||
import { loadPublicConfig } from "../../index.ts";
|
import { loadConfig } from "../../index.ts";
|
||||||
|
|
||||||
import type { CommandValues } from "./types.ts";
|
import type { CommandValues } from "./types.ts";
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ Options:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function runLoginCommand(values: CommandValues): Promise<unknown> {
|
export async function runLoginCommand(values: CommandValues): Promise<unknown> {
|
||||||
const config = await loadPublicConfig();
|
const config = await loadConfig("public-config");
|
||||||
return login({
|
return login({
|
||||||
tenantId: config.tenantId,
|
tenantId: config.tenantId,
|
||||||
clientId: config.clientId,
|
clientId: config.clientId,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { logout } from "../../azure/index.ts";
|
import { logout } from "../../azure/index.ts";
|
||||||
import { loadPublicConfig } from "../../index.ts";
|
import { loadConfig } from "../../index.ts";
|
||||||
|
|
||||||
import type { CommandValues } from "./types.ts";
|
import type { CommandValues } from "./types.ts";
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ Options:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function runLogoutCommand(values: CommandValues): Promise<unknown> {
|
export async function runLogoutCommand(values: CommandValues): Promise<unknown> {
|
||||||
const config = await loadPublicConfig();
|
const config = await loadConfig("public-config");
|
||||||
return logout({
|
return logout({
|
||||||
tenantId: config.tenantId,
|
tenantId: config.tenantId,
|
||||||
clientId: config.clientId,
|
clientId: config.clientId,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { acquireResourceTokenFromLogin } from "../../azure/index.ts";
|
import { acquireResourceTokenFromLogin } from "../../azure/index.ts";
|
||||||
import { getDevOpsApiToken } from "../../devops/index.ts";
|
import { getDevOpsApiToken } from "../../devops/index.ts";
|
||||||
import { loadPublicConfig } from "../../index.ts";
|
import { loadConfig } from "../../index.ts";
|
||||||
|
|
||||||
import type { CommandValues } from "./types.ts";
|
import type { CommandValues } from "./types.ts";
|
||||||
|
|
||||||
@@ -54,13 +54,7 @@ async function getAutoAuthorizationHeader(url: URL): Promise<string | null> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = await loadPublicConfig();
|
const config = await loadConfig("public-config");
|
||||||
if (!config.tenantId) {
|
|
||||||
throw new Error("tenantId is required");
|
|
||||||
}
|
|
||||||
if (!config.clientId) {
|
|
||||||
throw new Error("clientId is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host === "management.azure.com") {
|
if (host === "management.azure.com") {
|
||||||
const result = await acquireResourceTokenFromLogin({
|
const result = await acquireResourceTokenFromLogin({
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { minimatch } from "minimatch";
|
import { minimatch } from "minimatch";
|
||||||
|
|
||||||
import { loadPublicConfig } from "../../index.ts";
|
import { loadConfig } from "../../index.ts";
|
||||||
import { getGraphClient } from "../../graph/auth.ts";
|
import { getGraphClient } from "../../graph/auth.ts";
|
||||||
|
|
||||||
type PermissionRow = {
|
type PermissionRow = {
|
||||||
@@ -28,7 +28,7 @@ export function filterByDisplayName<T extends DisplayNameRow>(rows: T[], pattern
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getGraphClientFromPublicConfig(): Promise<{ client: any }> {
|
export async function getGraphClientFromPublicConfig(): Promise<{ client: any }> {
|
||||||
const config = await loadPublicConfig();
|
const config = await loadConfig("public-config");
|
||||||
return getGraphClient({
|
return getGraphClient({
|
||||||
tenantId: config.tenantId,
|
tenantId: config.tenantId,
|
||||||
clientId: config.clientId,
|
clientId: config.clientId,
|
||||||
|
|||||||
60
src/index.ts
60
src/index.ts
@@ -1,58 +1,36 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { readFile } from "node:fs/promises";
|
import { validate as validateUuid } from "uuid";
|
||||||
import os from "node:os";
|
import { getConfig } from "@slawek/sk-tools";
|
||||||
import path from "node:path";
|
|
||||||
|
|
||||||
type Config = {
|
type Config = {
|
||||||
tenantId?: string;
|
tenantId: string;
|
||||||
clientId?: string;
|
clientId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ConfigCandidate = {
|
export async function loadConfig(configName: string): Promise<Config> {
|
||||||
tenantId?: unknown;
|
if (typeof configName !== "string" || configName.trim() === "") {
|
||||||
clientId?: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getUserConfigDir(): string {
|
|
||||||
if (process.platform === "win32") {
|
|
||||||
return process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local");
|
|
||||||
}
|
|
||||||
|
|
||||||
return process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadConfig(configFileName: string): Promise<Config> {
|
|
||||||
if (typeof configFileName !== "string" || configFileName.trim() === "") {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Invalid config file name. Expected a non-empty string like "public-config.json" or "confidential-config.json".',
|
'Invalid config name. Expected a non-empty string like "public-config" or "confidential-config".',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const envConfig: Config = {
|
const envConfig = {
|
||||||
tenantId: process.env.AZURE_TENANT_ID,
|
tenantId: process.env.AZURE_TENANT_ID,
|
||||||
clientId: process.env.AZURE_CLIENT_ID,
|
clientId: process.env.AZURE_CLIENT_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
const configPath = path.join(getUserConfigDir(), "sk-az-tools", configFileName);
|
const json = (await getConfig("sk-az-tools", configName)) as Record<string, unknown>;
|
||||||
return readFile(configPath, "utf8")
|
|
||||||
.then((configJson) => JSON.parse(configJson) as ConfigCandidate)
|
const tenantId = (typeof json.tenantId === "string" && json.tenantId ? json.tenantId : envConfig.tenantId) ?? "";
|
||||||
.catch((err: unknown) => {
|
const clientId = (typeof json.clientId === "string" && json.clientId ? json.clientId : envConfig.clientId) ?? "";
|
||||||
if ((err as { code?: string } | null)?.code === "ENOENT") {
|
|
||||||
return {} as ConfigCandidate;
|
if (!validateUuid(tenantId ?? "") || !validateUuid(clientId ?? "")) {
|
||||||
|
throw new Error("tenantId and clientId must be valid GUIDs.");
|
||||||
}
|
}
|
||||||
throw err;
|
|
||||||
})
|
|
||||||
.then((json) => ({
|
|
||||||
tenantId: typeof json.tenantId === "string" && json.tenantId ? json.tenantId : envConfig.tenantId,
|
|
||||||
clientId: typeof json.clientId === "string" && json.clientId ? json.clientId : envConfig.clientId,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function loadPublicConfig(): Promise<Config> {
|
return {
|
||||||
return loadConfig("public-config.json");
|
tenantId,
|
||||||
}
|
clientId,
|
||||||
|
};
|
||||||
export function loadConfidentialConfig(): Promise<Config> {
|
|
||||||
return loadConfig("confidential-config.json");
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user