Merge pull request #32 from davidc789/main

Add exclude feature
This commit is contained in:
Alt 2023-06-30 11:23:20 +02:00 committed by GitHub
commit 019c45580f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 224 additions and 61 deletions

26
.gitattributes vendored Normal file
View file

@ -0,0 +1,26 @@
# js / ts files
*.js text
*.ts text
# Config text files
*.jsonc text
*.json text
*.yml text
.eslintrc text
.eslintignore text
.gitignore text
.gitattributes text
.prettierignore text
.prettierrc text
# Standard text files
*.txt text
*.md text
*.sh text eol=lf
*.bat text eol=crlf
LICENSE text
# Binary files
*.gif binary
*.jpg binary
*.png binary

View file

@ -1,4 +1,4 @@
#!/usr/bin/env -S node --experimental-specifier-resolution=node
import { start } from "../src/index";
#!/usr/bin/env -S node
import { start } from "../src/index.js";
await start();

166
package-lock.json generated
View file

@ -10,7 +10,7 @@
"license": "Unlicense",
"dependencies": {
"cheap-watch": "^1.0.4",
"convict": "^6.2.3",
"convict": "^6.2.4",
"signal-js": "^3.0.1",
"typescript": "^4.8.4",
"ws": "^8.8.1"
@ -25,6 +25,12 @@
"@types/expect": "^24.3.0",
"@types/mocha": "^10.0.0",
"@types/node": "^18.7.23",
"@types/parse-json": "^4.0.0",
"@types/prop-types": "^15.7.5",
"@types/react": "^18.0.34",
"@types/react-is": "^17.0.3",
"@types/react-transition-group": "^4.4.5",
"@types/scheduler": "^0.16.3",
"@types/sinon": "^10.0.13",
"@types/sinon-chai": "^3.2.8",
"@types/ws": "^8.5.3",
@ -32,7 +38,7 @@
"@typescript-eslint/parser": "^5.40.0",
"chai": "^4.3.6",
"eslint": "^8.25.0",
"mocha": "^10.0.0",
"mocha": "^10.1.0",
"nyc": "^15.1.0",
"prettier": "^2.7.1",
"sinon": "^14.0.0",
@ -944,6 +950,53 @@
"integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==",
"dev": true
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"node_modules/@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
},
"node_modules/@types/react": {
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-is": {
"version": "17.0.3",
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
},
"node_modules/@types/sinon": {
"version": "10.0.13",
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz",
@ -1229,12 +1282,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@ungap/promise-all-settled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
"dev": true
},
"node_modules/acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@ -1678,9 +1725,9 @@
"dev": true
},
"node_modules/convict": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/convict/-/convict-6.2.3.tgz",
"integrity": "sha512-mTY04Qr7WrqiXifdeUYXr4/+Te4hPFWDvz6J2FVIKCLc2XBhq63VOSSYAKJ+unhZAYOAjmEdNswTOeHt7s++pQ==",
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz",
"integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==",
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"yargs-parser": "^20.2.7"
@ -1709,6 +1756,12 @@
"node": ">= 8"
}
},
"node_modules/csstype": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"dev": true
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -2913,9 +2966,9 @@
"dev": true
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@ -3074,12 +3127,11 @@
}
},
"node_modules/mocha": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
"integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
"dev": true,
"dependencies": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.3",
@ -5205,6 +5257,53 @@
"integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==",
"dev": true
},
"@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
},
"@types/react": {
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"@types/react-is": {
"version": "17.0.3",
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/scheduler": {
"version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
"dev": true
},
"@types/sinon": {
"version": "10.0.13",
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz",
@ -5389,12 +5488,6 @@
"eslint-visitor-keys": "^3.3.0"
}
},
"@ungap/promise-all-settled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
"dev": true
},
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@ -5721,9 +5814,9 @@
}
},
"convict": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/convict/-/convict-6.2.3.tgz",
"integrity": "sha512-mTY04Qr7WrqiXifdeUYXr4/+Te4hPFWDvz6J2FVIKCLc2XBhq63VOSSYAKJ+unhZAYOAjmEdNswTOeHt7s++pQ==",
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz",
"integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==",
"requires": {
"lodash.clonedeep": "^4.5.0",
"yargs-parser": "^20.2.7"
@ -5746,6 +5839,12 @@
"which": "^2.0.1"
}
},
"csstype": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"dev": true
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -6642,9 +6741,9 @@
"dev": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"just-extend": {
@ -6764,12 +6863,11 @@
}
},
"mocha": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
"integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
"dev": true,
"requires": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.3",

View file

