Merge branch 'main' into feat/azure-authentication

This commit is contained in:
Pooya Parsa
2025-02-21 14:49:28 +01:00
8 changed files with 1784 additions and 3190 deletions

View File

@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: corepack enable
- run: npm i -fg corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "pnpm"
- run: pnpm install
- run: pnpm run gen-drivers
@@ -24,4 +24,4 @@ jobs:
run: pnpm run lint:fix
- uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
with:
commit-message: "chore: apply automated lint fixes"
commit-message: "chore: apply automated updates"

View File

@@ -18,10 +18,10 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: corepack enable
- run: npm i -fg corepack && corepack enable
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: "pnpm"
- uses: denoland/setup-deno@v2
with:

View File

@@ -10,7 +10,7 @@ icon: simple-icons:planetscale
**Driver name:** `planetscale`
::read-more{to="https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"}
::read-more{to="https://planetscale.com/"}
Learn more about PlanetScale.
::

View File

@@ -39,9 +39,9 @@ const storage = createStorage({
});
```
Usage with Redis cluster (e.g. AWS ElastiCache or Azure Redis Cache):
Usage with a Redis cluster (e.g. AWS ElastiCache or Azure Redis Cache):
⚠️ If you connect to a cluster, you have to use `hastags` as prefix to avoid the redis error `CROSSSLOT Keys in request don't hash to the same slot`. This means, the prefix has to be surrounded by curly braces, which forces the keys into the same hash slot.
⚠️ If you connect to a cluster, you have to use [`hashtags`](https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/#hash-tags) as the prefix to avoid the Redis error `CROSSSLOT Keys in request don't hash to the same slot`. This means the prefix has to be surrounded by curly braces, which forces the keys into the same hash slot. You can read more [here](https://redis.io/blog/redis-clustering-best-practices-with-keys/).
```js
const storage = createStorage({
@@ -65,7 +65,7 @@ const storage = createStorage({
**Options:**
- `base`: Optional prefix to use for all keys. Can be used for namespacing. Has to be used as hastag prefix for redis cluster mode.
- `base`: Optional prefix to use for all keys. Can be used for namespacing. Has to be used as a hashtag prefix for redis cluster mode.
- `url`: Url to use for connecting to redis. Takes precedence over `host` option. Has the format `redis://<REDIS_USER>:<REDIS_PASSWORD>@<REDIS_HOST>:<REDIS_PORT>`
- `cluster`: List of redis nodes to use for cluster mode. Takes precedence over `url` and `host` options.
- `clusterOptions`: Options to use for cluster mode.

View File

@@ -45,11 +45,11 @@
},
"dependencies": {
"anymatch": "^3.1.3",
"chokidar": "^3.6.0",
"chokidar": "^4.0.3",
"destr": "^2.0.3",
"h3": "^1.13.1",
"h3": "^1.15.0",
"lru-cache": "^10.4.3",
"node-fetch-native": "^1.6.4",
"node-fetch-native": "^1.6.6",
"ofetch": "^1.4.1",
"ufo": "^1.5.4"
},
@@ -57,53 +57,53 @@
"@azure/app-configuration": "^1.8.0",
"@azure/cosmos": "^4.2.0",
"@azure/data-tables": "^13.3.0",
"@azure/identity": "^4.6.0",
"@azure/identity": "^4.7.0",
"@azure/keyvault-secrets": "^4.9.0",
"@azure/storage-blob": "^12.26.0",
"@capacitor/preferences": "^6.0.3",
"@cloudflare/workers-types": "^4.20250109.0",
"@capacitor/preferences": "^7.0.0",
"@cloudflare/workers-types": "^4.20250214.0",
"@deno/kv": "^0.9.0",
"@electric-sql/pglite": "^0.2.15",
"@electric-sql/pglite": "^0.2.17",
"@libsql/client": "^0.14.0",
"@netlify/blobs": "^8.1.0",
"@netlify/blobs": "^8.1.1",
"@planetscale/database": "^1.19.0",
"@types/deno": "^2.0.0",
"@types/deno": "^2.2.0",
"@types/ioredis-mock": "^8.2.5",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.10.7",
"@upstash/redis": "^1.34.3",
"@types/node": "^22.13.4",
"@upstash/redis": "^1.34.4",
"@vercel/blob": "^0.27.1",
"@vercel/kv": "^3.0.0",
"@vitest/coverage-v8": "^2.1.8",
"@vitest/coverage-v8": "^3.0.6",
"aws4fetch": "^1.0.20",
"azurite": "^3.33.0",
"better-sqlite3": "^11.8.1",
"changelogen": "^0.5.7",
"citty": "^0.1.6",
"db0": "^0.2.1",
"eslint": "^9.18.0",
"db0": "^0.2.4",
"eslint": "^9.20.1",
"eslint-config-unjs": "^0.4.2",
"fake-indexeddb": "^6.0.0",
"get-port-please": "^3.1.2",
"idb-keyval": "^6.2.1",
"ioredis": "^5.4.2",
"ioredis": "^5.5.0",
"ioredis-mock": "^8.9.0",
"jiti": "^2.4.2",
"jsdom": "^25.0.1",
"jsdom": "^26.0.0",
"listhen": "^1.9.0",
"mitata": "^1.0.31",
"mitata": "^1.0.34",
"mlly": "^1.7.4",
"mongodb": "^6.12.0",
"mongodb-memory-server": "^10.1.3",
"prettier": "^3.4.2",
"mongodb": "^6.13.1",
"mongodb-memory-server": "^10.1.4",
"prettier": "^3.5.1",
"scule": "^1.3.0",
"types-cloudflare-worker": "^1.2.0",
"typescript": "^5.7.3",
"unbuild": "^3.3.1",
"uploadthing": "^7.4.4",
"vite": "^6.0.7",
"vitest": "^2.1.8",
"wrangler": "^3.101.0"
"uploadthing": "^7.5.2",
"vite": "^6.1.1",
"vitest": "^3.0.6",
"wrangler": "^3.109.2"
},
"peerDependencies": {
"@azure/app-configuration": "^1.8.0",
@@ -181,5 +181,17 @@
"optional": true
}
},
"packageManager": "pnpm@9.15.4"
"packageManager": "pnpm@10.4.1",
"pnpm": {
"ignoredBuiltDependencies": [
"@parcel/watcher",
"sharp",
"workerd"
],
"onlyBuiltDependencies": [
"better-sqlite3",
"esbuild",
"mongodb-memory-server"
]
}
}

