Added directory/file exists
This commit is contained in:
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 1.3.1-r3
|
||||||
|
- Added directory/file exists
|
||||||
|
- Fix unit tests
|
||||||
|
|
||||||
|
## 1.3.1-r2
|
||||||
|
- Initial release
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {get_version, instance_id, package_json} from '../utils/constants';
|
import { get_version, instance_id, package_json } from '../utils/constants';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
test(`can read 'package.json'`, () => {
|
test(`can read 'package.json'`, () => {
|
||||||
@@ -14,7 +14,7 @@ test(`'instance_id' is valid`, () => {
|
|||||||
|
|
||||||
test(`'version' can be read from 'package.json'`, () => {
|
test(`'version' can be read from 'package.json'`, () => {
|
||||||
console.log(get_version());
|
console.log(get_version());
|
||||||
expect(get_version()).toBe('1.3.1-r1');
|
expect(get_version()).toBe('1.3.1-r3');
|
||||||
});
|
});
|
||||||
|
|
||||||
test(`'version' can be overridden by environment variable`, () => {
|
test(`'version' can be overridden by environment variable`, () => {
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ test('can create and remove a directory using api', async () => {
|
|||||||
);
|
);
|
||||||
const api = repertory.create_api(conn);
|
const api = repertory.create_api(conn);
|
||||||
expect(await api.directory.create('/repertory_js')).toEqual(0);
|
expect(await api.directory.create('/repertory_js')).toEqual(0);
|
||||||
|
expect(await api.directory.exists('/repertory_js')).toEqual(true);
|
||||||
|
expect(await api.file.exists('/repertory_js')).toEqual(false);
|
||||||
expect(await api.directory.remove('/repertory_js')).toEqual(0);
|
expect(await api.directory.remove('/repertory_js')).toEqual(0);
|
||||||
|
|
||||||
await conn.disconnect();
|
await conn.disconnect();
|
||||||
@@ -278,6 +280,8 @@ test('can upload and download a file using api', async () => {
|
|||||||
await calculate_sha256('repertory_test.dat')
|
await calculate_sha256('repertory_test.dat')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(await api.directory.exists('/repertory_test.dat')).toEqual(false);
|
||||||
|
expect(await api.file.exists('/repertory_test.dat')).toEqual(true);
|
||||||
expect(await api.file.delete('/repertory_test.dat')).toEqual(0);
|
expect(await api.file.delete('/repertory_test.dat')).toEqual(0);
|
||||||
fs.unlinkSync('repertory_test.dat');
|
fs.unlinkSync('repertory_test.dat');
|
||||||
|
|
||||||
@@ -518,3 +522,27 @@ test('can resume upload using api', async () => {
|
|||||||
|
|
||||||
await conn.disconnect();
|
await conn.disconnect();
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
test('exists returns false if directory is not found', async () => {
|
||||||
|
const conn = await repertory.create_pool(
|
||||||
|
2,
|
||||||
|
TEST_HOST,
|
||||||
|
TEST_PORT,
|
||||||
|
TEST_PASSWORD
|
||||||
|
);
|
||||||
|
const api = repertory.create_api(conn);
|
||||||
|
expect(await api.directory.exists('/cow')).toEqual(false);
|
||||||
|
await conn.disconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('exists returns false if file is not found', async () => {
|
||||||
|
const conn = await repertory.create_pool(
|
||||||
|
2,
|
||||||
|
TEST_HOST,
|
||||||
|
TEST_PORT,
|
||||||
|
TEST_PASSWORD
|
||||||
|
);
|
||||||
|
const api = repertory.create_api(conn);
|
||||||
|
expect(await api.file.exists('/cow')).toEqual(false);
|
||||||
|
await conn.disconnect();
|
||||||
|
});
|
||||||
|
|||||||
22
src/index.js
22
src/index.js
@@ -13,6 +13,17 @@ export const create_api = (conn) => {
|
|||||||
return {
|
return {
|
||||||
directory: {
|
directory: {
|
||||||
create: async (remote_path) => ops.create_directory(conn, remote_path),
|
create: async (remote_path) => ops.create_directory(conn, remote_path),
|
||||||
|
exists: async (remote_path) => {
|
||||||
|
try {
|
||||||
|
const info = await ops.get_file_attributes2(conn, remote_path);
|
||||||
|
return info.directory;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.split(':')[1].trim() == '-2') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
list: async (remote_path, page_reader_cb) =>
|
list: async (remote_path, page_reader_cb) =>
|
||||||
ops.list_directory(conn, remote_path, page_reader_cb),
|
ops.list_directory(conn, remote_path, page_reader_cb),
|
||||||
remove: async (remote_path) => ops.remove_directory(conn, remote_path),
|
remove: async (remote_path) => ops.remove_directory(conn, remote_path),
|
||||||
@@ -43,6 +54,17 @@ export const create_api = (conn) => {
|
|||||||
overwrite,
|
overwrite,
|
||||||
resume
|
resume
|
||||||
),
|
),
|
||||||
|
exists: async (remote_path) => {
|
||||||
|
try {
|
||||||
|
const info = await ops.get_file_attributes2(conn, remote_path);
|
||||||
|
return !info.directory;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.split(':')[1].trim() == '-2') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw new Error(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
open: async (remote_path) =>
|
open: async (remote_path) =>
|
||||||
new file(conn, await ops.open_file(conn, remote_path), remote_path),
|
new file(conn, await ops.open_file(conn, remote_path), remote_path),
|
||||||
upload: async (local_path, remote_path, progress_cb, overwrite, resume) =>
|
upload: async (local_path, remote_path, progress_cb, overwrite, resume) =>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export default class connection {
|
|||||||
this.host_or_ip,
|
this.host_or_ip,
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
@@ -67,20 +68,32 @@ export default class connection {
|
|||||||
if (buffer.length >= size + 4) {
|
if (buffer.length >= size + 4) {
|
||||||
const packet_data = buffer.slice(4, 4 + size);
|
const packet_data = buffer.slice(4, 4 + size);
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
const reject = this.reject;
|
const complete = () => {
|
||||||
const resolve = this.resolve;
|
const reject = this.reject;
|
||||||
|
const resolve = this.resolve;
|
||||||
cleanup();
|
cleanup();
|
||||||
|
return {
|
||||||
|
reject,
|
||||||
|
resolve,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const response = new packet(this.password);
|
const response = new packet(this.password);
|
||||||
response.buffer = new Uint8Array(packet_data);
|
response.buffer = new Uint8Array(packet_data);
|
||||||
response
|
response
|
||||||
.decrypt()
|
.decrypt()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolve(response);
|
const { resolve } = complete();
|
||||||
|
if (resolve) {
|
||||||
|
resolve(response);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
reject(e);
|
console.log(e);
|
||||||
|
const { reject } = complete();
|
||||||
|
if (reject) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +107,10 @@ export default class connection {
|
|||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
reject(e);
|
console.log(e);
|
||||||
|
if (reject) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -105,7 +121,10 @@ export default class connection {
|
|||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
reject(new Error('socket closed'));
|
console.log('socket closed');
|
||||||
|
if (reject) {
|
||||||
|
reject(new Error('socket closed'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -312,6 +312,37 @@ export const get_file_attributes = async (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const get_file_attributes2 = async (
|
||||||
|
conn,
|
||||||
|
remote_path,
|
||||||
|
optional_thread_id
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const request = new packet();
|
||||||
|
request.encode_utf8(remote_path);
|
||||||
|
request.encode_ui32(0);
|
||||||
|
request.encode_ui32(0);
|
||||||
|
|
||||||
|
const response = await conn.send(
|
||||||
|
'::RemoteFUSEGetattr',
|
||||||
|
request,
|
||||||
|
optional_thread_id
|
||||||
|
);
|
||||||
|
response.decode_ui32(); // Service flags
|
||||||
|
|
||||||
|
const result = response.decode_i32();
|
||||||
|
if (result === 0) {
|
||||||
|
return response.decode_stat();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(
|
||||||
|
new Error(`'get_file_attributes2' failed: ${result}`)
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(new Error(`'get_file_attributes2' failed: ${err}`));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const list_directory = async (conn, remote_path, page_reader_cb) => {
|
export const list_directory = async (conn, remote_path, page_reader_cb) => {
|
||||||
const dir_snapshot = await _snapshot_directory(conn, remote_path);
|
const dir_snapshot = await _snapshot_directory(conn, remote_path);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user