6 Commits

Author SHA1 Message Date
c35355a846 1.0.6 2024-04-26 13:51:46 +02:00
d82d9e4cfa fix(core): update 2024-04-26 13:51:45 +02:00
43b5dac24a 1.0.5 2024-04-24 18:24:19 +02:00
c391c180fd fix(core): update 2024-04-24 18:24:19 +02:00
2be31e409b 1.0.4 2024-04-24 18:14:58 +02:00
c9eb03dc31 fix(core): update 2024-04-24 18:14:57 +02:00
6 changed files with 82 additions and 48 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@push.rocks/smartexpose", "name": "@push.rocks/smartexpose",
"version": "1.0.3", "version": "1.0.6",
"private": false, "private": false,
"description": "a package to expose things to the internet", "description": "a package to expose things to the internet",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",

View File

@ -9,17 +9,17 @@ import * as smartexpose from '../ts/index.js'
let testSmartexpose: smartexpose.SmartExpose; let testSmartexpose: smartexpose.SmartExpose;
tap.test('should create a valid instance of smartexpose using Webdav', async () => { tap.test('should create a valid instance of smartexpose using Webdav', async () => {
testSmartexpose = await smartexpose.SmartExpose.createWithWebdav({ testSmartexpose = new smartexpose.SmartExpose({
webdavCredentials: { webdav: {
serverUrl: await testQenv.getEnvVarOnDemand('WEBDAV_SERVER_URL'), webdavCredentials: {
password: await testQenv.getEnvVarOnDemand('WEBDAV_SERVER_TOKEN'), serverUrl: await testQenv.getEnvVarOnDemand('WEBDAV_SERVER_URL'),
password: await testQenv.getEnvVarOnDemand('WEBDAV_SERVER_TOKEN'),
},
webdavSubPath: await testQenv.getEnvVarOnDemand('WEBDAV_SUB_PATH'),
}, },
webdavSubPath: await testQenv.getEnvVarOnDemand('WEBDAV_SUB_PATH'), deleteAfterMillis: 30000,
exposeOptions: { privateUrl: true,
deleteAfterMillis: 30000, exposedBaseUrl: await testQenv.getEnvVarOnDemand('EXPOSED_BASE_URL'),
privateUrl: true,
exposedBaseUrl: await testQenv.getEnvVarOnDemand('EXPOSED_BASE_URL'),
}
}); });
await testSmartexpose.start(); await testSmartexpose.start();
expect(testSmartexpose).toBeInstanceOf(smartexpose.SmartExpose); expect(testSmartexpose).toBeInstanceOf(smartexpose.SmartExpose);

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartexpose', name: '@push.rocks/smartexpose',
version: '1.0.3', version: '1.0.6',
description: 'a package to expose things to the internet' description: 'a package to expose things to the internet'
} }

View File

@ -28,6 +28,16 @@ export abstract class ExposeProvider {
status: 'created' | 'updated'; status: 'created' | 'updated';
}>; }>;
public abstract exposeFileArray(optionsArg: {
smartFiles: plugins.smartfile.SmartFile[],
deleteAfterMillis?: number,
privateUrl?: boolean,
}): Promise<{
url: string;
id: string;
status: 'created' | 'updated';
}[]>;
public abstract start(): Promise<void>; public abstract start(): Promise<void>;
public abstract stop(): Promise<void>; public abstract stop(): Promise<void>;

View File

@ -12,8 +12,9 @@ export class WebDavExposeProvider extends ExposeProvider {
public webdavClient: plugins.smartwebdav.WebdavClient; public webdavClient: plugins.smartwebdav.WebdavClient;
public options: IWebdavExposeProviderOptions; public options: IWebdavExposeProviderOptions;
constructor(optionsArg: IWebdavExposeProviderOptions) { constructor(smartexposeRefArg: SmartExpose, optionsArg: IWebdavExposeProviderOptions) {
super(); super();
this.smartExposeRef = smartexposeRefArg;
this.options = optionsArg; this.options = optionsArg;
} }
@ -38,39 +39,50 @@ export class WebDavExposeProvider extends ExposeProvider {
this.webdavClient = new plugins.smartwebdav.WebdavClient(this.options.webdavCredentials); this.webdavClient = new plugins.smartwebdav.WebdavClient(this.options.webdavCredentials);
await this.ensureBaseDir(); await this.ensureBaseDir();
await this.houseKeeping(); await this.houseKeeping();
this.smartExposeRef.taskmanager.addAndScheduleTask(new plugins.taskbuffer.Task({ this.smartExposeRef.taskmanager.addAndScheduleTask(
name: 'webdavHousekeeping', new plugins.taskbuffer.Task({
taskFunction: async () => { name: 'webdavHousekeeping',
await this.houseKeeping(); taskFunction: async () => {
}, await this.houseKeeping();
}), '0 * * * * *') },
}),
'0 * * * * *'
);
} }
public async stop(): Promise<void> { public async stop(): Promise<void> {
// Nothing to do here // Nothing to do here
} }
public async exposeFile(optionsArg: { public async exposeFile(
smartFile: plugins.smartfile.SmartFile; optionsArg: Parameters<ExposeProvider['exposeFile']>[0]
deleteAfterMillis?: number; ): Promise<{ url: string; id: string; status: 'created' | 'updated' }> {
privateUrl?: boolean;
}): Promise<{ url: string; id: string; status: 'created' | 'updated' }> {
await this.ensureBaseDir(); await this.ensureBaseDir();
const fileId = plugins.smartunique.shortId(30); const fileId = plugins.smartunique.shortId(30);
console.log(`Expsing file under id: ${fileId}. (${ console.log(
plugins.smartformat.prettyBytes(optionsArg.smartFile.contents.length) `Expsing file under id: ${fileId}. (${plugins.smartformat.prettyBytes(
})`); optionsArg.smartFile.contents.length
)})`
);
const webdavFilePath = await this.getFilePathById(fileId); const webdavFilePath = await this.getFilePathById(fileId);
const fileToUpload = await plugins.smartfile.SmartFile.fromBuffer(webdavFilePath, optionsArg.smartFile.contents); const fileToUpload = await plugins.smartfile.SmartFile.fromBuffer(
webdavFilePath,
optionsArg.smartFile.contents
);
await this.webdavClient.uploadSmartFileArray([fileToUpload]); await this.webdavClient.uploadSmartFileArray([fileToUpload]);
console.log(`checking file presence: ${webdavFilePath}`); console.log(`checking file presence: ${webdavFilePath}`);
const existsOnWebdav = await this.webdavClient.wdClient.exists(webdavFilePath); const existsOnWebdav = await this.webdavClient.wdClient.exists(webdavFilePath);
const publicUrl = plugins.smartpath.join(this.smartExposeRef.options.exposedBaseUrl, webdavFilePath); const publicUrl = plugins.smartpath.join(
console.log(`cehcking for file at ${publicUrl}`) this.smartExposeRef.options.exposedBaseUrl,
webdavFilePath
);
console.log(`cehcking for file at ${publicUrl}`);
const response = await plugins.smartrequest.getBinary(publicUrl); const response = await plugins.smartrequest.getBinary(publicUrl);
plugins.smartexpect.expect(response.body).toEqual(fileToUpload.contents); plugins.smartexpect.expect(response.body).toEqual(fileToUpload.contents);
if (optionsArg.deleteAfterMillis) { if (optionsArg.deleteAfterMillis) {
console.log(`Scheduling deletion of file with id: ${fileId} in ${optionsArg.deleteAfterMillis}ms...`); console.log(
`Scheduling deletion of file with id: ${fileId} in ${optionsArg.deleteAfterMillis}ms...`
);
plugins.smartdelay.delayFor(optionsArg.deleteAfterMillis).then(() => { plugins.smartdelay.delayFor(optionsArg.deleteAfterMillis).then(() => {
console.log(`Deleting file with id: ${fileId}...`); console.log(`Deleting file with id: ${fileId}...`);
this.deleteFileById(fileId); this.deleteFileById(fileId);
@ -84,6 +96,20 @@ export class WebDavExposeProvider extends ExposeProvider {
}; };
} }
public async exposeFileArray(optionsArg: Parameters<ExposeProvider['exposeFileArray']>[0]) {
const returnArray = [];
for (const smartFile of optionsArg.smartFiles) {
returnArray.push(
await this.exposeFile({
smartFile,
deleteAfterMillis: optionsArg.deleteAfterMillis,
privateUrl: optionsArg.privateUrl,
})
);
}
return returnArray;
}
public async wipeAll(): Promise<{ id: string; status: 'deleted' | 'failed' | 'notfound' }[]> { public async wipeAll(): Promise<{ id: string; status: 'deleted' | 'failed' | 'notfound' }[]> {
const directoryContents = await this.webdavClient.listDirectory(this.options.webdavSubPath); const directoryContents = await this.webdavClient.listDirectory(this.options.webdavSubPath);
await this.webdavClient.ensureEmptyDirectory(this.options.webdavSubPath); await this.webdavClient.ensureEmptyDirectory(this.options.webdavSubPath);

View File

@ -6,36 +6,30 @@ export interface ISmartExposeOptions {
deleteAfterMillis?: number, deleteAfterMillis?: number,
privateUrl?: boolean, privateUrl?: boolean,
exposedBaseUrl: string, exposedBaseUrl: string,
webdav?: {
webdavCredentials: plugins.smartwebdav.IWebdavClientOptions,
webdavSubPath: string,
}
} }
export class SmartExpose { export class SmartExpose {
// STATIC
public static createWithWebdav(optionsArg: {
webdavCredentials: plugins.smartwebdav.IWebdavClientOptions,
webdavSubPath: string,
exposeOptions: ISmartExposeOptions,
}) {
const provider = new WebDavExposeProvider({
webdavCredentials: optionsArg.webdavCredentials,
webdavSubPath: optionsArg.webdavSubPath,
});
const smartexposeInstance = new SmartExpose(provider, optionsArg.exposeOptions);
provider.smartExposeRef = smartexposeInstance;
return smartexposeInstance;
}
// INSTANCE // INSTANCE
public taskmanager: plugins.taskbuffer.TaskManager; public taskmanager: plugins.taskbuffer.TaskManager;
public provider: ExposeProvider; public provider: ExposeProvider;
public options: ISmartExposeOptions; public options: ISmartExposeOptions;
constructor(provider: ExposeProvider, optionsArg: ISmartExposeOptions) { constructor(optionsArg: ISmartExposeOptions) {
this.provider = provider;
this.options = optionsArg; this.options = optionsArg;
} }
public async start() { public async start() {
this.taskmanager = new plugins.taskbuffer.TaskManager(); this.taskmanager = new plugins.taskbuffer.TaskManager();
if (this.options.webdav) {
this.provider = new WebDavExposeProvider(this, {
webdavCredentials: this.options.webdav.webdavCredentials,
webdavSubPath: this.options.webdav.webdavSubPath,
});
}
await this.provider.start(); await this.provider.start();
this.taskmanager.start(); this.taskmanager.start();
} }
@ -48,4 +42,8 @@ export class SmartExpose {
public async exposeFile(optionsArg: Parameters<ExposeProvider['exposeFile']>[0]) { public async exposeFile(optionsArg: Parameters<ExposeProvider['exposeFile']>[0]) {
return this.provider.exposeFile(optionsArg); return this.provider.exposeFile(optionsArg);
} }
public async exposeFileArray(optionsArg: Parameters<ExposeProvider['exposeFileArray']>[0]) {
return this.provider.exposeFileArray(optionsArg);
}
} }