@taprootio/site-authoring 0.10.1 → 0.10.2
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/package.json +2 -2
- package/src/constants.js +1 -1
- package/src/content/components.js +5 -0
- package/src/transport.js +37 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/site-authoring",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Taproot site authoring CLI: sign in once in the browser, then pull, validate, push, preview, approve, and deploy a site from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "ISC",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"README.md"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@taprootio/espalier": "4.
|
|
31
|
+
"@taprootio/espalier": "4.17.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"test": "node --test",
|
package/src/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const CLI_NAME = "@taprootio/site-authoring";
|
|
2
|
-
export const CLI_VERSION = "0.10.
|
|
2
|
+
export const CLI_VERSION = "0.10.2";
|
|
3
3
|
export const CLI_BINARY_NAME = "taproot-site";
|
|
4
4
|
export const RESULT_SCHEMA_VERSION = 1;
|
|
5
5
|
export const CONFIG_FILE_NAME = "taproot-site.json";
|
|
@@ -256,6 +256,9 @@ const IMAGE_BANNER = Object.freeze({
|
|
|
256
256
|
followingSpacing: enumOf("standard", "compact"),
|
|
257
257
|
scrim: enumOf("auto", "none", "flat", "top", "bottom", "left", "right", "radial"),
|
|
258
258
|
scrimStrength: enumOf("soft", "medium", "strong"),
|
|
259
|
+
// Finish a directional scrim's anchored edge at full alpha so the banner
|
|
260
|
+
// joins the adjoining band without a seam (Espalier 4.17.0 scrim-edge).
|
|
261
|
+
scrimEdge: enumOf("none", "flush"),
|
|
259
262
|
bannerScheme: enumOf("auto", "light", "dark"),
|
|
260
263
|
// Drop-shadow strength applied to the overlay text.
|
|
261
264
|
textShadow: enumOf("none", "light", "medium", "strong"),
|
|
@@ -502,6 +505,7 @@ const COMPONENT_DEFINITIONS = Object.freeze({
|
|
|
502
505
|
followingSpacing: "standard",
|
|
503
506
|
scrim: "auto",
|
|
504
507
|
scrimStrength: "medium",
|
|
508
|
+
scrimEdge: "none",
|
|
505
509
|
bannerScheme: "auto",
|
|
506
510
|
textShadow: "none",
|
|
507
511
|
texture: "none",
|
|
@@ -512,6 +516,7 @@ const COMPONENT_DEFINITIONS = Object.freeze({
|
|
|
512
516
|
"Set altText to describe meaningful banner imagery; leave it empty only when the image is decorative.",
|
|
513
517
|
"Choose a scrim and scheme that keep overlay text readable across the image.",
|
|
514
518
|
"For a full-bleed photograph with text aligned to the surrounding page well, set contentGutter to page. followingSpacing: compact reduces the top padding of an immediately following section so a bottom banner heading reads with its supporting paragraph. Use a banner-only contentPadding: none section followed by a standard text section; keep their theme contexts consistent. Defaults preserve frame-edge text and standard section spacing.",
|
|
519
|
+
"scrimEdge: flush finishes a directional scrim at full strength where it meets the page, so a full-bleed banner dissolves into the band below instead of ending at a visible line. It requires the arrangement above: a banner-only contentPadding: none section immediately followed by a section in the same theme context. It is inert when scrim is none, flat, or radial, and it stops being seamless when bannerScheme pins a polarity the page scheme does not share, because the scrim ink is then a derived color rather than the adjoining band's own. Default none; add it deliberately, per banner.",
|
|
515
520
|
"Compose around the actual photograph: identify the meaningful subject and a quiet area for copy. Do not cover faces, product details, or high-detail edges. A focal point controls cropping, not text placement; inspect wide and compact crops separately. Keep the subject's face, ears, and other identifying details inside the compact frame, including at both ends of parallax travel. Adjust focus toward the subject rather than reusing a generic center; reduce motion or choose a roomier crop if preserving the subject requires it.",
|
|
516
521
|
"Use contentPosition to place copy in that quiet area, not automatically in the center. Keep one dominant message and nearby supporting copy/actions; if the photo has no safe text area, use a split hero or a separate text section instead of forcing an overlay.",
|
|
517
522
|
"Use the rule of thirds as a composition guide: consider the subject near one third and a compact text group in quiet space on the opposite side. Golden-ratio proportions are optional alternatives, not a proven engagement formula. Neither guide overrides legibility, the actual subject, or the compact crop. Current contentPosition values are edge/center anchors, not exact third or golden-ratio coordinates; do not invent unsupported positioning properties.",
|
package/src/transport.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
HTTP_TOO_MANY_REQUESTS,
|
|
11
11
|
HTTP_UNAUTHORIZED,
|
|
12
12
|
LIMITS,
|
|
13
|
+
LOCAL_API_BASE_URL,
|
|
13
14
|
PLAN_LIMIT_REFUSAL_FIELD,
|
|
14
15
|
PUBLISH_KEY_ENVIRONMENT_VARIABLE,
|
|
15
16
|
REFUSAL_CAPABILITY_MISSING,
|
|
@@ -82,6 +83,18 @@ function isUndelivered(error) {
|
|
|
82
83
|
return code !== undefined && UNDELIVERED_CAUSE_CODES.has(code);
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
/**
|
|
87
|
+
* The certificate-verification codes, named once. `describeTransportCause`
|
|
88
|
+
* softens them into a sentence and `localCertificateHint` decides whether a
|
|
89
|
+
* remediation belongs with them, so the list must not be restated in either.
|
|
90
|
+
*/
|
|
91
|
+
const CERTIFICATE_CAUSE_CODES = new Set([
|
|
92
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
93
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
94
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
95
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
96
|
+
]);
|
|
97
|
+
|
|
85
98
|
/**
|
|
86
99
|
* The underlying cause, named.
|
|
87
100
|
*
|
|
@@ -94,12 +107,32 @@ function isUndelivered(error) {
|
|
|
94
107
|
function describeTransportCause(error) {
|
|
95
108
|
const code = transportCauseCode(error);
|
|
96
109
|
if (code === undefined || !SAFE_CAUSE_CODE.test(code)) return undefined;
|
|
97
|
-
return code
|
|
98
|
-
|| code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY" || code === "DEPTH_ZERO_SELF_SIGNED_CERT"
|
|
110
|
+
return CERTIFICATE_CAUSE_CODES.has(code)
|
|
99
111
|
? `${code}: the server's TLS certificate was not trusted`
|
|
100
112
|
: code;
|
|
101
113
|
}
|
|
102
114
|
|
|
115
|
+
/**
|
|
116
|
+
* The one remediation this error has, and only where it is the answer.
|
|
117
|
+
*
|
|
118
|
+
* Against the local stack an untrusted certificate is nearly always setup, not
|
|
119
|
+
* an attack: mkcert installs its root into the system and browser trust stores
|
|
120
|
+
* and Node reads neither, so the CLI fails while the same host loads fine in
|
|
121
|
+
* Chrome. Naming the fix here saves the round-trip the bare cause code costs.
|
|
122
|
+
*
|
|
123
|
+
* Deliberately silent for every other origin. On production the same code
|
|
124
|
+
* means an interception or a genuinely broken chain, and printing "here is how
|
|
125
|
+
* to trust it" would be advice to disable the check that just did its job.
|
|
126
|
+
*/
|
|
127
|
+
function localCertificateHint(apiOrigin, error) {
|
|
128
|
+
const code = transportCauseCode(error);
|
|
129
|
+
if (code === undefined || !CERTIFICATE_CAUSE_CODES.has(code)) return "";
|
|
130
|
+
if (apiOrigin !== new URL(LOCAL_API_BASE_URL).origin) return "";
|
|
131
|
+
return " The local stack uses mkcert, whose root Node does not read from the system trust store."
|
|
132
|
+
+ " Export NODE_EXTRA_CA_CERTS=\"$HOME/Library/Application Support/mkcert/rootCA.pem\""
|
|
133
|
+
+ " (or NODE_USE_SYSTEM_CA=1 on Node 22.19+ or 24.6+) and run the command again.";
|
|
134
|
+
}
|
|
135
|
+
|
|
103
136
|
const SAFE_CAUSE_CODE = /^[A-Z0-9_]{1,64}$/u;
|
|
104
137
|
|
|
105
138
|
// Exported because the credential store's pre-mint size projection has to
|
|
@@ -742,7 +775,8 @@ export class SiteApiClient {
|
|
|
742
775
|
(ambiguous
|
|
743
776
|
? "A Taproot API mutation ended without an authoritative response."
|
|
744
777
|
: "A Taproot API request failed before a response was received.")
|
|
745
|
-
+ (cause === undefined ? "" : ` (${cause})`)
|
|
778
|
+
+ (cause === undefined ? "" : ` (${cause})`)
|
|
779
|
+
+ localCertificateHint(this.apiOrigin, error),
|
|
746
780
|
);
|
|
747
781
|
}
|
|
748
782
|
if (response.status >= 200 && response.status < 300 && !response.redirected) {
|