syncodemayo 1.0.9 → 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 +91 -25
- 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 +1 -1
- package/dist/lib/Cli.js +104 -0
- package/dist/lib/Cli.js.map +1 -0
- package/{lib → dist/lib}/Client.d.ts +4 -4
- 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/{lib → dist/lib}/Log.d.ts +1 -1
- package/{lib → dist/lib}/Log.js +9 -16
- 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 -102
- package/index.d.ts +0 -1
- package/index.js +0 -7
- package/lib/Cli.js +0 -130
- package/lib/Client.js +0 -85
- package/lib/Config.d.ts +0 -32
- package/lib/Config.js +0 -114
- 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 -112
- 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 -140
- package/lib/TargetServer.d.ts +0 -22
- package/lib/TargetServer.js +0 -74
- 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
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as Log from './Log.js';
|
|
2
|
+
import { resolveTarget } from './Config.js';
|
|
3
|
+
import { Connection } from './Connection.js';
|
|
4
|
+
import { Sync } from './Sync.js';
|
|
5
|
+
export class TargetServer {
|
|
6
|
+
get config() {
|
|
7
|
+
return this._targetConfig;
|
|
8
|
+
}
|
|
9
|
+
get name() {
|
|
10
|
+
return this.config._name;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* `connect` opens the connection for each operation. It defaults to FTP/FTPS (`Connection`);
|
|
14
|
+
* tests pass a fake.
|
|
15
|
+
*/
|
|
16
|
+
constructor(config, target, connect = Connection.create) {
|
|
17
|
+
this._config = config;
|
|
18
|
+
this._targetConfig = resolveTarget(config, target);
|
|
19
|
+
this._connect = connect;
|
|
20
|
+
}
|
|
21
|
+
// Opens a connection, runs `task` with it, and closes it, whether `task` resolves or rejects.
|
|
22
|
+
async _withConnection(task) {
|
|
23
|
+
const conn = this._connect(this._targetConfig);
|
|
24
|
+
try {
|
|
25
|
+
return await task(conn);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
try {
|
|
29
|
+
await conn.close();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
Log.debug("Error closing the connection:", err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Add a cache file, if there's not one. `target.path` must already exist: a missing path is
|
|
38
|
+
* most likely a typo, so this rejects (telling the user to create the folder) and creates
|
|
39
|
+
* nothing.
|
|
40
|
+
*/
|
|
41
|
+
async prepare(force) {
|
|
42
|
+
const remoteCachePath = `${this._targetConfig.path}/${this._targetConfig.cache}`;
|
|
43
|
+
return this._withConnection(async (conn) => {
|
|
44
|
+
const remoteIsConfigured = await conn.remoteFileExists(remoteCachePath);
|
|
45
|
+
if (remoteIsConfigured && force !== true) {
|
|
46
|
+
Log.info(`${this._targetConfig.host} already is initialized.`);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const { path, host } = this._targetConfig;
|
|
50
|
+
const remoteDirFound = await conn.remoteDirectoryFound(path);
|
|
51
|
+
if (!remoteDirFound) {
|
|
52
|
+
throw new Error(`Remote path "${path}" not found on ${host}. ` +
|
|
53
|
+
`Check the target's "path", or create the folder on the server, then run init again.`);
|
|
54
|
+
}
|
|
55
|
+
await conn.putContent("{}", remoteCachePath);
|
|
56
|
+
return true;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Verify the server has a cache file
|
|
61
|
+
*/
|
|
62
|
+
async verify() {
|
|
63
|
+
const remoteCachePath = `${this._targetConfig.path}/${this._targetConfig.cache}`;
|
|
64
|
+
return this._withConnection(conn => conn.remoteFileExists(remoteCachePath));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sync local files to target server
|
|
68
|
+
*/
|
|
69
|
+
async sync(isDryRun, forceConfirmation = false) {
|
|
70
|
+
return this._withConnection(conn => Sync.create(conn, this._config, this._targetConfig).run(isDryRun, forceConfirmation));
|
|
71
|
+
}
|
|
72
|
+
static create(config, targetConfig, connect) {
|
|
73
|
+
return new TargetServer(config, targetConfig, connect);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=TargetServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TargetServer.js","sourceRoot":"./","sources":["lib/TargetServer.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Log from './Log.js'\nimport { IConfig, ITargetConfig, resolveTarget } from './Config.js'\nimport { Connection } from './Connection.js'\nimport { ConnectionFactory, RemoteConnection } from './RemoteConnection.js'\nimport { Sync, IChangeset } from './Sync.js'\n\nexport class TargetServer {\n private _config: IConfig\n private _targetConfig: ITargetConfig\n private _connect: ConnectionFactory\n\n get config() {\n return this._targetConfig\n }\n\n get name() {\n return this.config._name\n }\n\n /**\n * `connect` opens the connection for each operation. It defaults to FTP/FTPS (`Connection`);\n * tests pass a fake.\n */\n constructor(config: IConfig, target: string | ITargetConfig | undefined, connect: ConnectionFactory = Connection.create) {\n this._config = config\n this._targetConfig = resolveTarget(config, target)\n this._connect = connect\n }\n\n // Opens a connection, runs `task` with it, and closes it, whether `task` resolves or rejects.\n private async _withConnection<T>(task: (conn: RemoteConnection) => Promise<T>): Promise<T> {\n const conn = this._connect(this._targetConfig)\n try {\n return await task(conn)\n }\n finally {\n try {\n await conn.close()\n }\n catch (err) {\n Log.debug(\"Error closing the connection:\", err)\n }\n }\n }\n\n /**\n * Add a cache file, if there's not one. `target.path` must already exist: a missing path is\n * most likely a typo, so this rejects (telling the user to create the folder) and creates\n * nothing.\n */\n async prepare(force?: boolean): Promise<boolean> {\n const remoteCachePath = `${this._targetConfig.path}/${this._targetConfig.cache}`\n return this._withConnection(async (conn) => {\n const remoteIsConfigured = await conn.remoteFileExists(remoteCachePath)\n\n if (remoteIsConfigured && force !== true) {\n Log.info(`${this._targetConfig.host} already is initialized.`)\n return false\n }\n\n const { path, host } = this._targetConfig\n const remoteDirFound = await conn.remoteDirectoryFound(path)\n if (!remoteDirFound) {\n throw new Error(\n `Remote path \"${path}\" not found on ${host}. ` +\n `Check the target's \"path\", or create the folder on the server, then run init again.`)\n }\n\n await conn.putContent(\"{}\", remoteCachePath)\n\n return true\n })\n }\n\n /**\n * Verify the server has a cache file\n */\n async verify(): Promise<boolean> {\n const remoteCachePath = `${this._targetConfig.path}/${this._targetConfig.cache}`\n return this._withConnection(conn => conn.remoteFileExists(remoteCachePath))\n }\n\n /**\n * Sync local files to target server\n */\n async sync(isDryRun: boolean, forceConfirmation = false): Promise<IChangeset | null> {\n return this._withConnection(conn =>\n Sync.create(conn, this._config, this._targetConfig).run(isDryRun, forceConfirmation))\n }\n\n static create(config: IConfig, targetConfig: string | ITargetConfig | undefined, connect?: ConnectionFactory): TargetServer {\n return new TargetServer(config, targetConfig, connect)\n }\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './Client.js';
|
|
2
|
+
export * from './Config.js';
|
|
3
|
+
export * from './ConfigSchema.js';
|
|
4
|
+
export * from './Connection.js';
|
|
5
|
+
export * from './Filelist.js';
|
|
6
|
+
export * from './RemoteConnection.js';
|
|
7
|
+
export * from './Sync.js';
|
|
8
|
+
export * from './TargetServer.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './Client.js';
|
|
2
|
+
export * from './Config.js';
|
|
3
|
+
export * from './ConfigSchema.js';
|
|
4
|
+
export * from './Connection.js';
|
|
5
|
+
export * from './Filelist.js';
|
|
6
|
+
export * from './RemoteConnection.js';
|
|
7
|
+
export * from './Sync.js';
|
|
8
|
+
export * from './TargetServer.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"./","sources":["lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './Client.js'\nexport * from './Config.js'\nexport * from './ConfigSchema.js'\nexport * from './Connection.js'\nexport * from './Filelist.js'\nexport * from './RemoteConnection.js'\nexport * from './Sync.js'\nexport * from './TargetServer.js'"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type Options = {
|
|
2
|
+
/**
|
|
3
|
+
Strip trailing commas in addition to comments.
|
|
4
|
+
|
|
5
|
+
@default false
|
|
6
|
+
*/
|
|
7
|
+
readonly trailingCommas?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
Replace comments and trailing commas with whitespace instead of stripping them entirely.
|
|
10
|
+
|
|
11
|
+
@default true
|
|
12
|
+
*/
|
|
13
|
+
readonly whitespace?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
Strip comments from JSON. Lets you use comments in your JSON files!
|
|
17
|
+
|
|
18
|
+
It will replace single-line comments `//` and multi-line comments `/**\/` with whitespace. This allows JSON error positions to remain as close as possible to the original source.
|
|
19
|
+
|
|
20
|
+
@param jsonString - Accepts a string with JSON.
|
|
21
|
+
@returns A JSON string without comments.
|
|
22
|
+
*/
|
|
23
|
+
export default function stripJsonComments(jsonString: string, { whitespace, trailingCommas }?: Options): string;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
+
|
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
11
|
+
*/
|
|
12
|
+
const singleComment = Symbol('singleComment');
|
|
13
|
+
const multiComment = Symbol('multiComment');
|
|
14
|
+
const stripWithoutWhitespace = (_string, _start, _end) => '';
|
|
15
|
+
// Replace all characters except ASCII spaces, tabs and line endings with regular spaces to ensure valid JSON output.
|
|
16
|
+
const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/[^ \t\r\n]/g, ' ');
|
|
17
|
+
const isEscaped = (jsonString, quotePosition) => {
|
|
18
|
+
let index = quotePosition - 1;
|
|
19
|
+
let backslashCount = 0;
|
|
20
|
+
while (jsonString[index] === '\\') {
|
|
21
|
+
index -= 1;
|
|
22
|
+
backslashCount += 1;
|
|
23
|
+
}
|
|
24
|
+
return Boolean(backslashCount % 2);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
Strip comments from JSON. Lets you use comments in your JSON files!
|
|
28
|
+
|
|
29
|
+
It will replace single-line comments `//` and multi-line comments `/**\/` with whitespace. This allows JSON error positions to remain as close as possible to the original source.
|
|
30
|
+
|
|
31
|
+
@param jsonString - Accepts a string with JSON.
|
|
32
|
+
@returns A JSON string without comments.
|
|
33
|
+
*/
|
|
34
|
+
export default function stripJsonComments(jsonString, { whitespace = true, trailingCommas = false } = {}) {
|
|
35
|
+
if (typeof jsonString !== 'string') {
|
|
36
|
+
throw new TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``);
|
|
37
|
+
}
|
|
38
|
+
const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
|
|
39
|
+
let isInsideString = false;
|
|
40
|
+
let isInsideComment = false;
|
|
41
|
+
let offset = 0;
|
|
42
|
+
let buffer = '';
|
|
43
|
+
let result = '';
|
|
44
|
+
let commaIndex = -1;
|
|
45
|
+
for (let index = 0; index < jsonString.length; index++) {
|
|
46
|
+
const currentCharacter = jsonString[index];
|
|
47
|
+
const nextCharacter = jsonString[index + 1];
|
|
48
|
+
if (!isInsideComment && currentCharacter === '"') {
|
|
49
|
+
// Enter or exit string
|
|
50
|
+
const escaped = isEscaped(jsonString, index);
|
|
51
|
+
if (!escaped) {
|
|
52
|
+
isInsideString = !isInsideString;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (isInsideString) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!isInsideComment && currentCharacter + nextCharacter === '//') {
|
|
59
|
+
// Enter single-line comment
|
|
60
|
+
buffer += jsonString.slice(offset, index);
|
|
61
|
+
offset = index;
|
|
62
|
+
isInsideComment = singleComment;
|
|
63
|
+
index++;
|
|
64
|
+
}
|
|
65
|
+
else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
|
|
66
|
+
// Exit single-line comment via \r\n
|
|
67
|
+
index++;
|
|
68
|
+
isInsideComment = false;
|
|
69
|
+
buffer += strip(jsonString, offset, index);
|
|
70
|
+
offset = index;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
else if (isInsideComment === singleComment && currentCharacter === '\n') {
|
|
74
|
+
// Exit single-line comment via \n
|
|
75
|
+
isInsideComment = false;
|
|
76
|
+
buffer += strip(jsonString, offset, index);
|
|
77
|
+
offset = index;
|
|
78
|
+
}
|
|
79
|
+
else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
|
|
80
|
+
// Enter multiline comment
|
|
81
|
+
buffer += jsonString.slice(offset, index);
|
|
82
|
+
offset = index;
|
|
83
|
+
isInsideComment = multiComment;
|
|
84
|
+
index++;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
|
|
88
|
+
// Exit multiline comment
|
|
89
|
+
index++;
|
|
90
|
+
isInsideComment = false;
|
|
91
|
+
buffer += strip(jsonString, offset, index + 1);
|
|
92
|
+
offset = index + 1;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
else if (trailingCommas && !isInsideComment) {
|
|
96
|
+
if (commaIndex !== -1) {
|
|
97
|
+
if (currentCharacter === '}' || currentCharacter === ']') {
|
|
98
|
+
// Strip trailing comma
|
|
99
|
+
buffer += jsonString.slice(offset, index);
|
|
100
|
+
result += strip(buffer, 0, 1) + buffer.slice(1);
|
|
101
|
+
buffer = '';
|
|
102
|
+
offset = index;
|
|
103
|
+
commaIndex = -1;
|
|
104
|
+
}
|
|
105
|
+
else if (currentCharacter !== ' ' && currentCharacter !== '\t' && currentCharacter !== '\r' && currentCharacter !== '\n') {
|
|
106
|
+
// Hit non-whitespace following a comma; comma is not trailing
|
|
107
|
+
buffer += jsonString.slice(offset, index);
|
|
108
|
+
offset = index;
|
|
109
|
+
commaIndex = -1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (currentCharacter === ',') {
|
|
113
|
+
// Flush buffer prior to this point, and save new comma index
|
|
114
|
+
result += buffer + jsonString.slice(offset, index);
|
|
115
|
+
buffer = '';
|
|
116
|
+
offset = index;
|
|
117
|
+
commaIndex = index;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const remaining = (isInsideComment === singleComment)
|
|
122
|
+
? strip(jsonString, offset)
|
|
123
|
+
: jsonString.slice(offset);
|
|
124
|
+
return result + buffer + remaining;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=strip-json-comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strip-json-comments.js","sourceRoot":"./","sources":["vendor/strip-json-comments.ts"],"names":[],"mappings":"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","sourcesContent":["/*\nMIT License\n\nCopyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n\n// Vendored from strip-json-comments 5.0.3 (https://github.com/sindresorhus/strip-json-comments),\n// index.js and index.d.ts, converted to TypeScript. The logic is unchanged; only type annotations\n// were added. Upstream is ESM-only, so it is vendored here instead of depended on.\n\nexport type Options = {\n\t/**\n\tStrip trailing commas in addition to comments.\n\n\t@default false\n\t*/\n\treadonly trailingCommas?: boolean;\n\n\t/**\n\tReplace comments and trailing commas with whitespace instead of stripping them entirely.\n\n\t@default true\n\t*/\n\treadonly whitespace?: boolean;\n};\n\nconst singleComment = Symbol('singleComment');\nconst multiComment = Symbol('multiComment');\n\ntype CommentState = false | typeof singleComment | typeof multiComment;\n\nconst stripWithoutWhitespace = (_string: string, _start?: number, _end?: number): string => '';\n\n// Replace all characters except ASCII spaces, tabs and line endings with regular spaces to ensure valid JSON output.\nconst stripWithWhitespace = (string: string, start?: number, end?: number): string => string.slice(start, end).replace(/[^ \\t\\r\\n]/g, ' ');\n\nconst isEscaped = (jsonString: string, quotePosition: number): boolean => {\n\tlet index = quotePosition - 1;\n\tlet backslashCount = 0;\n\n\twhile (jsonString[index] === '\\\\') {\n\t\tindex -= 1;\n\t\tbackslashCount += 1;\n\t}\n\n\treturn Boolean(backslashCount % 2);\n};\n\n/**\nStrip comments from JSON. Lets you use comments in your JSON files!\n\nIt will replace single-line comments `//` and multi-line comments `/**\\/` with whitespace. This allows JSON error positions to remain as close as possible to the original source.\n\n@param jsonString - Accepts a string with JSON.\n@returns A JSON string without comments.\n*/\nexport default function stripJsonComments(jsonString: string, {whitespace = true, trailingCommas = false}: Options = {}): string {\n\tif (typeof jsonString !== 'string') {\n\t\tthrow new TypeError(`Expected argument \\`jsonString\\` to be a \\`string\\`, got \\`${typeof jsonString}\\``);\n\t}\n\n\tconst strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;\n\n\tlet isInsideString = false;\n\tlet isInsideComment: CommentState = false;\n\tlet offset = 0;\n\tlet buffer = '';\n\tlet result = '';\n\tlet commaIndex = -1;\n\n\tfor (let index = 0; index < jsonString.length; index++) {\n\t\tconst currentCharacter = jsonString[index];\n\t\tconst nextCharacter = jsonString[index + 1];\n\n\t\tif (!isInsideComment && currentCharacter === '\"') {\n\t\t\t// Enter or exit string\n\t\t\tconst escaped = isEscaped(jsonString, index);\n\t\t\tif (!escaped) {\n\t\t\t\tisInsideString = !isInsideString;\n\t\t\t}\n\t\t}\n\n\t\tif (isInsideString) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!isInsideComment && currentCharacter + nextCharacter === '//') {\n\t\t\t// Enter single-line comment\n\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\toffset = index;\n\t\t\tisInsideComment = singleComment;\n\t\t\tindex++;\n\t\t} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\\r\\n') {\n\t\t\t// Exit single-line comment via \\r\\n\n\t\t\tindex++;\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index);\n\t\t\toffset = index;\n\t\t\tcontinue;\n\t\t} else if (isInsideComment === singleComment && currentCharacter === '\\n') {\n\t\t\t// Exit single-line comment via \\n\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index);\n\t\t\toffset = index;\n\t\t} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {\n\t\t\t// Enter multiline comment\n\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\toffset = index;\n\t\t\tisInsideComment = multiComment;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {\n\t\t\t// Exit multiline comment\n\t\t\tindex++;\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index + 1);\n\t\t\toffset = index + 1;\n\t\t\tcontinue;\n\t\t} else if (trailingCommas && !isInsideComment) {\n\t\t\tif (commaIndex !== -1) {\n\t\t\t\tif (currentCharacter === '}' || currentCharacter === ']') {\n\t\t\t\t\t// Strip trailing comma\n\t\t\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\t\t\tresult += strip(buffer, 0, 1) + buffer.slice(1);\n\t\t\t\t\tbuffer = '';\n\t\t\t\t\toffset = index;\n\t\t\t\t\tcommaIndex = -1;\n\t\t\t\t} else if (currentCharacter !== ' ' && currentCharacter !== '\\t' && currentCharacter !== '\\r' && currentCharacter !== '\\n') {\n\t\t\t\t\t// Hit non-whitespace following a comma; comma is not trailing\n\t\t\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\t\t\toffset = index;\n\t\t\t\t\tcommaIndex = -1;\n\t\t\t\t}\n\t\t\t} else if (currentCharacter === ',') {\n\t\t\t\t// Flush buffer prior to this point, and save new comma index\n\t\t\t\tresult += buffer + jsonString.slice(offset, index);\n\t\t\t\tbuffer = '';\n\t\t\t\toffset = index;\n\t\t\t\tcommaIndex = index;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst remaining = (isInsideComment === singleComment)\n\t\t? strip(jsonString, offset)\n\t\t: jsonString.slice(offset);\n\n\treturn result + buffer + remaining;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "syncodemayo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A simple FTP syncing tool",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
6
8
|
"bin": {
|
|
7
|
-
"syncodemayo": "
|
|
9
|
+
"syncodemayo": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=22.17"
|
|
8
17
|
},
|
|
9
18
|
"scripts": {
|
|
10
|
-
"test": "
|
|
11
|
-
"compile": "tsc -p ./tsconfig.json && echo 'Finished compile.'",
|
|
19
|
+
"test": "bun run compile && node --test \"test/**/*.test.mjs\"",
|
|
20
|
+
"compile": "tsc -p ./tsconfig.json && chmod +x dist/cli.js && echo 'Finished compile.'",
|
|
12
21
|
"compile:watch": "tsc --watch -p ./tsconfig.json",
|
|
13
|
-
"
|
|
14
|
-
"prepublishOnly": "
|
|
22
|
+
"smoke:pack": "node scripts/smoke-pack.mjs",
|
|
23
|
+
"prepublishOnly": "bun run test"
|
|
15
24
|
},
|
|
16
25
|
"repository": {
|
|
17
26
|
"type": "git",
|
|
@@ -24,25 +33,14 @@
|
|
|
24
33
|
},
|
|
25
34
|
"homepage": "https://github.com/mattmccray/syncodemayo#readme",
|
|
26
35
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
"crc": "3.4.1",
|
|
29
|
-
"dotenv": "^4.0.0",
|
|
30
|
-
"glob": "^7.1.2",
|
|
31
|
-
"joi": "^10.6.0",
|
|
32
|
-
"jsftp": "1.3.1",
|
|
33
|
-
"jsftp-mkdirp": "0.1.2",
|
|
34
|
-
"minimatch": "^3.0.4",
|
|
35
|
-
"strip-json-comments": "^2.0.1",
|
|
36
|
-
"yesno": "^0.0.1"
|
|
36
|
+
"basic-ftp": "^6.2.6"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"typescript": "^2.4.2"
|
|
47
|
-
}
|
|
39
|
+
"@types/node": "^22.20.5",
|
|
40
|
+
"ajv": "^8.20.0",
|
|
41
|
+
"ajv-draft-04": "^1.0.0",
|
|
42
|
+
"ftp-srv": "^4.6.3",
|
|
43
|
+
"typescript": "^5.9.3"
|
|
44
|
+
},
|
|
45
|
+
"packageManager": "bun@1.4.4"
|
|
48
46
|
}
|
package/.npmignore
DELETED
package/cli.d.ts
DELETED
|
File without changes
|
package/cli.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node --harmony
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const dotenv = require("dotenv");
|
|
5
|
-
dotenv.config();
|
|
6
|
-
const CLI = require("./lib/Cli");
|
|
7
|
-
const Log = require("./lib/Log");
|
|
8
|
-
const program = require("commander");
|
|
9
|
-
const defaultTarget = undefined;
|
|
10
|
-
let syncTarget = undefined;
|
|
11
|
-
let command = 'help';
|
|
12
|
-
program
|
|
13
|
-
.version('1.0.0')
|
|
14
|
-
.option('-c, --config [file]', 'Specify local config [file]')
|
|
15
|
-
.option('-v, --verbose', 'Verbose logging', false)
|
|
16
|
-
.option('-q, --quiet', 'Minimal logging', false);
|
|
17
|
-
program
|
|
18
|
-
.command('init [target]')
|
|
19
|
-
.description("Configure local folder and/or server to sync")
|
|
20
|
-
.action((target) => {
|
|
21
|
-
syncTarget = target || defaultTarget;
|
|
22
|
-
command = 'init';
|
|
23
|
-
});
|
|
24
|
-
program
|
|
25
|
-
.command('changes [target]')
|
|
26
|
-
.alias('diff')
|
|
27
|
-
.description("Perform sync dry run and display the changes")
|
|
28
|
-
.action((target) => {
|
|
29
|
-
syncTarget = target || defaultTarget;
|
|
30
|
-
command = 'changes';
|
|
31
|
-
});
|
|
32
|
-
program
|
|
33
|
-
.command('verify [target]')
|
|
34
|
-
.description("Verify server is configured")
|
|
35
|
-
.action((target) => {
|
|
36
|
-
syncTarget = target || defaultTarget;
|
|
37
|
-
command = 'check';
|
|
38
|
-
});
|
|
39
|
-
program
|
|
40
|
-
.command('sync [target]')
|
|
41
|
-
.description("Perform sync to server")
|
|
42
|
-
.option('-f, --force', "Don't prompt before uploading.", false)
|
|
43
|
-
.action((target, options) => {
|
|
44
|
-
syncTarget = target || defaultTarget;
|
|
45
|
-
command = options.force ? 'syncf' : 'sync';
|
|
46
|
-
});
|
|
47
|
-
program
|
|
48
|
-
.command('ls')
|
|
49
|
-
.description("List defined targets in config")
|
|
50
|
-
.action(() => {
|
|
51
|
-
command = "ls";
|
|
52
|
-
});
|
|
53
|
-
program.parse(process.argv);
|
|
54
|
-
CLI.setFlags({
|
|
55
|
-
logLevel: program.verbose
|
|
56
|
-
? Log.LogLevel.Debug
|
|
57
|
-
: program.quiet
|
|
58
|
-
? Log.LogLevel.Info
|
|
59
|
-
: Log.LogLevel.Default
|
|
60
|
-
});
|
|
61
|
-
switch (command) {
|
|
62
|
-
case "changes":
|
|
63
|
-
Log.debug(`Performing '${command}' on target: ${syncTarget || '(default)'}...\n`);
|
|
64
|
-
CLI.changes(program.config, syncTarget).then(showDone).catch(showError);
|
|
65
|
-
break;
|
|
66
|
-
case "check":
|
|
67
|
-
Log.debug(`Performing '${command}' on target: ${syncTarget || '(default)'}...\n`);
|
|
68
|
-
CLI.check(program.config, syncTarget).then(showDone).catch(showError);
|
|
69
|
-
break;
|
|
70
|
-
case "init":
|
|
71
|
-
Log.debug(`Performing '${command}' on target: ${syncTarget || '(default)'}...\n`);
|
|
72
|
-
CLI.init(program.config, syncTarget).then(showDone).catch(showError);
|
|
73
|
-
break;
|
|
74
|
-
case "ls":
|
|
75
|
-
Log.debug(`Performing '${command}'...\n`);
|
|
76
|
-
CLI.ls(program.config).then(showDone).catch(showError);
|
|
77
|
-
break;
|
|
78
|
-
case "sync":
|
|
79
|
-
Log.debug(`Performing '${command}' on target: ${syncTarget || '(default)'}\n...`);
|
|
80
|
-
CLI.sync(program.config, syncTarget, false).then(showDone).catch(showError);
|
|
81
|
-
break;
|
|
82
|
-
case "syncf":
|
|
83
|
-
Log.debug(`Performing (forced) 'sync' on target: ${syncTarget || '(default)'}\n...`);
|
|
84
|
-
CLI.sync(program.config, syncTarget, true).then(showDone).catch(showError);
|
|
85
|
-
break;
|
|
86
|
-
case "help":
|
|
87
|
-
default:
|
|
88
|
-
syncTarget = "app";
|
|
89
|
-
program.help();
|
|
90
|
-
}
|
|
91
|
-
function showDone() {
|
|
92
|
-
Log.log("\nDone.");
|
|
93
|
-
process.exit(0);
|
|
94
|
-
}
|
|
95
|
-
function showError(err) {
|
|
96
|
-
console.error("\n(!)", err.message, "\n\n", err);
|
|
97
|
-
// if (program.verbose) {
|
|
98
|
-
// console.error(err)
|
|
99
|
-
// }
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=cli.js.map
|
package/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib';
|
package/index.js
DELETED
package/lib/Cli.js
DELETED
|
@@ -1,130 +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 Log = require("./Log");
|
|
12
|
-
const Client_1 = require("./Client");
|
|
13
|
-
function setFlags(flags) {
|
|
14
|
-
Log.setLogLevel(flags.logLevel);
|
|
15
|
-
}
|
|
16
|
-
exports.setFlags = setFlags;
|
|
17
|
-
function changes(configPath, target) {
|
|
18
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
const client = yield Client_1.Client.create(configPath);
|
|
20
|
-
const changeset = yield client.getTargetServer(target).sync(true);
|
|
21
|
-
if (changeset == null)
|
|
22
|
-
throw new Error("Change detection failed.");
|
|
23
|
-
const added = changeset.added.length;
|
|
24
|
-
const changed = changeset.changed.length;
|
|
25
|
-
const removed = changeset.removed.length;
|
|
26
|
-
if (added + changed + removed === 0) {
|
|
27
|
-
Log.log("\nNo changes detected.");
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
if (added > 0) {
|
|
31
|
-
Log.info("\nNew Local Files: (%s)", added);
|
|
32
|
-
changeset.added.forEach(f => Log.log(" -", f));
|
|
33
|
-
}
|
|
34
|
-
if (changed > 0) {
|
|
35
|
-
Log.info("\nChanged Local Files: (%s)", changeset.changed.length);
|
|
36
|
-
changeset.changed.forEach(f => Log.log(" -", f));
|
|
37
|
-
}
|
|
38
|
-
if (removed > 0) {
|
|
39
|
-
Log.info(`\nRemoved Local Files${client.config.local.deleteRemoteFiles ? '' : ' (disabled)'}: (%s)`, changeset.removed.length);
|
|
40
|
-
changeset.removed.forEach(f => Log.log(" -", f));
|
|
41
|
-
}
|
|
42
|
-
return true;
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
exports.changes = changes;
|
|
46
|
-
function check(configPath, target) {
|
|
47
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const client = yield Client_1.Client.create(configPath);
|
|
49
|
-
if (client.hasError) {
|
|
50
|
-
throw client.loadError || client.parseError;
|
|
51
|
-
}
|
|
52
|
-
if (!client.hasConfig && !client.hasError) {
|
|
53
|
-
Log.urgent("This directory isn't configured for SyncoDeMayo!");
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
const targetServer = client.getTargetServer(target);
|
|
57
|
-
const isServerConfigured = yield targetServer.verify();
|
|
58
|
-
if (isServerConfigured) {
|
|
59
|
-
Log.info("Target", JSON.stringify(targetServer.name), "is ready for syncing.");
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
Log.urgent("Target", JSON.stringify(targetServer.name), "isn't configured, run init.");
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
return true;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
exports.check = check;
|
|
69
|
-
function init(configPath, target) {
|
|
70
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
const client = yield Client_1.Client.create(configPath);
|
|
72
|
-
if (!client.hasConfig && client.hasError) {
|
|
73
|
-
throw client.loadError || client.parseError;
|
|
74
|
-
}
|
|
75
|
-
if (!client.hasConfig) {
|
|
76
|
-
yield client.createConfig(configPath);
|
|
77
|
-
Log.info("Created local config at", configPath);
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
const targetServer = client.getTargetServer(target);
|
|
81
|
-
const isServerConfigured = yield targetServer.verify();
|
|
82
|
-
if (!isServerConfigured) {
|
|
83
|
-
yield targetServer.prepare();
|
|
84
|
-
Log.info("Created", targetServer.config.cache, "on server target", targetServer.config._name);
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
Log.info("Everything seems to be configured correctly.");
|
|
88
|
-
return false;
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
exports.init = init;
|
|
92
|
-
function ls(configPath) {
|
|
93
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
const client = yield Client_1.Client.create(configPath);
|
|
95
|
-
const targets = yield client.getTargetNames();
|
|
96
|
-
Log.urgent("Defined server targets:");
|
|
97
|
-
targets.forEach(name => {
|
|
98
|
-
const target = client.config.targets[name];
|
|
99
|
-
const bullet = client.config.local.defaultTarget === target._name
|
|
100
|
-
? " *"
|
|
101
|
-
: " -";
|
|
102
|
-
Log.urgent(bullet, name, `\t(${target.user}@${target.host}:${target.path})`);
|
|
103
|
-
});
|
|
104
|
-
return true;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
exports.ls = ls;
|
|
108
|
-
function sync(configPath, target, forceConfirmation = false) {
|
|
109
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
-
const client = yield Client_1.Client.create(configPath);
|
|
111
|
-
if (!client.hasConfig) {
|
|
112
|
-
if (client.hasError)
|
|
113
|
-
throw client.loadError || client.parseError;
|
|
114
|
-
else
|
|
115
|
-
throw new Error("This directory isn't configured for SyncoDeMayo!");
|
|
116
|
-
}
|
|
117
|
-
const changes = yield client.getTargetServer(target).sync(false, forceConfirmation);
|
|
118
|
-
if (changes != null) {
|
|
119
|
-
Log.info("\nSummary:");
|
|
120
|
-
Log.info(" %s files uploaded.", changes.added.length + changes.changed.length);
|
|
121
|
-
changes.added.forEach(path => Log.log(" +", path));
|
|
122
|
-
changes.changed.forEach(path => Log.log(" -", path));
|
|
123
|
-
Log.info(` %s files removed. ${client.config.local.deleteRemoteFiles ? '' : '(disabled)'}`, changes.removed.length);
|
|
124
|
-
changes.removed.forEach(path => Log.log(" x", path));
|
|
125
|
-
}
|
|
126
|
-
return true;
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
exports.sync = sync;
|
|
130
|
-
//# sourceMappingURL=Cli.js.map
|