4835
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,7 @@
import { existsSync, promises as fsp, Stats } from "node:fs";
import { resolve, relative, join } from "node:path";
import {
FSWatcher,
type WatchOptions as ChokidarOptions,
watch,
} from "chokidar";
import { FSWatcher, type ChokidarOptions, watch } from "chokidar";
import anymatch from "anymatch";
import { createError, createRequiredError, defineDriver } from "./utils";
import {
readFile,
@@ -13,7 +10,6 @@ import {
rmRecursive,
unlink,
} from "./utils/node-fs";
import anymatch from "anymatch";
export interface FSStorageOptions {
base?: string;
@@ -27,16 +23,17 @@ const PATH_TRAVERSE_RE = /\.\.:|\.\.$/;
const DRIVER_NAME = "fs";
export default defineDriver((opts: FSStorageOptions = {}) => {
if (!opts.base) {
export default defineDriver((userOptions: FSStorageOptions = {}) => {
if (!userOptions.base) {
throw createRequiredError(DRIVER_NAME, "base");
}
if (!opts.ignore) {
opts.ignore = ["**/node_modules/**", "**/.git/**"];
}
const base = resolve(userOptions.base);
const ignore = anymatch(
userOptions.ignore || ["**/node_modules/**", "**/.git/**"]
);
opts.base = resolve(opts.base);
const r = (key: string) => {
if (PATH_TRAVERSE_RE.test(key)) {
throw createError(
@@ -44,7 +41,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
`Invalid key: ${JSON.stringify(key)}. It should not contain .. segments`
);
}
const resolved = join(opts.base!, key.replace(/:/g, "/"));
const resolved = join(base, key.replace(/:/g, "/"));
return resolved;
};
@@ -58,7 +55,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
return {
name: DRIVER_NAME,
options: opts,
options: userOptions,
flags: {
maxDepth: true,
},
@@ -78,32 +75,28 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
return { atime, mtime, size, birthtime, ctime };
},
setItem(key, value) {
if (opts.readOnly) {
if (userOptions.readOnly) {
return;
}
return writeFile(r(key), value, "utf8");
},
setItemRaw(key, value) {
if (opts.readOnly) {
if (userOptions.readOnly) {
return;
}
return writeFile(r(key), value);
},
removeItem(key) {
if (opts.readOnly) {
if (userOptions.readOnly) {
return;
}
return unlink(r(key));
},
getKeys(_base, topts) {
return readdirRecursive(
r("."),
anymatch(opts.ignore || []),
topts?.maxDepth
);
return readdirRecursive(r("."), ignore, topts?.maxDepth);
},
async clear() {
if (opts.readOnly || opts.noClear) {
if (userOptions.readOnly || userOptions.noClear) {
return;
}
await rmRecursive(r("."));
@@ -118,17 +111,26 @@ export default defineDriver((opts: FSStorageOptions = {}) => {
return _unwatch;
}
await new Promise<void>((resolve, reject) => {
_watcher = watch(opts.base!, {
const watchOptions: ChokidarOptions = {
ignoreInitial: true,
ignored: opts.ignore,
...opts.watchOptions,
})
...userOptions.watchOptions,
};
if (!watchOptions.ignored) {
watchOptions.ignored = [];
} else if (Array.isArray(watchOptions.ignored)) {
watchOptions.ignored = [...watchOptions.ignored];
} else {
watchOptions.ignored = [watchOptions.ignored];
}
watchOptions.ignored.push(ignore);
_watcher = watch(base, watchOptions)
.on("ready", () => {
resolve();
})
.on("error", reject)
.on("all", (eventName, path) => {
path = relative(opts.base!, path);
path = relative(base, path);
if (eventName === "change" || eventName === "add") {
callback("update", path);
} else if (eventName === "unlink") {

View File

@@ -2,6 +2,7 @@
"compilerOptions": {
"target": "ESNext",
"module": "preserve",
"moduleResolution": "bundler",
"moduleDetection": "force",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,