@ -6,6 +6,7 @@
"bin": "./dist/npx/bitburner-filesync.js",
"main": "./dist/npx/bitburner-filesync.js",
"scripts": {
"prepare": "npm run build",
"build": "tsc --build --verbose --pretty",
"clean": "tsc --build --clean",
"format": "prettier -w .",
@ -32,7 +33,7 @@
"homepage": "https://github.com/bitburner-official/bitburner-filesync#readme",
"dependencies": {
"cheap-watch": "^1.0.4",
"convict": "^6.2.3",
"convict": "^6.2.4",
"signal-js": "^3.0.1",
"typescript": "^4.8.4",
"ws": "^8.8.1"
@ -49,9 +50,15 @@
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"@types/parse-json": "^4.0.0",
"@types/react": "^18.0.34",
"@types/react-is": "^17.0.3",
"@types/react-transition-group": "^4.4.5",
"@types/prop-types": "^15.7.5",
"@types/scheduler": "^0.16.3",
"chai": "^4.3.6",
"eslint": "^8.25.0",
"mocha": "^10.0.0",
"mocha": "^10.1.0",
"nyc": "^15.1.0",
"prettier": "^2.7.1",
"sinon": "^14.0.0",

View file

@ -28,6 +28,11 @@ export const config = convict({
env: "BB_SCRIPTFOLDER",
arg: "folder",
},
exclude: {
doc: "A list of folders or files to exclude from the sync.",
format: "Array",
default: [".vscode", ".idea", ".github"],
},
quiet: {
doc: "Log less internal events to stdout.",
format: "Boolean",

View file

@ -1,21 +1,45 @@
import CheapWatch from "cheap-watch";
import { config } from "./config";
import { EventType } from "./eventTypes";
import { config } from "./config.js";
import { EventType } from "./eventTypes.js";
import { mkdir } from "fs/promises";
import { resolve } from "path";
import { resolve, relative, isAbsolute } from "path";
import type { Signal } from "signal-js";
import type { File } from "./interfaces";
import type { File } from "./interfaces.js";
/**
* Returns true if a directory is a subdirectory of a parent directory (not necessarily strict).
* @param dir The directory to perform the check on.
* @param parent The parent directory.
*/
function isSubDirOf(dir: string, parent: string) {
const relPath = relative(resolve(parent), resolve(dir));
return !!relPath && !relPath.startsWith("..") && !isAbsolute(relPath);
}
/**
* Returns true if the given file should be watched.
* @param file The provided file.
*/
function fileFilter(file: File) {
// If the file is excluded, skip all other checks and ignore it.
if (config.get("exclude").some((x) => isSubDirOf(file.path, x))) return false;
if (config.get("allowedFiletypes").some((extension) => file.path.endsWith(extension))) return true;
if (file.stats.isDirectory()) return true;
return false;
}
/**
* Type guard for {@code NodeJS.ErrnoException}.
* @param err
*/
function isError(err: unknown): err is NodeJS.ErrnoException {
return (err as NodeJS.ErrnoException).code !== undefined;
}
/**
* Sets up the file watch.
* @param signaller The signal event emitter.
*/
export async function setupWatch(signaller: Signal) {
try {
await mkdir(resolve(config.get("scriptsFolder")));

View file

@ -1,6 +1,6 @@
import { setupWatch } from "./fileWatch";
import { config, loadConfig } from "./config";
import { setupSocket } from "./networking/webSocket";
import { setupWatch } from "./fileWatch.js";
import { config, loadConfig } from "./config.js";
import { setupSocket } from "./networking/webSocket.js";
import signal from "signal-js";
import { RawData } from "ws";
import {
@ -8,11 +8,14 @@ import {
fileRemovalEventToMsg,
requestFilenames,
requestDefinitionFile,
} from "./networking/messageGenerators";
import { EventType } from "./eventTypes";
import { messageHandler } from "./networking/messageHandler";
import { FileEvent } from "./interfaces";
} from "./networking/messageGenerators.js";
import { EventType } from "./eventTypes.js";
import { messageHandler } from "./networking/messageHandler.js";
import { FileEvent } from "./interfaces.js";
/**
* Starts the file watcher.
*/
export async function start() {
loadConfig();
const watch = await setupWatch(signal);

View file

@ -1,7 +1,7 @@
import { readFileSync } from "fs";
import { config } from "../config";
import { config } from "../config.js";
import { join } from "path";
import type { FileEvent, Message } from "../interfaces";
import type { FileEvent, Message } from "../interfaces.js";
let messageCounter = 0;

View file

@ -1,11 +1,11 @@
import { messageTracker } from "./messageTracker";
import { messageTracker } from "./messageTracker.js";
import { Stats, writeFile } from "fs";
import { RawData } from "ws";
import { config } from "../config";
import { EventType } from "../eventTypes";
import { fileChangeEventToMsg } from "./messageGenerators";
import { config } from "../config.js";
import { EventType } from "../eventTypes.js";
import { fileChangeEventToMsg } from "./messageGenerators.js";
import type { Signal } from "signal-js";
import { Message } from "../interfaces";
import { Message } from "../interfaces.js";
function deserialize(data: RawData): Message {
const msg = JSON.parse(data.toString());

View file

@ -1,4 +1,4 @@
import type { Message } from "../interfaces";
import type { Message } from "../interfaces.js";
class MessageTracker {
data = new Map<number, Message>();

View file

@ -1,9 +1,9 @@
import type { Signal } from "signal-js";
import { WebSocketServer } from "ws";
import { config } from "../config";
import { EventType } from "../eventTypes";
import { Message } from "../interfaces";
import { messageTracker } from "./messageTracker";
import { config } from "../config.js";
import { EventType } from "../eventTypes.js";
import { Message } from "../interfaces.js";
import { messageTracker } from "./messageTracker.js";
export function setupSocket(signaller: Signal) {
const wss = new WebSocketServer({ port: config.get("port") });