Skip to content

Commit

Permalink
refactor: use shared util for driver errors
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed May 5, 2023
1 parent 129a935 commit 5ecca54
Show file tree
Hide file tree
Showing 21 changed files with 144 additions and 89 deletions.
14 changes: 9 additions & 5 deletions src/drivers/azure-app-configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { defineDriver, createRequiredError } from "./utils";
import { AppConfigurationClient } from "@azure/app-configuration";
import { DefaultAzureCredential } from "@azure/identity";

Expand Down Expand Up @@ -34,6 +34,8 @@ export interface AzureAppConfigurationOptions {
connectionString?: string;
}

const DRIVER_NAME = "azure-app-configuration";

export default defineDriver((opts: AzureAppConfigurationOptions = {}) => {
const labelFilter = opts.label || "\0";
const keyFilter = opts.prefix ? `${opts.prefix}:*` : "*";
Expand All @@ -46,9 +48,11 @@ export default defineDriver((opts: AzureAppConfigurationOptions = {}) => {
return client;
}
if (!opts.endpoint && !opts.appConfigName && !opts.connectionString) {
throw new Error(
"[unstorage] [azure-app-configuration] Either the `endpoint`, `appConfigName` or `connectionString` option must be provided."
);
throw createRequiredError(DRIVER_NAME, [
"endpoint",
"appConfigName",
"connectionString",
]);
}
const appConfigEndpoint =
opts.endpoint || `https://${opts.appConfigName}.azconfig.io`;
Expand All @@ -62,7 +66,7 @@ export default defineDriver((opts: AzureAppConfigurationOptions = {}) => {
};

return {
name: "azure-app-configuration",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
try {
Expand Down
10 changes: 5 additions & 5 deletions src/drivers/azure-cosmos.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { createRequiredError, defineDriver } from "./utils";
import { Container, CosmosClient } from "@azure/cosmos";
import { DefaultAzureCredential } from "@azure/identity";

Expand Down Expand Up @@ -26,6 +26,8 @@ export interface AzureCosmosOptions {
containerName?: string;
}

const DRIVER_NAME = "azure-cosmos";

export interface AzureCosmosItem {
/**
* The unstorage key as id of the item.
Expand All @@ -50,9 +52,7 @@ export default defineDriver((opts: AzureCosmosOptions) => {
return client;
}
if (!opts.endpoint) {
throw new Error(
"Azure CosmosDB driver requires an endpoint to be provided."
);
throw createRequiredError(DRIVER_NAME, "endpoint");
}
if (opts.accountKey) {
const cosmosClient = new CosmosClient({
Expand Down Expand Up @@ -84,7 +84,7 @@ export default defineDriver((opts: AzureCosmosOptions) => {
};

return {
name: "azure-cosmos",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
const item = await (await getCosmosClient())
Expand Down
14 changes: 6 additions & 8 deletions src/drivers/azure-key-vault.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { createError, createRequiredError, defineDriver } from "./utils";
import { SecretClient, SecretClientOptions } from "@azure/keyvault-secrets";
import { DefaultAzureCredential } from "@azure/identity";

Expand All @@ -21,6 +21,8 @@ export interface AzureKeyVaultOptions {
pageSize?: number;
}

const DRIVER_NAME = "azure-key-vault";

export default defineDriver((opts: AzureKeyVaultOptions) => {
let keyVaultClient: SecretClient;
const getKeyVaultClient = () => {
Expand All @@ -29,14 +31,10 @@ export default defineDriver((opts: AzureKeyVaultOptions) => {
}
const { vaultName = null, serviceVersion = "7.3", pageSize = 25 } = opts;
if (!vaultName) {
throw new Error(
"[unstorage] [key-vault] Azure Key Vault driver requires a vault name to be provided."
);
throw createRequiredError(DRIVER_NAME, "vaultName");
}
if (pageSize > 25) {
throw new Error(
"[unstorage] [key-vault] pageSize cannot be greater than 25."
);
throw createError(DRIVER_NAME, "`pageSize` cannot be greater than `25`");
}
const credential = new DefaultAzureCredential();
const url = `https://${vaultName}.vault.azure.net`;
Expand All @@ -45,7 +43,7 @@ export default defineDriver((opts: AzureKeyVaultOptions) => {
};

return {
name: "azure-key-vault",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
try {
Expand Down
10 changes: 5 additions & 5 deletions src/drivers/azure-storage-blob.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { createError, defineDriver } from "./utils";
import {
BlobServiceClient,
ContainerClient,
Expand Down Expand Up @@ -34,16 +34,16 @@ export interface AzureStorageBlobOptions {
connectionString?: string;
}

const DRIVER_NAME = "azure-storage-blob";

export default defineDriver((opts: AzureStorageBlobOptions) => {
let containerClient: ContainerClient;
const getContainerClient = () => {
if (containerClient) {
return containerClient;
}
if (!opts.accountName) {
throw new Error(
"Account name is required to use the Azure Storage Blob driver."
);
throw createError(DRIVER_NAME, "accountName");
}
let serviceClient: BlobServiceClient;
if (opts.accountKey) {
Expand Down Expand Up @@ -79,7 +79,7 @@ export default defineDriver((opts: AzureStorageBlobOptions) => {
};

return {
name: "azure-storage-blob",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
return await getContainerClient().getBlockBlobClient(key).exists();
Expand Down
15 changes: 9 additions & 6 deletions src/drivers/azure-storage-table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { createError, createRequiredError, defineDriver } from "./utils";
import {
TableClient,
AzureNamedKeyCredential,
Expand Down Expand Up @@ -46,6 +46,8 @@ export interface AzureStorageTableOptions {
pageSize?: number;
}

const DRIVER_NAME = "azure-storage-table";

export default defineDriver((opts: AzureStorageTableOptions) => {
const {
accountName = null,
Expand All @@ -63,12 +65,13 @@ export default defineDriver((opts: AzureStorageTableOptions) => {
return client;
}
if (!accountName) {
throw new Error(
"Account name is required to use the Azure Storage Table driver."
);
throw createRequiredError(DRIVER_NAME, "accountName");
}
if (pageSize > 1000) {
throw new Error("pageSize exceeds the maximum allowed value of 1000");
throw createError(
DRIVER_NAME,
"`pageSize` exceeds the maximum allowed value of `1000`"
);
}
if (accountKey) {
// AzureNamedKeyCredential is only available in Node.js runtime, not in browsers
Expand Down Expand Up @@ -100,7 +103,7 @@ export default defineDriver((opts: AzureStorageTableOptions) => {
};

return {
name: "azure-strorage-table",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
try {
Expand Down
16 changes: 10 additions & 6 deletions src/drivers/cloudflare-kv-binding.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/// <reference types="@cloudflare/workers-types" />
import { defineDriver } from "./utils";
import { createError, defineDriver } from "./utils";
export interface KVOptions {
binding?: string | KVNamespace;
}

// https://developers.cloudflare.com/workers/runtime-apis/kv

const DRIVER_NAME = "cloudflare-kv-binding";

export default defineDriver((opts: KVOptions = {}) => {
async function getKeys(base?: string) {
const binding = getBinding(opts.binding);
Expand All @@ -14,7 +16,7 @@ export default defineDriver((opts: KVOptions = {}) => {
}

return {
name: "cloudflare-kv-binding",
name: DRIVER_NAME,
options: opts,
async hasItem(key) {
const binding = getBinding(opts.binding);
Expand Down Expand Up @@ -52,15 +54,17 @@ function getBinding(binding: KVNamespace | string = "STORAGE") {
}

if (!binding) {
throw new Error(
`Invalid Cloudflare KV binding '${bindingName}': ${binding}`
throw createError(
DRIVER_NAME,
`Invalid binding \`${bindingName}\`: \`${binding}\``
);
}

for (const key of ["get", "put", "delete"]) {
if (!(key in binding)) {
throw new Error(
`Invalid Cloudflare KV binding '${bindingName}': '${key}' key is missing`
throw createError(
DRIVER_NAME,
`Invalid binding \`${bindingName}\`: \`${key}\` key is missing`
);
}
}
Expand Down
16 changes: 9 additions & 7 deletions src/drivers/cloudflare-kv-http.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { $fetch } from "ofetch";
import { defineDriver } from "./utils";
import { createError, createRequiredError, defineDriver } from "./utils";

const LOG_TAG = "[unstorage] [cloudflare-http] ";

Expand Down Expand Up @@ -72,12 +72,14 @@ type CloudflareAuthorizationHeaders =
Authorization: `Bearer ${string}`;
};

const DRIVER_NAME = "cloudflare-kv-http";

export default defineDriver<KVHTTPOptions>((opts) => {
if (!opts.accountId) {
throw new Error(LOG_TAG + "`accountId` is required.");
throw createRequiredError(DRIVER_NAME, "accountId");
}
if (!opts.namespaceId) {
throw new Error(LOG_TAG + "`namespaceId` is required.");
throw createRequiredError(DRIVER_NAME, "namespaceId");
}

let headers: CloudflareAuthorizationHeaders;
Expand All @@ -89,9 +91,9 @@ export default defineDriver<KVHTTPOptions>((opts) => {
} else if (opts.email && opts.apiKey) {
headers = { "X-Auth-Email": opts.email, "X-Auth-Key": opts.apiKey };
} else {
throw new Error(
LOG_TAG +
"One of the `apiToken`, `userServiceKey`, or a combination of `email` and `apiKey` is required."
throw createError(
DRIVER_NAME,
"One of the `apiToken`, `userServiceKey`, or a combination of `email` and `apiKey` is required."
);
}

Expand Down Expand Up @@ -193,7 +195,7 @@ export default defineDriver<KVHTTPOptions>((opts) => {
};

return {
name: "cloudflare-kv-http",
name: DRIVER_NAME,
options: opts,
hasItem,
getItem,
Expand Down
14 changes: 8 additions & 6 deletions src/drivers/fs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { existsSync, promises as fsp, Stats } from "fs";
import { resolve, relative, join } from "path";
import { FSWatcher, WatchOptions, watch } from "chokidar";
import { defineDriver } from "./utils";
import { createError, createRequiredError, defineDriver } from "./utils";
import {
readFile,
writeFile,
Expand All @@ -21,9 +21,11 @@ export interface FSStorageOptions {

const PATH_TRAVERSE_RE = /\.\.\:|\.\.$/;

const DRIVER_NAME = "fs";

export default defineDriver((opts: FSStorageOptions = {}) => {
if (!opts.base) {
throw new Error("base is required");
throw createRequiredError(DRIVER_NAME, "base");
}

if (!opts.ignore) {
Expand All @@ -33,9 +35,9 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
opts.base = resolve(opts.base);
const r = (key: string) => {
if (PATH_TRAVERSE_RE.test(key)) {
throw new Error(
"[unstorage] [fs] Invalid key. It should not contain `..` segments: " +
key
throw createError(
DRIVER_NAME,
`Invalid key: ${JSON.stringify(key)}. It should not contain .. segments`
);
}
const resolved = join(opts.base!, key.replace(/:/g, "/"));
Expand All @@ -45,7 +47,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
let _watcher: FSWatcher;

return {
name: "fs",
name: DRIVER_NAME,
options: opts,
hasItem(key) {
return existsSync(r(key));
Expand Down
31 changes: 17 additions & 14 deletions src/drivers/github.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineDriver } from "./utils";
import { createError, createRequiredError, defineDriver } from "./utils";
import { $fetch } from "ofetch";
import { withTrailingSlash, joinURL } from "ufo";

Expand Down Expand Up @@ -44,6 +44,8 @@ const defaultOptions: GithubOptions = {
cdnURL: "https://raw.githubusercontent.com",
};

const DRIVER_NAME = "github";

export default defineDriver((_opts: GithubOptions) => {
const opts = { ...defaultOptions, ..._opts };
const rawUrl = joinURL(opts.cdnURL, opts.repo, opts.branch, opts.dir);
Expand All @@ -52,11 +54,11 @@ export default defineDriver((_opts: GithubOptions) => {
let lastCheck = 0;
let syncPromise: Promise<any>;

if (!opts.repo) {
throw new Error('[unstorage] [github] Missing required option "repo"');
}

const syncFiles = async () => {
if (!opts.repo) {
throw createRequiredError(DRIVER_NAME, "repo");
}

if (lastCheck + opts.ttl * 1000 > Date.now()) {
return;
}
Expand All @@ -71,7 +73,7 @@ export default defineDriver((_opts: GithubOptions) => {
};

return {
name: "github",
name: DRIVER_NAME,
options: opts,
async getKeys() {
await syncFiles();
Expand All @@ -98,10 +100,12 @@ export default defineDriver((_opts: GithubOptions) => {
Authorization: opts.token ? `token ${opts.token}` : undefined,
},
});
} catch (err) {
throw new Error(`[unstorage] [github] Failed to fetch "${key}"`, {
cause: err,
});
} catch (error) {
throw createError(
"github",
`Failed to fetch \`${JSON.stringify(key)}\``,
{ cause: error }
);
}
}
return item.body;
Expand Down Expand Up @@ -141,10 +145,9 @@ async function fetchFiles(opts: GithubOptions) {
},
};
}
} catch (err) {
throw new Error(`[unstorage] [github] Failed to fetch git tree`, {
cause: err,
} catch (error) {
throw createError(DRIVER_NAME, "Failed to fetch git tree", {
cause: error,
});
}
return files;
}
Loading

0 comments on commit 5ecca54

Please sign in to comment.