- added own provider for drive methods
Some checks failed
CI Pipeline / japa-tests (push) Failing after 1m13s

- renamed middleware Role and Can to role_middleware and can_middleware
- added some typing for inertia vue3 components
- npm updates
This commit is contained in:
Kaimbacher 2024-04-23 19:36:45 +02:00
parent cb51a4136f
commit 296c8fd46e
67 changed files with 2515 additions and 1913 deletions

View file

@ -0,0 +1,154 @@
import type { ApplicationService } from '@adonisjs/core/types';
import { Manager } from '@poppinss/manager';
import { Exception } from '@poppinss/utils';
import { DriverContract, DriversList, DriveConfig, DriveListItem, DirectoryListingContract, LocalDriverConfig } from './types/drive.js';
// import { LocalDriver } from './drivers/local.js';
import { LocalDriver } from '../drivers/local.js';
type test = {
[P in keyof DriversList]: DriversList[P];
};
// type DriveMappings = {
// local: string
// fake: string
// }
// interface DriversList {
// local: {
// implementation: LocalDriverContract;
// config: LocalDriverConfig;
// };
// }
// type DriverConfig = {
// disk: keyof DriversList
// disks: {
// [K in keyof DriversList]: any
// }
// }
// const mailerConfig: DriveConfig = {
// disk: 'local',
// disks: {
// local: {
// driver: 'local',
// root: '',
// visibility: '',
// serveFiles: false,
// basePath: '',
// },
// // 'fake': {
// // driver: 'fake',
// // root: '',
// // },
// },
// };
export default class DriveManager extends Manager<
ApplicationService,
DriverContract,
DriverContract,
{
[P in keyof DriversList]: DriversList[P]['implementation'];
}
> {
protected singleton = true;
private config;
/**
* Find if drive is ready to be used
*/
private isReady: boolean;
protected getDefaultMappingName() {
return this.config.disk; // "local"
}
protected getMappingConfig(mappingName: string) {
return this.config.disks[mappingName];
}
protected getMappingDriver(mappingName: string) {
return this.config.disks[mappingName].driver;
}
/**
* Make instance of the local driver
*/
protected createLocal(diskName: keyof DriversList, config: LocalDriverConfig) {
// const { LocalDriver } = await import('../drivers/local.js');
return new LocalDriver(diskName, config);
}
constructor(application: ApplicationService, config: DriveConfig) {
super(application);
this.config = config;
/**
* Find if drive is ready to be used
*/
this.isReady = false;
this.validateConfig();
}
/**
* Validate config
*/
private validateConfig() {
if (!this.config) {
return;
}
// const validator = new utils_1.ManagerConfigValidator(this.config, 'drive', 'config/drive');
// validator.validateDefault('disk');
// validator.validateList('disks', 'disk');
this.isReady = true;
}
/**
* Resolve instance for a disk
*/
use(disk?: keyof test): DriversList[keyof DriversList]['implementation'] {
if (!this.isReady) {
throw new Exception('Missing configuration for drive. Visit https://bit.ly/2WnR5j9 for setup instructions', {
status: 500,
code: 'E_MISSING_DRIVE_CONFIG',
});
}
disk = disk || this.getDefaultMappingName();
// if (this.fakeDrive.isFaked(disk)) {
// return this.fakeDrive.use(disk);
// }
return super.use(disk);
}
/**
* A boolean to find if the location path exists or not
*/
exists(location: string): Promise<boolean> {
const driver = this.use();
return driver.exists(location);
}
/**
* Remove a given location path
*/
delete(location: string): Promise<void> {
const driver = this.use();
return driver.delete(location);
}
/**
* Return a listing directory iterator for given location.
*/
list(location: string): DirectoryListingContract<DriverContract, DriveListItem> {
const driver = this.use();
if (typeof driver.list !== 'function') {
throw new Exception(`List is not supported by the "${driver.name}" driver.`, {
status: 500,
code: 'E_LIST_NOT_SUPPORTED',
});
}
return driver.list(location);
}
}

View file

@ -0,0 +1,68 @@
import { DriveListItem, DriverContract } from './types/drive.js';
// import * as fsExtra from 'fs-extra';
import { DirectoryListingContract } from './types/drive.js';
// class AsyncIterableArray<T> implements AsyncIterable<T> {
export class AsyncIterableArray<SpecificDriver extends DriverContract, T extends DriveListItem>
implements DirectoryListingContract<SpecificDriver, T>
{
public driver: SpecificDriver;
private generator: () => AsyncGenerator<T, void, unknown>;
// private generator: () => AsyncGenerator<T, void, unknown>;
private chain: any[];
constructor(driver: SpecificDriver, generator: () => AsyncGenerator<T, void, unknown>) {
// constructor(driver: SpecificDriver, listing: T) {
this.driver = driver;
this.generator = generator;
/**
* Functions chain to be executed for transforming generated listing iterable
*/
this.chain = [];
}
/**
* Convert directory listing to array.
*/
// public async toArray(): Promise<T[]> {
// const arr = [];
// for await (const item of this.toIterable()) {
// arr.push(item);
// }
// return arr;
// }
async toArray(): Promise<T[]> {
const arr: T[] = [];
for await (const item of this) {
arr.push(item);
}
return arr;
}
/**
* A method that returns the default async iterator for an object.
*/
public async *[Symbol.asyncIterator](): AsyncIterableIterator<T> {
// yield* this.toIterable();
for await (const item of this.generator.call(this.driver)) {
yield item;
}
// yield 1
// // await something()
// yield 2
// // await somethingElse()
// yield 3
}
/**
* Get the final async iterable after passing directory listing through chain of piping functions modifying the output.
*/
public toIterable(): AsyncIterable<T> {
const generator = this.generator.call(this.driver);
const iterable = this.chain.reduce((prevIterable, currentIterable) => {
return currentIterable.call(this.driver, prevIterable);
}, generator);
return iterable;
}
}

