dxfl 0.3.2 → 0.4.1
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 +9 -0
- package/README.md +8 -2
- package/dist/deploy.js +1 -3
- package/dist/error.js +4 -4
- package/dist/guichet.js +2 -2
- package/dist/index.js +2 -1
- package/dist/inspect.js +12 -11
- package/dist/utils.js +2 -6
- package/dist/vhosts.js +5 -5
- package/dist/website_config.js +9 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -40,6 +40,12 @@ Or only display the changes without applying them, with the `--dry-run` option:
|
|
|
40
40
|
dxfl deploy example.com _public --dry-run
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
You can also specify a custom TOML configuration file to use instead of the default `deuxfleurs.toml`, with the `--config-file` option:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
dxfl deploy example.com _public --config-file custom.toml
|
|
47
|
+
```
|
|
48
|
+
|
|
43
49
|
Use the `empty` command to delete all files from a website (required before deleting it):
|
|
44
50
|
|
|
45
51
|
```
|
|
@@ -54,10 +60,10 @@ dxfl inspect example.com
|
|
|
54
60
|
|
|
55
61
|
## Website configuration
|
|
56
62
|
|
|
57
|
-
`dxfl deploy` reads a `deuxfleurs.toml`
|
|
63
|
+
`dxfl deploy` reads a TOML configuration file, `deuxfleurs.toml` by default (if it exists in the current directory), or the one specified with the `--config-file` option.
|
|
58
64
|
This file can be used to specify website configuration metadata such as redirections.
|
|
59
65
|
|
|
60
|
-
Your
|
|
66
|
+
Your configuration file should follow the following structure:
|
|
61
67
|
|
|
62
68
|
```toml
|
|
63
69
|
# Filename added after URLs that point to directories.
|
package/dist/deploy.js
CHANGED
|
@@ -323,10 +323,8 @@ export function deploy(website, localFolder, options) {
|
|
|
323
323
|
if (options.dryRun && options.yes) {
|
|
324
324
|
throw new ErrorMsg("options --yes and --dry-run cannot be passed at the same time");
|
|
325
325
|
}
|
|
326
|
-
// TODO: make this configurable
|
|
327
|
-
const website_config_path = "deuxfleurs.toml";
|
|
328
326
|
// Read and validate the local configuration file before doing anything else
|
|
329
|
-
const localWebsiteConfig = yield readConfigFile(
|
|
327
|
+
const localWebsiteConfig = yield readConfigFile(options.configFile);
|
|
330
328
|
process.stdout.write("Fetching the website configuration and metadata...\n");
|
|
331
329
|
const [localFiles, [bucket, remoteFiles, remoteWebsiteConfig]] = yield Promise.all([
|
|
332
330
|
// Get paths & size of the local files to deploy
|
package/dist/error.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { S3ServiceException } from "@aws-sdk/client-s3";
|
|
11
|
-
import
|
|
11
|
+
import { styleText } from "node:util";
|
|
12
12
|
export class ErrorCtx {
|
|
13
13
|
constructor(ctx, error) {
|
|
14
14
|
this.ctx = ctx;
|
|
@@ -83,10 +83,10 @@ export function wrapS3Call(context, expectedCodes, f) {
|
|
|
83
83
|
// otherwise it is thrown as an exception.
|
|
84
84
|
export function handleError(e) {
|
|
85
85
|
if (e instanceof ErrorMsg) {
|
|
86
|
-
console.error(`${
|
|
86
|
+
console.error(`${styleText("red", "Error:")} ${e.msg}`);
|
|
87
87
|
}
|
|
88
88
|
else if (e instanceof ErrorGuichet) {
|
|
89
|
-
let msg =
|
|
89
|
+
let msg = styleText("red", "Error: ");
|
|
90
90
|
if (e.cause.kind == "Unauthorized") {
|
|
91
91
|
msg +=
|
|
92
92
|
"failed to authenticate with Guichet. Is your password and login correct?";
|
|
@@ -97,7 +97,7 @@ export function handleError(e) {
|
|
|
97
97
|
console.error(msg);
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
|
-
console.error(
|
|
100
|
+
console.error(styleText("red", "Unexpected error:") + "\n", e);
|
|
101
101
|
}
|
|
102
102
|
process.exit(1);
|
|
103
103
|
}
|
package/dist/guichet.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { WebsiteApi, } from "guichet-sdk-ts";
|
|
11
|
-
import {
|
|
11
|
+
import { styleText } from "node:util";
|
|
12
12
|
import { ErrorGuichet } from "./error.js";
|
|
13
13
|
// The GuichetApi class wraps WebsiteApi (from the guichet sdk). It catches
|
|
14
14
|
// errors that can happen in normal use, and it turn them into a dedicated error type
|
|
@@ -45,7 +45,7 @@ export class GuichetApi {
|
|
|
45
45
|
// the migration of websites *.web.deuxfleurs.fr to bucket
|
|
46
46
|
// names with the full domain name.
|
|
47
47
|
// We just warn that this is a working but deprecated name.
|
|
48
|
-
console.log(`${
|
|
48
|
+
console.log(`${styleText("yellow", "Warning")}: the name "${vhost}" is now deprecated for this website,` +
|
|
49
49
|
` you should use "${vhost}.web.deuxfleurs.fr" instead.`);
|
|
50
50
|
}
|
|
51
51
|
return websiteInfo;
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { deploy } from "./deploy.js";
|
|
|
6
6
|
import { empty } from "./empty.js";
|
|
7
7
|
import { vhostsList } from "./vhosts.js";
|
|
8
8
|
import { inspect } from "./inspect.js";
|
|
9
|
-
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.
|
|
9
|
+
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.4.1");
|
|
10
10
|
program
|
|
11
11
|
.command("login")
|
|
12
12
|
.description("Link your Deuxfleurs account with this tool.")
|
|
@@ -29,6 +29,7 @@ program
|
|
|
29
29
|
.argument("<local_folder>", "your local folder")
|
|
30
30
|
.option("-n, --dry-run", "do a trial run without making actual changes")
|
|
31
31
|
.option("-y, --yes", "apply the changes without asking for confirmation")
|
|
32
|
+
.option("-c, --config-file <path>", "apply a custom TOML config file")
|
|
32
33
|
.action((website, localFolder, options) => withHandleErrors(() => deploy(website, localFolder, options)));
|
|
33
34
|
program
|
|
34
35
|
.command("empty")
|
package/dist/inspect.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { WebsiteApi } from "guichet-sdk-ts";
|
|
11
11
|
import { openApiConf } from "./auth.js";
|
|
12
|
-
import { formatBytesHuman, separator
|
|
13
|
-
import
|
|
12
|
+
import { formatBytesHuman, separator } from "./utils.js";
|
|
13
|
+
import { styleText } from "node:util";
|
|
14
14
|
export function inspect(website, options) {
|
|
15
15
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
var _a, _b, _c;
|
|
@@ -24,17 +24,18 @@ export function inspect(website, options) {
|
|
|
24
24
|
if (!options.secret) {
|
|
25
25
|
kSecret =
|
|
26
26
|
`**** ` +
|
|
27
|
-
|
|
27
|
+
styleText(["gray", "italic"], `(use \`dxfl inspect ${v === null || v === void 0 ? void 0 : v.name} --secret\` to reveal it)`);
|
|
28
28
|
}
|
|
29
|
-
console.log(
|
|
29
|
+
console.log(styleText(["green", "bold"], `${v === null || v === void 0 ? void 0 : v.name} details`));
|
|
30
30
|
console.log(separator());
|
|
31
|
-
console.log(` ${
|
|
32
|
-
console.log(` ${
|
|
33
|
-
console.log(` ${
|
|
34
|
-
console.log(` ${
|
|
35
|
-
console.log(` ${
|
|
36
|
-
console.log(` ${
|
|
31
|
+
console.log(` ${styleText("bold", "id")}: ${v === null || v === void 0 ? void 0 : v.name}`);
|
|
32
|
+
console.log(` ${styleText("bold", "url")}: ${styleText("underline", "https://" + (v === null || v === void 0 ? void 0 : v.domain))}`);
|
|
33
|
+
console.log(` ${styleText("bold", "usage")}:`, `${formatBytesHuman((_a = q === null || q === void 0 ? void 0 : q.current) !== null && _a !== void 0 ? _a : 0)} / ${formatBytesHuman((_b = q === null || q === void 0 ? void 0 : q.max) !== null && _b !== void 0 ? _b : 0)}`, `(${Math.round(((_c = q === null || q === void 0 ? void 0 : q.ratio) !== null && _c !== void 0 ? _c : 0) * 100)}%)`);
|
|
34
|
+
console.log(` ${styleText("bold", "S3 keys")}:`);
|
|
35
|
+
console.log(` ${styleText("bold", "access_key_id")}: ${kId}`);
|
|
36
|
+
console.log(` ${styleText("bold", "secret_access_key")}: ${kSecret}`);
|
|
37
37
|
console.log(separator());
|
|
38
|
-
console.log(
|
|
38
|
+
console.log(styleText(["gray", "italic"], `→ For more information and features, you can visit the web UI: ` +
|
|
39
|
+
`${styleText("underline", "https://guichet.deuxfleurs.fr/website/inspect/" + (v === null || v === void 0 ? void 0 : v.name))}`));
|
|
39
40
|
});
|
|
40
41
|
}
|
package/dist/utils.js
CHANGED
|
@@ -19,11 +19,7 @@ import crypto from "crypto";
|
|
|
19
19
|
import { stdin, stdout } from "process";
|
|
20
20
|
import readline from "readline/promises";
|
|
21
21
|
import { ErrorMsg } from "./error.js";
|
|
22
|
-
import
|
|
23
|
-
export const textGreen = clc.green;
|
|
24
|
-
export const textWarn = clc.yellow;
|
|
25
|
-
export const textError = clc.red;
|
|
26
|
-
export const textGrey = clc.xterm(242);
|
|
22
|
+
import { styleText } from "node:util";
|
|
27
23
|
export function getFileMd5(file) {
|
|
28
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
25
|
var _a, e_1, _b, _c;
|
|
@@ -132,5 +128,5 @@ export function separator(size = 42) {
|
|
|
132
128
|
for (let i = 0; i < size; i++) {
|
|
133
129
|
dashes += "-";
|
|
134
130
|
}
|
|
135
|
-
return
|
|
131
|
+
return styleText("gray", dashes);
|
|
136
132
|
}
|
package/dist/vhosts.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { WebsiteApi } from "guichet-sdk-ts";
|
|
11
11
|
import { openApiConf } from "./auth.js";
|
|
12
|
-
import { separator
|
|
13
|
-
import
|
|
12
|
+
import { separator } from "./utils.js";
|
|
13
|
+
import { styleText } from "node:util";
|
|
14
14
|
export function vhostsList() {
|
|
15
15
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16
16
|
var _a, _b, _c;
|
|
@@ -24,9 +24,9 @@ export function vhostsList() {
|
|
|
24
24
|
if (i === 0) {
|
|
25
25
|
console.log(separator());
|
|
26
26
|
}
|
|
27
|
-
console.log(
|
|
28
|
-
console.log(` ${
|
|
29
|
-
console.log(` ${
|
|
27
|
+
console.log(styleText("green", v.name || ""));
|
|
28
|
+
console.log(` ${styleText("green", "id")}: ${v.name}`);
|
|
29
|
+
console.log(` ${styleText("bold", "url")}: ${styleText("underline", "https://" + v.domain)}`);
|
|
30
30
|
console.log(separator());
|
|
31
31
|
});
|
|
32
32
|
});
|
package/dist/website_config.js
CHANGED
|
@@ -54,7 +54,15 @@ export function equalCorsRules(c1, c2) {
|
|
|
54
54
|
// Parsing: TOML -> untyped object
|
|
55
55
|
function readConfigFileObject(filename) {
|
|
56
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
if (
|
|
57
|
+
if (filename != undefined) {
|
|
58
|
+
if (!fs.existsSync(filename)) {
|
|
59
|
+
throw new ErrorMsg(`${filename} configuration file not found`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (fs.existsSync("deuxfleurs.toml")) {
|
|
63
|
+
filename = "deuxfleurs.toml";
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
58
66
|
return {};
|
|
59
67
|
}
|
|
60
68
|
let strConf;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dxfl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "EUPL-1.2",
|
|
6
6
|
"author": "Deuxfleurs Team <coucou@deuxfleurs.fr>",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"bin": {
|
|
14
14
|
"dxfl": "dist/index.js"
|
|
15
15
|
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20.0.0"
|
|
18
|
+
},
|
|
16
19
|
"scripts": {
|
|
17
20
|
"prepare": "npx tsc",
|
|
18
21
|
"prettier": "npx prettier . --write",
|
|
@@ -24,7 +27,6 @@
|
|
|
24
27
|
"@commander-js/extra-typings": "^14.0.0",
|
|
25
28
|
"@supercharge/promise-pool": "^3.2.0",
|
|
26
29
|
"@types/node": "^25.2.1",
|
|
27
|
-
"cli-color": "^2.0.4",
|
|
28
30
|
"commander": "^14.0.3",
|
|
29
31
|
"fast-uri": "^3.1.0",
|
|
30
32
|
"guichet-sdk-ts": "^0.1.0",
|
|
@@ -36,7 +38,6 @@
|
|
|
36
38
|
"zod-validation-error": "^3.4.1"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
|
-
"@types/cli-color": "^2.0.6",
|
|
40
41
|
"onchange": "^7.1.0",
|
|
41
42
|
"prettier": "3.5.3"
|
|
42
43
|
}
|