mirror of
https://github.com/45Drives/cockpit-navigator.git
synced 2025-07-29 16:45:13 +02:00
work on typings, start implementing PosixSource
This commit is contained in:
parent
87e4c72898
commit
9644b86dd4
@ -1,11 +1,15 @@
|
||||
import { Source } from "../types/Source";
|
||||
import { Location } from "../types/Location";
|
||||
import { INotifications } from "../types/Notifications";
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { Source } from "@/lib/Source";
|
||||
import { Location } from "@/types/Location";
|
||||
import { INotifications } from "@/types/Notifications";
|
||||
|
||||
export interface SourceContext {
|
||||
notifications: INotifications;
|
||||
}
|
||||
export default function useSourceAdapter() {
|
||||
let source;
|
||||
const items = ref([]);
|
||||
const route = useRoute();
|
||||
|
||||
export function defineSource<SourceType extends Source<Location>>(factory: (ctx: SourceContext) => SourceType) {
|
||||
return factory;
|
||||
return {
|
||||
items
|
||||
}
|
||||
}
|
||||
|
75
navigator/src/lib/Source.ts
Normal file
75
navigator/src/lib/Source.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { ItemDisplay } from '@/types/FrontEnd';
|
||||
import { Location } from '@/types/Location';
|
||||
|
||||
export interface ItemPermissions {
|
||||
owner: string | number;
|
||||
group: string | number;
|
||||
mode: number;
|
||||
}
|
||||
|
||||
export namespace Source {
|
||||
export interface CreateOptions {
|
||||
/**
|
||||
* If a file/link already exists at the specified path, and is the same type as what is being created, overwrite it.
|
||||
* Cannot overwrite directories.
|
||||
*/
|
||||
overwrite?: boolean;
|
||||
/**
|
||||
* If a file/link already exists at the specified path, overwrite it regardless of original type.
|
||||
* Cannot overwrite directories.
|
||||
*/
|
||||
forceOverwrite?: boolean;
|
||||
/**
|
||||
* If the path does not exist, create parent directories.
|
||||
* Analogous to `mkdir -p`
|
||||
*/
|
||||
parents?: boolean;
|
||||
}
|
||||
export interface DeleteOptions {
|
||||
/**
|
||||
* For directories, delete all children. If not specified for non-empty directory, deletion will fail.
|
||||
*/
|
||||
recursive?: boolean;
|
||||
}
|
||||
export interface DownloadOptions {
|
||||
/**
|
||||
* Compress files/directories into archive before downloading
|
||||
*/
|
||||
zip?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Source<ItemType extends Location, FileType extends Location = ItemType, DirectoryType extends Location = ItemType, LinkType extends Location = ItemType> {
|
||||
displayTransform(item: Readonly<ItemType>): ItemDisplay<ItemType>;
|
||||
|
||||
list(path?: string): Promise<ItemType[]>;
|
||||
lookup(path: string): Promise<ItemType>;
|
||||
|
||||
createFile?(path: string, opts?: Readonly<Source.CreateOptions>): Promise<FileType>;
|
||||
createDirectory?(path: string, opts?: Readonly<Source.CreateOptions>): Promise<DirectoryType>;
|
||||
createLink?(path: string, targetLocation: string, opts?: Readonly<Source.CreateOptions>): Promise<LinkType>;
|
||||
|
||||
delete?(item: ItemType, opts?: Readonly<Source.DeleteOptions>): Promise<ItemType>;
|
||||
moveToTrash?(item: ItemType, opts?: Readonly<Source.DeleteOptions>): Promise<ItemType>;
|
||||
|
||||
read?(item: FileType): Promise<Uint8Array>;
|
||||
write?(item: FileType, data: Uint8Array): Promise<FileType>;
|
||||
|
||||
getPermissions?(item: Location): Promise<Location & ItemPermissions>;
|
||||
setPermissions?(item: Location & Partial<ItemPermissions>, newPermissions?: Partial<ItemPermissions>): Promise<Location & ItemPermissions>;
|
||||
|
||||
download?(item: Location, options: Source.DownloadOptions): Promise<Location>;
|
||||
download?(items: Location[], options: Source.DownloadOptions): Promise<Location>;
|
||||
upload?(dataTransfer: DataTransfer): Promise<Location | Location[]>;
|
||||
}
|
||||
|
||||
export interface SourceStatic {
|
||||
readonly sourceTypeId: string;
|
||||
}
|
||||
|
||||
export const defineSource = <
|
||||
ItemType extends Location,
|
||||
FileType extends Location = ItemType,
|
||||
DirectoryType extends Location = ItemType,
|
||||
LinkType extends Location = ItemType
|
||||
>(ctor: SourceStatic & { new (...args: any[]): Source<ItemType, FileType, DirectoryType, LinkType>}) => ctor;
|
@ -1,6 +1,5 @@
|
||||
import { Source } from "../../../types/Source";
|
||||
import { ItemPosix, ItemPosixLink, ItemPosixNonLink, LsType } from "./types";
|
||||
import { UNIT_SEPARATOR, RECORD_SEPARATOR } from "../../constants";
|
||||
import { UNIT_SEPARATOR, RECORD_SEPARATOR } from "@/constants";
|
||||
|
||||
const findPrintfDirectives = [
|
||||
'%p', // full path
|
||||
@ -149,3 +148,7 @@ function makeItem(record: string): Omit<ItemPosixLink, 'source'> | Omit<ItemPosi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function list(path?: string) {
|
||||
|
||||
}
|
||||
|
@ -1,20 +1,74 @@
|
||||
import { defineSource } from "../../../composables/SourceAdapter";
|
||||
import { Source } from "../../../types/Source";
|
||||
import { ItemPosix } from "./types";
|
||||
import { ItemDisplay } from '@/types/FrontEnd';
|
||||
import { defineSource, Source, SourceStatic } from '@/lib/Source';
|
||||
import { SourceError } from '@/lib/Error';
|
||||
import { ItemPosix, LsType } from './types';
|
||||
|
||||
export default defineSource(({ notifications }) => {
|
||||
return class SourcePosix implements Source<ItemPosix> {
|
||||
constructor(private root: string, private host: string) { }
|
||||
private async getRecords(location: string): Promise<string[]> {
|
||||
return [
|
||||
""
|
||||
]
|
||||
export class SourcePosixError extends SourceError { }
|
||||
|
||||
export default defineSource(class SourcePosix implements Source<ItemPosix> {
|
||||
static readonly sourceTypeId = "fs";
|
||||
constructor(private root: string, private host: string) { }
|
||||
displayTransform(item: ItemPosix): ItemDisplay<ItemPosix> {
|
||||
const sourceItem = item;
|
||||
let displayType: ItemDisplay<ItemPosix>['displayType'];
|
||||
let isLink: ItemDisplay<ItemPosix>['isLink'];
|
||||
let isBrokenLink: ItemDisplay<ItemPosix>['isBrokenLink'];
|
||||
|
||||
switch (item.type) {
|
||||
case LsType.DIRECTORY:
|
||||
isLink = isBrokenLink = false;
|
||||
displayType = 'directory';
|
||||
break;
|
||||
case LsType.LINK:
|
||||
isLink = true;
|
||||
isBrokenLink = false;
|
||||
switch (item.targetType) {
|
||||
case LsType.DIRECTORY:
|
||||
displayType = 'directory';
|
||||
break;
|
||||
case LsType.LINK_BROKEN:
|
||||
case LsType.LINK_LOOP:
|
||||
isBrokenLink = true;
|
||||
/* fall through */
|
||||
default:
|
||||
displayType = 'file';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
isLink = isBrokenLink = false;
|
||||
displayType = 'file';
|
||||
break;
|
||||
}
|
||||
async list(path: string = ""): Promise<(ItemPosix)[]> {
|
||||
return (await this.getRecords(this.root + path)).map(record => this.makeItem(record));
|
||||
}
|
||||
async lookup(path: string): Promise<ItemPosix> {
|
||||
return this.makeItem(this.getRecords(this.root + location)[0])
|
||||
|
||||
return {
|
||||
name: item.name,
|
||||
sourceItem,
|
||||
displayType,
|
||||
isLink,
|
||||
isBrokenLink,
|
||||
};
|
||||
}
|
||||
async list(path: string = ""): Promise<(ItemPosix)[]> {
|
||||
return [];
|
||||
}
|
||||
async lookup(path: string): Promise<ItemPosix> {
|
||||
return {
|
||||
source: this,
|
||||
path,
|
||||
name: 'test',
|
||||
st_dev: 0,
|
||||
st_ino: 0,
|
||||
st_mode: 0,
|
||||
st_uid: 0,
|
||||
user: 'jimmy',
|
||||
st_gid: 0,
|
||||
group: 'bob',
|
||||
st_size: 0,
|
||||
st_atime: 0,
|
||||
st_mtime: 0,
|
||||
st_ctime: 0,
|
||||
st_btime: 0,
|
||||
type: LsType.REGULAR_FILE,
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
5
navigator/src/types/FrontEnd.d.ts
vendored
5
navigator/src/types/FrontEnd.d.ts
vendored
@ -7,7 +7,8 @@ export namespace ItemDisplay {
|
||||
export interface ItemDisplay<SourceItemType extends Location> {
|
||||
sourceItem: SourceItemType;
|
||||
name: string;
|
||||
displayType: 'file' | 'directory';
|
||||
isLink: true;
|
||||
displayType: 'directory' | 'file';
|
||||
isLink: boolean;
|
||||
isBrokenLink: boolean;
|
||||
mimetype?: ItemDisplay.mimetype;
|
||||
}
|
||||
|
64
navigator/src/types/Source.d.ts
vendored
64
navigator/src/types/Source.d.ts
vendored
@ -1,64 +0,0 @@
|
||||
import { ItemDisplay } from "./FrontEnd";
|
||||
import { Location } from "./Location";
|
||||
|
||||
export interface ItemPermissions {
|
||||
owner: string | number;
|
||||
group: string | number;
|
||||
mode: number;
|
||||
}
|
||||
|
||||
export namespace Source {
|
||||
export interface CreateOptions {
|
||||
/**
|
||||
* If a file/link already exists at the specified path, and is the same type as what is being created, overwrite it.
|
||||
* Cannot overwrite directories.
|
||||
*/
|
||||
overwrite?: boolean;
|
||||
/**
|
||||
* If a file/link already exists at the specified path, overwrite it regardless of original type.
|
||||
* Cannot overwrite directories.
|
||||
*/
|
||||
forceOverwrite?: boolean;
|
||||
/**
|
||||
* If the path does not exist, create parent directories.
|
||||
* Analogous to `mkdir -p`
|
||||
*/
|
||||
parents?: boolean;
|
||||
}
|
||||
export interface DeleteOptions {
|
||||
/**
|
||||
* For directories, delete all children. If not specified for non-empty directory, deletion will fail.
|
||||
*/
|
||||
recursive?: boolean;
|
||||
}
|
||||
export interface DownloadOptions {
|
||||
/**
|
||||
* Compress files/directories into archive before downloading
|
||||
*/
|
||||
zip?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Source<ItemType extends Location, FileType extends Location = ItemType, DirectoryType extends Location = ItemType, LinkType extends Location = ItemType> {
|
||||
displayTransform(item: ItemType): ItemDisplay<ItemType>;
|
||||
|
||||
async list(path?: string): Promise<ItemType[]>;
|
||||
async lookup(path: string): Promise<ItemType>;
|
||||
|
||||
async createFile?(path: string, opts?: Source.CreateOptions): Promise<FileType>;
|
||||
async createDirectory?(path: string, opts?: Source.CreateOptions): Promise<DirectoryType>;
|
||||
async createLink?(path: string, targetLocation: string, opts?: Source.CreateOptions): Promise<LinkType>;
|
||||
|
||||
async delete?(item: ItemType, opts?: Source.DeleteOptions): Promise<ItemType>;
|
||||
async moveToTrash?(item: ItemType, opts?: Source.DeleteOptions): Promise<ItemType>;
|
||||
|
||||
async read?(item: FileType): Promise<Uint8Array>;
|
||||
async write?(item: FileType, data: Uint8Array): Promise<FileType>;
|
||||
|
||||
async getPermissions?(item: Location): Promise<Location & ItemPermissions>;
|
||||
async setPermissions?(item: Location & Partial<ItemPermissions>, newPermissions?: Partial<ItemPermissions>): Promise<Location & ItemPermissions>;
|
||||
|
||||
async download?(item: Location, options: Source.DownloadOptions): Promise<Location>;
|
||||
async download?(items: Location[], options: Source.DownloadOptions): Promise<Location>;
|
||||
async upload?(dataTransfer: DataTransfer): Promise<Location | Location[]>;
|
||||
}
|
3
navigator/src/types/cockpit.d.ts
vendored
3
navigator/src/types/cockpit.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
declare global {
|
||||
var cockpit = {};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user