syncodemayo 1.0.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/README.md +99 -30
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +66 -0
- package/dist/cli.js.map +1 -0
- package/dist/env.d.ts +1 -0
- package/dist/env.js +17 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/Args.d.ts +21 -0
- package/dist/lib/Args.js +99 -0
- package/dist/lib/Args.js.map +1 -0
- package/{lib → dist/lib}/Cli.d.ts +5 -0
- package/dist/lib/Cli.js +104 -0
- package/dist/lib/Cli.js.map +1 -0
- package/{lib → dist/lib}/Client.d.ts +5 -3
- package/dist/lib/Client.js +73 -0
- package/dist/lib/Client.js.map +1 -0
- package/dist/lib/Config.d.ts +48 -0
- package/dist/lib/Config.js +92 -0
- package/dist/lib/Config.js.map +1 -0
- package/dist/lib/ConfigSchema.d.ts +3 -0
- package/dist/lib/ConfigSchema.js +132 -0
- package/dist/lib/ConfigSchema.js.map +1 -0
- package/dist/lib/Connection.d.ts +41 -0
- package/dist/lib/Connection.js +176 -0
- package/dist/lib/Connection.js.map +1 -0
- package/dist/lib/Filelist.d.ts +42 -0
- package/dist/lib/Filelist.js +156 -0
- package/dist/lib/Filelist.js.map +1 -0
- package/dist/lib/Log.d.ts +12 -0
- package/dist/lib/Log.js +46 -0
- package/dist/lib/Log.js.map +1 -0
- package/dist/lib/Prompt.d.ts +15 -0
- package/dist/lib/Prompt.js +31 -0
- package/dist/lib/Prompt.js.map +1 -0
- package/dist/lib/RemoteConnection.d.ts +37 -0
- package/dist/lib/RemoteConnection.js +2 -0
- package/dist/lib/RemoteConnection.js.map +1 -0
- package/dist/lib/Sync.d.ts +18 -0
- package/dist/lib/Sync.js +127 -0
- package/dist/lib/Sync.js.map +1 -0
- package/dist/lib/TargetServer.d.ts +31 -0
- package/dist/lib/TargetServer.js +76 -0
- package/dist/lib/TargetServer.js.map +1 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/vendor/strip-json-comments.d.ts +23 -0
- package/dist/vendor/strip-json-comments.js +126 -0
- package/dist/vendor/strip-json-comments.js.map +1 -0
- package/package.json +24 -26
- package/.npmignore +0 -9
- package/cli.d.ts +0 -0
- package/cli.js +0 -93
- package/index.d.ts +0 -1
- package/index.js +0 -7
- package/lib/Cli.js +0 -122
- package/lib/Client.js +0 -81
- package/lib/Config.d.ts +0 -32
- package/lib/Config.js +0 -115
- package/lib/ConfigSchema.d.ts +0 -7
- package/lib/ConfigSchema.js +0 -65
- package/lib/Connection.d.ts +0 -14
- package/lib/Connection.js +0 -111
- package/lib/Filelist.d.ts +0 -11
- package/lib/Filelist.js +0 -59
- package/lib/Sync.d.ts +0 -18
- package/lib/Sync.js +0 -141
- package/lib/TargetServer.d.ts +0 -22
- package/lib/TargetServer.js +0 -73
- package/lib/index.d.ts +0 -7
- package/lib/index.js +0 -13
- package/missing-types.d.ts +0 -14
- package/tsconfig.json +0 -48
- package/yarn.lock +0 -975
package/index.js
DELETED
package/lib/Cli.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const Client_1 = require("./Client");
|
|
12
|
-
function changes(configPath, target) {
|
|
13
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
-
const client = yield Client_1.Client.create(configPath);
|
|
15
|
-
const changeset = yield client.getTargetServer(target).sync(true);
|
|
16
|
-
if (changeset == null)
|
|
17
|
-
throw new Error("Change detection failed.");
|
|
18
|
-
const added = changeset.added.length;
|
|
19
|
-
const changed = changeset.changed.length;
|
|
20
|
-
const removed = changeset.removed.length;
|
|
21
|
-
if (added + changed + removed === 0) {
|
|
22
|
-
console.log("\nNo changes detected.");
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
if (added > 0) {
|
|
26
|
-
console.log("\nNew Local Files: (%s)", changeset.added.length);
|
|
27
|
-
changeset.added.forEach(f => console.log(" -", f));
|
|
28
|
-
}
|
|
29
|
-
if (changed > 0) {
|
|
30
|
-
console.log("\nChanged Local Files: (%s)", changeset.changed.length);
|
|
31
|
-
changeset.changed.forEach(f => console.log(" -", f));
|
|
32
|
-
}
|
|
33
|
-
if (removed > 0) {
|
|
34
|
-
console.log(`\nRemoved Local Files${client.config.local.deleteRemoteFiles ? '' : ' (disabled)'}: (%s)`, changeset.removed.length);
|
|
35
|
-
changeset.removed.forEach(f => console.log(" -", f));
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
exports.changes = changes;
|
|
41
|
-
function check(configPath, target) {
|
|
42
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
const client = yield Client_1.Client.create(configPath);
|
|
44
|
-
if (client.hasError) {
|
|
45
|
-
throw client.loadError || client.parseError;
|
|
46
|
-
}
|
|
47
|
-
if (!client.hasConfig && !client.hasError) {
|
|
48
|
-
console.log("This directory isn't configured for SyncoDeMayo!");
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
const targetServer = client.getTargetServer(target);
|
|
52
|
-
const isServerConfigured = yield targetServer.verify();
|
|
53
|
-
if (isServerConfigured) {
|
|
54
|
-
console.log("Target", JSON.stringify(targetServer.name), "is ready for syncing.");
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
console.log("Target", JSON.stringify(targetServer.name), "isn't configured, run init.");
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
return true;
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
exports.check = check;
|
|
64
|
-
function init(configPath, target) {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
const client = yield Client_1.Client.create(configPath);
|
|
67
|
-
if (!client.hasConfig && client.hasError) {
|
|
68
|
-
throw client.loadError || client.parseError;
|
|
69
|
-
}
|
|
70
|
-
if (!client.hasConfig) {
|
|
71
|
-
yield client.createConfig(configPath);
|
|
72
|
-
console.log("Created local config at", configPath);
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
const targetServer = client.getTargetServer(target);
|
|
76
|
-
const isServerConfigured = yield targetServer.verify();
|
|
77
|
-
if (!isServerConfigured) {
|
|
78
|
-
yield targetServer.prepare();
|
|
79
|
-
console.log("Created", targetServer.config.cache, "on server target", targetServer.config._name);
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
console.log("Everything seems to be configured correctly.");
|
|
83
|
-
return false;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
exports.init = init;
|
|
87
|
-
function ls(configPath) {
|
|
88
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
const client = yield Client_1.Client.create(configPath);
|
|
90
|
-
const targets = yield client.getTargetNames();
|
|
91
|
-
console.log("Defined server targets:");
|
|
92
|
-
targets.forEach(name => {
|
|
93
|
-
const target = client.config.targets[name];
|
|
94
|
-
const bullet = client.config.local.defaultTarget === target._name
|
|
95
|
-
? " *"
|
|
96
|
-
: " -";
|
|
97
|
-
console.log(bullet, name, `\t(${target.user}@${target.host}:${target.path})`);
|
|
98
|
-
});
|
|
99
|
-
return true;
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
exports.ls = ls;
|
|
103
|
-
function sync(configPath, target, forceConfirmation = false) {
|
|
104
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
const client = yield Client_1.Client.create(configPath);
|
|
106
|
-
if (!client.hasConfig) {
|
|
107
|
-
if (client.hasError)
|
|
108
|
-
throw client.loadError || client.parseError;
|
|
109
|
-
else
|
|
110
|
-
throw new Error("This directory isn't configured for SyncoDeMayo!");
|
|
111
|
-
}
|
|
112
|
-
const changes = yield client.getTargetServer(target).sync(false, forceConfirmation);
|
|
113
|
-
if (changes != null) {
|
|
114
|
-
console.log("\nSummary:");
|
|
115
|
-
console.log("- %s files uploaded.", changes.added.length + changes.changed.length);
|
|
116
|
-
console.log(`- %s files removed. ${client.config.local.deleteRemoteFiles ? '' : '(disabled)'}`, changes.removed.length);
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
exports.sync = sync;
|
|
122
|
-
//# sourceMappingURL=Cli.js.map
|
package/lib/Client.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const path_1 = require("path");
|
|
12
|
-
const Config_1 = require("./Config");
|
|
13
|
-
const TargetServer_1 = require("./TargetServer");
|
|
14
|
-
const ConfigSchema_1 = require("./ConfigSchema");
|
|
15
|
-
const Filelist_1 = require("./Filelist");
|
|
16
|
-
class Client {
|
|
17
|
-
constructor(preferredPath) {
|
|
18
|
-
this.hasConfig = null;
|
|
19
|
-
this.DEFAULT_CONFIG = "syncodemayo.json";
|
|
20
|
-
this._path = preferredPath;
|
|
21
|
-
this.whenReady = new Promise((resolve) => {
|
|
22
|
-
Config_1.loadConfigFile(preferredPath)
|
|
23
|
-
.then((config) => {
|
|
24
|
-
this.config = config;
|
|
25
|
-
this._path = this.config._path;
|
|
26
|
-
this.hasConfig = true;
|
|
27
|
-
resolve(this);
|
|
28
|
-
})
|
|
29
|
-
.catch((err) => {
|
|
30
|
-
if (err.message.indexOf('Schema Error'))
|
|
31
|
-
this.loadError = err;
|
|
32
|
-
if (err.message.indexOf('JSON'))
|
|
33
|
-
this.parseError = err;
|
|
34
|
-
this.hasConfig = false;
|
|
35
|
-
resolve(this);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
get hasError() {
|
|
40
|
-
return !!this.loadError || !!this.parseError;
|
|
41
|
-
}
|
|
42
|
-
createConfig(preferredPath) {
|
|
43
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
-
const path = path_1.resolve(preferredPath || this._path || this.DEFAULT_CONFIG);
|
|
45
|
-
const alreadyExists = yield Filelist_1.localFileExists(path);
|
|
46
|
-
if (alreadyExists) {
|
|
47
|
-
throw new Error("Config already exists at " + path);
|
|
48
|
-
}
|
|
49
|
-
Filelist_1.writeLocalFile(path, JSON.stringify(ConfigSchema_1.DefaultConfig, null, 2));
|
|
50
|
-
return true;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
getTargetNames() {
|
|
54
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
-
if (this.hasConfig === null)
|
|
56
|
-
throw new Error("Config not loaded yet.");
|
|
57
|
-
if (this.hasConfig === false) {
|
|
58
|
-
if (this.hasError) {
|
|
59
|
-
const error = this.loadError || this.parseError;
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
throw new Error("This directory has no SyncoDeMayo config.");
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return Object.keys(this.config.targets).filter(name => this.config.targets[name].enabled);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
getTargetConfig(name) {
|
|
70
|
-
return Config_1.resolveTarget(this.config, name);
|
|
71
|
-
}
|
|
72
|
-
getTargetServer(name) {
|
|
73
|
-
return TargetServer_1.TargetServer.create(this.config, name);
|
|
74
|
-
}
|
|
75
|
-
static create(configPath) {
|
|
76
|
-
const client = new Client(configPath);
|
|
77
|
-
return client.whenReady;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
exports.Client = Client;
|
|
81
|
-
//# sourceMappingURL=Client.js.map
|
package/lib/Config.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export interface IConfig {
|
|
2
|
-
local: ILocalConfig;
|
|
3
|
-
targets: {
|
|
4
|
-
[name: string]: ITargetConfig;
|
|
5
|
-
};
|
|
6
|
-
_path?: string;
|
|
7
|
-
}
|
|
8
|
-
export interface ILocalConfig {
|
|
9
|
-
path: string;
|
|
10
|
-
files: string;
|
|
11
|
-
exclude: string[];
|
|
12
|
-
defaultTarget: string;
|
|
13
|
-
deleteRemoteFiles: boolean;
|
|
14
|
-
}
|
|
15
|
-
export interface ITargetConfig {
|
|
16
|
-
host: string;
|
|
17
|
-
user: string;
|
|
18
|
-
pass?: string;
|
|
19
|
-
path: string;
|
|
20
|
-
port: number;
|
|
21
|
-
cache: string;
|
|
22
|
-
prompt?: boolean | string;
|
|
23
|
-
_name: string;
|
|
24
|
-
enabled?: boolean;
|
|
25
|
-
type?: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Sending nulll as the preferred path will result in scan for the config
|
|
29
|
-
*/
|
|
30
|
-
export declare function loadConfigFile(preferredPath?: string): Promise<IConfig>;
|
|
31
|
-
export declare function resolvePassword(targetConfig: ITargetConfig): string;
|
|
32
|
-
export declare function resolveTarget(config: IConfig, name: string | ITargetConfig | undefined): ITargetConfig;
|
package/lib/Config.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const path_1 = require("path");
|
|
12
|
-
const ConfigSchema_1 = require("./ConfigSchema");
|
|
13
|
-
const Filelist_1 = require("./Filelist");
|
|
14
|
-
const stripJsonComments = require("strip-json-comments");
|
|
15
|
-
function evalConfigFromFile(pathname) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
if (typeof pathname !== 'string')
|
|
18
|
-
throw new Error(`Path must be a string. Got a ${typeof pathname}`);
|
|
19
|
-
const fullpath = path_1.resolve("./" + pathname);
|
|
20
|
-
if (!Filelist_1.localFileExists(fullpath))
|
|
21
|
-
throw new Error("SKIP");
|
|
22
|
-
const source = yield Filelist_1.readLocalFile(fullpath, false);
|
|
23
|
-
const data = JSON.parse(stripJsonComments(source));
|
|
24
|
-
// const data = require(fullpath) as IConfig
|
|
25
|
-
if (typeof data === 'object')
|
|
26
|
-
data._path = fullpath;
|
|
27
|
-
return data;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Sending nulll as the preferred path will result in scan for the config
|
|
32
|
-
*/
|
|
33
|
-
function loadConfigFile(preferredPath) {
|
|
34
|
-
const loadingPromise = new Promise((resolve, reject) => {
|
|
35
|
-
const potentialConfigs = (!!preferredPath)
|
|
36
|
-
? [preferredPath]
|
|
37
|
-
: [
|
|
38
|
-
'syncodemayo.json',
|
|
39
|
-
'.syncodemayo.json',
|
|
40
|
-
'syncodemayo.js',
|
|
41
|
-
'.syncodemayo.js',
|
|
42
|
-
'.syncodemayo',
|
|
43
|
-
'sync-config.json',
|
|
44
|
-
'sync-config.js',
|
|
45
|
-
'.sync-config',
|
|
46
|
-
];
|
|
47
|
-
const tryLoading = (path) => {
|
|
48
|
-
// console.log("Trying to load config:", path)
|
|
49
|
-
if (!!path) {
|
|
50
|
-
evalConfigFromFile(path)
|
|
51
|
-
.then(resolve)
|
|
52
|
-
.catch(err => {
|
|
53
|
-
if (err.message === "SKIP")
|
|
54
|
-
tryLoading(potentialConfigs.shift());
|
|
55
|
-
else
|
|
56
|
-
reject(err);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
reject(new Error("Local config not found."));
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
// Kick off config loading...
|
|
64
|
-
tryLoading(potentialConfigs.shift());
|
|
65
|
-
});
|
|
66
|
-
return loadingPromise
|
|
67
|
-
.then(ConfigSchema_1.validateConfig)
|
|
68
|
-
.then(massageConfigData);
|
|
69
|
-
}
|
|
70
|
-
exports.loadConfigFile = loadConfigFile;
|
|
71
|
-
function massageConfigData(config) {
|
|
72
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
-
config.local.files = config.local.files || '**/**';
|
|
74
|
-
config.local.exclude = config.local.exclude || [];
|
|
75
|
-
config.local.defaultTarget = config.local.defaultTarget || "staging";
|
|
76
|
-
config.local.deleteRemoteFiles = config.local.deleteRemoteFiles === true;
|
|
77
|
-
Object.keys(config.targets).forEach(name => {
|
|
78
|
-
const target = config.targets[name];
|
|
79
|
-
target._name = name;
|
|
80
|
-
target.port = target.port || 21;
|
|
81
|
-
target.cache = target.cache || ".synco-filelist";
|
|
82
|
-
target.enabled = target.enabled !== false;
|
|
83
|
-
target.type = target.type || 'ftp'; // Will support more eventually
|
|
84
|
-
if (typeof target.prompt === 'undefined')
|
|
85
|
-
target.prompt = true;
|
|
86
|
-
});
|
|
87
|
-
return config;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function resolvePassword(targetConfig) {
|
|
91
|
-
const password = targetConfig.pass || process.env[`${targetConfig._name.toUpperCase()}_PWD`];
|
|
92
|
-
if (typeof password === 'undefined') {
|
|
93
|
-
throw new Error("Cannot find password for target: " + targetConfig._name);
|
|
94
|
-
}
|
|
95
|
-
return password;
|
|
96
|
-
}
|
|
97
|
-
exports.resolvePassword = resolvePassword;
|
|
98
|
-
function resolveTarget(config, name) {
|
|
99
|
-
if (typeof name === 'undefined')
|
|
100
|
-
name = config.local.defaultTarget;
|
|
101
|
-
if (typeof name === 'object')
|
|
102
|
-
return name;
|
|
103
|
-
const lookingFor = name;
|
|
104
|
-
const targetName = Object.keys(config.targets).find(namedTarget => (lookingFor.toUpperCase() === config.targets[namedTarget]._name.toUpperCase()));
|
|
105
|
-
if (!targetName) {
|
|
106
|
-
throw new Error("Target '" + name + "' not found.");
|
|
107
|
-
}
|
|
108
|
-
const target = config.targets[targetName];
|
|
109
|
-
if (!target.enabled) {
|
|
110
|
-
throw new Error("Target '" + name + "' not enabled.");
|
|
111
|
-
}
|
|
112
|
-
return target;
|
|
113
|
-
}
|
|
114
|
-
exports.resolveTarget = resolveTarget;
|
|
115
|
-
//# sourceMappingURL=Config.js.map
|
package/lib/ConfigSchema.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { IConfig } from './Config';
|
|
2
|
-
import * as joi from 'joi';
|
|
3
|
-
export declare const localSchema: joi.ObjectSchema;
|
|
4
|
-
export declare const targetSchema: joi.ObjectSchema;
|
|
5
|
-
export declare const configSchema: joi.ObjectSchema;
|
|
6
|
-
export declare function validateConfig(config: IConfig): Promise<IConfig>;
|
|
7
|
-
export declare const DefaultConfig: any;
|
package/lib/ConfigSchema.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const joi = require("joi");
|
|
12
|
-
exports.localSchema = joi.object({
|
|
13
|
-
path: joi.string().required(),
|
|
14
|
-
files: joi.string(),
|
|
15
|
-
exclude: joi.array().items(joi.string()),
|
|
16
|
-
defaultTarget: joi.string(),
|
|
17
|
-
deleteRemoteFiles: joi.bool(),
|
|
18
|
-
});
|
|
19
|
-
exports.targetSchema = joi.object({
|
|
20
|
-
host: joi.string().required(),
|
|
21
|
-
user: joi.string().required(),
|
|
22
|
-
path: joi.string().required(),
|
|
23
|
-
pass: joi.string(),
|
|
24
|
-
port: joi.number(),
|
|
25
|
-
cache: joi.string(),
|
|
26
|
-
prompt: joi.alternatives([joi.bool(), joi.string()]),
|
|
27
|
-
enabled: joi.bool(),
|
|
28
|
-
// For future use...
|
|
29
|
-
type: joi.string(),
|
|
30
|
-
});
|
|
31
|
-
exports.configSchema = joi.object({
|
|
32
|
-
local: exports.localSchema.required(),
|
|
33
|
-
targets: joi.object().pattern(/.*/, exports.targetSchema).required()
|
|
34
|
-
}).unknown(true);
|
|
35
|
-
function validateConfig(config) {
|
|
36
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
const result = exports.configSchema.validate(config);
|
|
38
|
-
if (!!result.error)
|
|
39
|
-
throw new Error("Config Schema Error: " + result.error.message);
|
|
40
|
-
return config;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
exports.validateConfig = validateConfig;
|
|
44
|
-
exports.DefaultConfig = {
|
|
45
|
-
local: {
|
|
46
|
-
path: "public",
|
|
47
|
-
files: "**/**",
|
|
48
|
-
exclude: ["**/*.map", "**/.DS_Store", "**/.git*"],
|
|
49
|
-
defaultTarget: "staging"
|
|
50
|
-
},
|
|
51
|
-
targets: {
|
|
52
|
-
staging: {
|
|
53
|
-
path: "Example/www/stage",
|
|
54
|
-
host: "www.example.com",
|
|
55
|
-
user: "USERNAME"
|
|
56
|
-
},
|
|
57
|
-
production: {
|
|
58
|
-
path: "Example/www",
|
|
59
|
-
host: "www.example.com",
|
|
60
|
-
user: "USERNAME",
|
|
61
|
-
prompt: "This will upload to PRODUCTION! Are you sure?"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=ConfigSchema.js.map
|
package/lib/Connection.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { ITargetConfig } from './Config';
|
|
2
|
-
export declare class Connection {
|
|
3
|
-
private _ftpConn;
|
|
4
|
-
constructor(host: string, port: number, user: string, pass: string);
|
|
5
|
-
getRemoteFile(filename: string): Promise<string>;
|
|
6
|
-
remoteDirectoryExists(pathname: string): Promise<boolean>;
|
|
7
|
-
remoteFileExists(remotePath: string): Promise<boolean>;
|
|
8
|
-
putBuffer(buff: any, remotePath: string): Promise<boolean>;
|
|
9
|
-
putContent(content: string, remotePath: string): Promise<boolean>;
|
|
10
|
-
putFile(filename: string, remotePath: string): Promise<string>;
|
|
11
|
-
deleteRemoteFile(remotePath: string): Promise<boolean>;
|
|
12
|
-
close(): void;
|
|
13
|
-
static create(target: ITargetConfig): Connection;
|
|
14
|
-
}
|
package/lib/Connection.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const JsFtp = require("jsftp");
|
|
12
|
-
const JsFtpMkDirP = require("jsftp-mkdirp");
|
|
13
|
-
const Config_1 = require("./Config");
|
|
14
|
-
const Filelist_1 = require("./Filelist");
|
|
15
|
-
const Ftp = JsFtpMkDirP(JsFtp);
|
|
16
|
-
/*
|
|
17
|
-
TODO: Extract FTP from the connection to allow other connection types.. File/SFTP/S3/whatever
|
|
18
|
-
*/
|
|
19
|
-
// interface IRemoteConnection {
|
|
20
|
-
// get(filepath): Promise<string>
|
|
21
|
-
// put(filepath): Promise<boolean>
|
|
22
|
-
// }
|
|
23
|
-
class Connection {
|
|
24
|
-
constructor(host, port, user, pass) {
|
|
25
|
-
// log("Connecting to FTP:", { host, port, user, pass: `(${pass.length} chars)` })
|
|
26
|
-
this._ftpConn = new Ftp({ host, port, user, pass });
|
|
27
|
-
process.on('beforeExit', () => {
|
|
28
|
-
this.close(); // Ensure all connections are close when the app exits
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
getRemoteFile(filename) {
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
let content = "";
|
|
34
|
-
console.log(" <-", filename);
|
|
35
|
-
this._ftpConn.get(filename, function (err, socket) {
|
|
36
|
-
if (err != null) {
|
|
37
|
-
return reject(err);
|
|
38
|
-
}
|
|
39
|
-
socket.on("data", (d) => content += d.toString());
|
|
40
|
-
socket.on('error', (err) => {
|
|
41
|
-
console.log("Retrieval error.");
|
|
42
|
-
reject(err);
|
|
43
|
-
});
|
|
44
|
-
socket.on("close", (connErr) => {
|
|
45
|
-
if (connErr)
|
|
46
|
-
reject(connErr);
|
|
47
|
-
else
|
|
48
|
-
resolve(content);
|
|
49
|
-
});
|
|
50
|
-
socket.resume();
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
remoteDirectoryExists(pathname) {
|
|
55
|
-
return new Promise((resolve, reject) => {
|
|
56
|
-
this._ftpConn.mkdirp(pathname, (err) => resolve(!err));
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
remoteFileExists(remotePath) {
|
|
60
|
-
return new Promise((resolve, reject) => {
|
|
61
|
-
this._ftpConn.raw.size(remotePath, (err, size) => resolve(!err));
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
putBuffer(buff, remotePath) {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
console.log(" ->", remotePath);
|
|
67
|
-
this._ftpConn.put(buff, remotePath, (err) => {
|
|
68
|
-
if (err)
|
|
69
|
-
reject(err);
|
|
70
|
-
else
|
|
71
|
-
resolve(true);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
putContent(content, remotePath) {
|
|
76
|
-
return this.putBuffer(new Buffer(content), remotePath);
|
|
77
|
-
}
|
|
78
|
-
putFile(filename, remotePath) {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
-
const buffer = yield Filelist_1.readLocalFile(filename, true);
|
|
81
|
-
yield this.putBuffer(buffer, remotePath);
|
|
82
|
-
return remotePath;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
deleteRemoteFile(remotePath) {
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
console.log(" x", remotePath);
|
|
88
|
-
this._ftpConn.raw('dele', remotePath, function (err, data) {
|
|
89
|
-
if (err)
|
|
90
|
-
console.log("Error removing", remotePath, err.message);
|
|
91
|
-
if (err)
|
|
92
|
-
resolve(false);
|
|
93
|
-
else
|
|
94
|
-
resolve(true);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
close() {
|
|
99
|
-
const conn = this._ftpConn;
|
|
100
|
-
conn && conn.raw && conn.raw.quit && conn.raw.quit((err, data) => {
|
|
101
|
-
if (err != null)
|
|
102
|
-
console.error(err);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
static create(target) {
|
|
106
|
-
const pass = Config_1.resolvePassword(target);
|
|
107
|
-
return new Connection(target.host, target.port, target.user, pass);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
exports.Connection = Connection;
|
|
111
|
-
//# sourceMappingURL=Connection.js.map
|
package/lib/Filelist.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { ILocalConfig, ITargetConfig } from './Config';
|
|
3
|
-
import { Connection } from './Connection';
|
|
4
|
-
export interface IFilelist {
|
|
5
|
-
[filename: string]: number;
|
|
6
|
-
}
|
|
7
|
-
export declare function localFileExists(path: string): Promise<boolean>;
|
|
8
|
-
export declare function readLocalFile(path: string, asBuffer?: boolean): Promise<string | Buffer>;
|
|
9
|
-
export declare function writeLocalFile(path: string, content: string): Promise<any>;
|
|
10
|
-
export declare function getRemoteFilelist(target: ITargetConfig, conn: Connection): Promise<IFilelist>;
|
|
11
|
-
export declare function buildLocalFilelist(config: ILocalConfig): Promise<IFilelist>;
|
package/lib/Filelist.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const glob = require("glob");
|
|
12
|
-
const minimatch = require("minimatch");
|
|
13
|
-
const crc = require("crc");
|
|
14
|
-
const fs = require("fs");
|
|
15
|
-
function localFileExists(path) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
return fs.existsSync(path);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
exports.localFileExists = localFileExists;
|
|
21
|
-
function readLocalFile(path, asBuffer = false) {
|
|
22
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
-
const buff = fs.readFileSync(path);
|
|
24
|
-
return asBuffer ? buff : buff.toString();
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
exports.readLocalFile = readLocalFile;
|
|
28
|
-
function writeLocalFile(path, content) {
|
|
29
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
-
return fs.writeFileSync(path, content);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
exports.writeLocalFile = writeLocalFile;
|
|
34
|
-
function getRemoteFilelist(target, conn) {
|
|
35
|
-
const path = `${target.path}/${target.cache}`;
|
|
36
|
-
// console.log(" <-", path)
|
|
37
|
-
return conn.getRemoteFile(path)
|
|
38
|
-
.then(JSON.parse)
|
|
39
|
-
.catch((err) => {
|
|
40
|
-
console.log("Missing or error parsing remote file list.", err);
|
|
41
|
-
console.log("\n Run sync:init to setup SyncoDeMayo on the server.\n");
|
|
42
|
-
process.exit(1);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
exports.getRemoteFilelist = getRemoteFilelist;
|
|
46
|
-
function buildLocalFilelist(config) {
|
|
47
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
// Create the CRCs...
|
|
49
|
-
const excludeDirectories = (path) => !fs.statSync(path).isDirectory();
|
|
50
|
-
const excludeBlacklistedFiles = (path) => !config.exclude.some(pattern => minimatch(path, pattern, { dot: true }));
|
|
51
|
-
return glob
|
|
52
|
-
.sync(`${config.path}/${config.files}`)
|
|
53
|
-
.filter(excludeDirectories)
|
|
54
|
-
.filter(excludeBlacklistedFiles)
|
|
55
|
-
.reduce((hash, filepath) => (hash[filepath] = crc.crc32(fs.readFileSync(filepath)), hash), {});
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
exports.buildLocalFilelist = buildLocalFilelist;
|
|
59
|
-
//# sourceMappingURL=Filelist.js.map
|
package/lib/Sync.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { IConfig, ITargetConfig } from './Config';
|
|
2
|
-
import { Connection } from './Connection';
|
|
3
|
-
export interface IChangeset {
|
|
4
|
-
added: string[];
|
|
5
|
-
changed: string[];
|
|
6
|
-
removed: string[];
|
|
7
|
-
}
|
|
8
|
-
export declare class Sync {
|
|
9
|
-
private _conn;
|
|
10
|
-
private _config;
|
|
11
|
-
private _target;
|
|
12
|
-
constructor(conn: Connection, config: IConfig, target: string | ITargetConfig);
|
|
13
|
-
run(isDryRun?: boolean, forceConfirmation?: boolean): Promise<IChangeset | null>;
|
|
14
|
-
private _confirmUpload(target, fileCount);
|
|
15
|
-
private _getFilelists(local, target, conn);
|
|
16
|
-
private _buildChangeset(localFiles, remoteFiles);
|
|
17
|
-
static create(conn: Connection, config: IConfig, target: string | ITargetConfig): Sync;
|
|
18
|
-
}
|