Skip to content

Commit

Permalink
feature(storage): new storage abstraction
Browse files Browse the repository at this point in the history
more adapters to come
  • Loading branch information
marcj committed Oct 8, 2023
1 parent 8511efb commit 895ccae
Show file tree
Hide file tree
Showing 14 changed files with 624 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"packages/template",
"packages/injector",
"packages/mongo",
"packages/storage",
"packages/sql",
"packages/mysql",
"packages/postgres",
Expand Down
Empty file added packages/storage/.npmignore
Empty file.
14 changes: 14 additions & 0 deletions packages/storage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# skeleton package

This package can be copied when a new package should be created.

### Steps after copying:

- Adjust "name", "description", and "private" in `package.json`.
- Adjust README.md
- Put this package into root `/package.json` "jest.references".
- Put this package into root `/tsconfig.json` "references".
- Put this package into root `/tsconfig.esm.json` "references".
- Add dependencies to `package.json` and run `node sync-tsconfig-deps.js` to adjust tsconfig automatically.
- Add to .github/workflows/main.yml tsc build step if necessary.
- Add to typedoc build in deepkit-website if necessary.
Empty file added packages/storage/dist/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions packages/storage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/storage.js';
50 changes: 50 additions & 0 deletions packages/storage/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@deepkit/storage",
"version": "1.0.1-alpha.13",
"description": "Fileystem abstraction Deepkit",
"type": "commonjs",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/cjs/index.d.ts",
"exports": {
".": {
"types": "./dist/cjs/index.d.ts",
"require": "./dist/cjs/index.js",
"default": "./dist/esm/index.js"
}
},
"repository": "https://github.com/deepkit/deepkit-framework",
"author": "Marc J. Schmidt <[email protected]>",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "echo '{\"type\": \"module\"}' > ./dist/esm/package.json"
},
"peerDependencies": {
"@deepkit/core": "^1.0.1-alpha.13"
},
"dependencies": {
},
"devDependencies": {
"@deepkit/core": "^1.0.1-alpha.13"
},
"jest": {
"testEnvironment": "node",
"transform": {
"^.+\\.(ts|tsx)$": [
"ts-jest",
{
"tsconfig": "<rootDir>/tsconfig.json"
}
]
},
"moduleNameMapper": {
"(.+)\\.js": "$1"
},
"testMatch": [
"**/tests/**/*.spec.ts"
]
}
}
104 changes: 104 additions & 0 deletions packages/storage/src/local-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { File, FileType, pathDirectory, pathNormalize, Reporter, StorageAdapter } from './storage.js';
import type * as fs from 'fs/promises';

export class StorageNodeLocalAdapter implements StorageAdapter {
fs?: typeof fs;

constructor(public path: string) {
this.path = pathNormalize(path);
}

protected async getFs(): Promise<typeof fs> {
if (!this.fs) this.fs = await import('fs/promises');
return this.fs;
}

getPath(path: string): string {
return this.path + path;
}

async copy(source: string, destination: string, reporter: Reporter): Promise<void> {
source = this.getPath(source);
destination = this.getPath(destination);
const fs = await this.getFs();
await fs.cp(source, destination, { recursive: true });
}

async delete(path: string): Promise<void> {
path = this.getPath(path);
const fs = await this.getFs();
await fs.rm(path);
}

async deleteDirectory(path: string, reporter: Reporter): Promise<void> {
path = this.getPath(path);
const fs = await this.getFs();
await fs.rm(path, { recursive: true });
}

async exists(path: string): Promise<boolean> {
path = this.getPath(path);
const fs = await this.getFs();
try {
const res = await fs.stat(path);
return res.isFile() || res.isDirectory();
} catch (error: any) {
return false;
}
}

async files(path: string): Promise<File[]> {
const localPath = this.getPath(path);
const files: File[] = [];
const fs = await this.getFs();

for (const name of await fs.readdir(localPath)) {
const file = new File(path + '/' + name);
const stat = await fs.stat(localPath + '/' + name);
file.size = stat.size;
file.lastModified = new Date(stat.mtime);
file.type = stat.isFile() ? FileType.File : FileType.Directory;
files.push(file);
}

return files;
}

async get(path: string): Promise<File | undefined> {
const localPath = this.getPath(path);
const fs = await this.getFs();
const file = new File(path);
try {
const stat = await fs.stat(localPath);
file.size = stat.size;
file.lastModified = new Date(stat.mtime);
file.type = stat.isFile() ? FileType.File : FileType.Directory;
return file;
} catch (error: any) {
return undefined;
}
}

async move(source: string, destination: string, reporter: Reporter): Promise<void> {
source = this.getPath(source);
destination = this.getPath(destination);
const fs = await this.getFs();
await fs.rename(source, destination);
}

async read(path: string, reporter: Reporter): Promise<Uint8Array> {
path = this.getPath(path);
const fs = await this.getFs();
const content = await fs.readFile(path);
return content;
}

async write(path: string, contents: Uint8Array, reporter: Reporter): Promise<void> {
path = this.getPath(path);
const fs = await this.getFs();
await fs.mkdir(pathDirectory(path), { recursive: true });
await fs.writeFile(path, contents);
}
}

export const StorageLocalAdapter = StorageNodeLocalAdapter;
Loading

0 comments on commit 895ccae

Please sign in to comment.