View file

@ -0,0 +1,5 @@
import { DriveConfig } from "./drive.js";
export function defineConfig(config: DriveConfig): DriveConfig {
return config;
}

View file

@ -0,0 +1,176 @@
import fsExtra from 'fs-extra';
import { LocalDriver } from '#providers/drive/drivers/local';
/**
* List item returned by the drive drivers
*/
export interface DriveListItem<T = any> {
/**
* Location of list item on disk which can be used in driver methods
*/
location: string;
/**
* Flag to know if item represents file or directory
*/
isFile: boolean;
/**
* Original list item returned from underlying driver
*/
original: T;
}
/**
* List item returned from local disk driver
*/
export interface LocalDriveListItem extends DriveListItem<fsExtra.Dirent> {}
export interface DirectoryListingContract<Driver extends DriverContract, T> extends AsyncIterable<T> {
/**
* Reference to the driver for which the listing was created.
*/
driver: Driver;
/**
* Filter generated items of listing with the given predicate function.
*/
// filter(predicate: (item: T, index: number, driver: Driver) => Promise<boolean> | boolean): DirectoryListingContract<Driver, T>;
/**
* Transform generated items of listing with the given mapper function.
*/
// map<M>(mapper: (item: T, index: number, driver: Driver) => Promise<M> | M): DirectoryListingContract<Driver, M>;
/**
* Do recursive listing of items. Without the next function it will do listing of leaf nodes only.
* For advanced usage you can pass the next function which will get as parameter current item and it should
* return the next location for list or null if the recursion should stop and yield the current item.
* For advanced usage you can also limit the depth of recursion using the second argument of next function.
*/
// recursive(
// next?: (current: T, depth: number, driver: Driver) => Promise<string | null> | string | null,
// ): DirectoryListingContract<Driver, T>;
/**
* Add a piping chain function which gets the current async iterable and returns
* new async iterable with modified directory listing output.
* Function this is bound to instance of driver for which the listing is generated.
* This allows using async generator functions and reference the driver methods easily.
* Piping will always return clone of the current instance and add the function
* to the chain of new cloned instance only to prevent side effects.
*/
// pipe<U>(fn: (this: Driver, source: AsyncIterable<T>) => AsyncIterable<U>): DirectoryListingContract<Driver, U>;
/**
* Get the final async iterable after passing directory listing through chain of piping functions modifying the output.
*/
toIterable(): AsyncIterable<T>;
/**
* Convert directory listing to array.
*/
toArray(): Promise<T[]>;
}
/**
* Shape of the generic driver
*/
export interface DriverContract {
/**
* Name of the driver
*/
name: string;
/**
* A boolean to find if the location path exists or not
*/
exists(location: string): Promise<boolean>;
/**
* Remove a given location path
*/
delete(location: string): Promise<void>;
/**
* Return a listing directory iterator for given location.
* @experimental
*/
list?(location: string): DirectoryListingContract<DriverContract, DriveListItem>;
}
/**
* Shape of the local disk driver
*/
export interface LocalDriverContract extends DriverContract {
name: 'local';
/**
* Reference to the underlying adapter. Which is fs-extra
*/
adapter: typeof fsExtra;
/**
* Make path to a given file location
*/
makePath(location: string): string;
}
// interface LocalDriverContract {
// delete(): Promise<void>;
// }
export type LocalDriverConfig = {
driver: 'local';
// visibility: Visibility
root: string;
/**
* Base path is always required when "serveFiles = true"
*/
serveFiles?: boolean;
basePath?: string;
};
/**
* List of registered drivers. Drivers shipped via other packages
* should merge drivers to this interface
*/
export interface DriversList {
// [key: string]: {implementation : DriverContract, config: {}};
local: {
implementation: LocalDriver;
config: {
driver: string;
visibility: string;
root: string;
serveFiles: boolean;
basePath: string;
};
};
// [key: string]: DriverContract;
// local: LocalDriver;
// fake: {
// implementation: LocalDriverContract;
// config: LocalDriverConfig;
// };
}
export type DriveConfig = {
disk: keyof DriversList;
// disks: {
// [name: string]: {
// driver: DriverContract;
// };
// };
disks: {
[name: string]: {
[K in keyof DriversList]: DriversList[K]['config'] & {
driver: K;
visibility: string;
root: string;
serveFiles: boolean;
basePath: string;
};
}[keyof DriversList];
};
};