@mapled/cli 0.14.1 → 0.14.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/README.md +1 -1
- package/dist/commands.js +5 -0
- package/dist/html5.d.ts +13 -2
- package/dist/html5.js +9 -0
- package/dist/report.d.ts +4 -0
- package/dist/scanHtml.d.ts +2 -1
- package/dist/scanHtml.js +11 -4
- package/dist/types.js +3 -1
- package/dist/vanillaDigests.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -256,7 +256,7 @@ npx @mapled/cli preview
|
|
|
256
256
|
npx @mapled/cli preview articles hello-world
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
Prints a Preview link — the one the **Preview** button in Mapled opens: the site in draft mode, with every saved change that isn't published yet. Name a collection and a record's slug (or id) and the link lands on the record's page, the one the pushed site manifest says shows it; a collection alone opens the page that lists it, a single its page, nothing at all the home page. Mapled makes the link after checking that the site answers and mounts its preview route; it works once, for five minutes. `--open` opens it in your browser instead of printing it; `--json` prints the link with the page and when it expires.
|
|
259
|
+
Prints a Preview link — the one the **Preview** button in Mapled opens: the site in draft mode, with every saved change that isn't published yet. Name a collection and a record's slug (or id) and the link lands on the record's page, the one the pushed site manifest says shows it; a collection alone opens the page that lists it, a single its page, nothing at all the home page. Mapled makes the link after checking that the site answers and mounts its preview route; it works once, for five minutes. A plain HTML site whose pages are built with the content in them has no page for a record it wasn't built with: for such a record the command says so instead of printing a link — its page appears once the site is built with it. `--open` opens it in your browser instead of printing it; `--json` prints the link with the page and when it expires.
|
|
260
260
|
|
|
261
261
|
## Options
|
|
262
262
|
|
package/dist/commands.js
CHANGED
|
@@ -507,6 +507,11 @@ export async function preview(ctx, flags, words) {
|
|
|
507
507
|
if (answer.status === "not_set_up") {
|
|
508
508
|
throw new CliError(`${clean(answer.origin)} has no preview route — mount createPreviewHandler from "@mapled/next/server" at /api/mapled/preview and redeploy.`);
|
|
509
509
|
}
|
|
510
|
+
if (answer.status === "no_route") {
|
|
511
|
+
// a site with its content baked in at build time has no page for a record it wasn't built with (§22.7 п. 3)
|
|
512
|
+
const where = answer.path ? `at ${clean(answer.path, 500)}` : "for this record";
|
|
513
|
+
throw new CliError(`${clean(answer.origin)} has no page ${where} — if the record is new, its page appears once the site is built with it. Then try again.`);
|
|
514
|
+
}
|
|
510
515
|
// the link is printed as it came (masking would drop the token): printable ASCII only
|
|
511
516
|
if (typeof answer.url !== "string" || !/^https?:\/\/[!-~]+$/.test(answer.url)) {
|
|
512
517
|
throw new CliError("Mapled answered with a link this CLI can't print. Update @mapled/cli and try again.");
|
package/dist/html5.d.ts
CHANGED
|
@@ -18,11 +18,21 @@ import { type Token, type TreeAdapter, type TreeAdapterTypeMap } from "parse5";
|
|
|
18
18
|
before a <table>: indexOf), the adoption agency (a misnested </b>:
|
|
19
19
|
splice from the front) and repeated <html>/<body> tags (every
|
|
20
20
|
attribute so far) walk them — 160,000 "a<br>" in a table: 11 s.
|
|
21
|
-
The worst page within the cap is the depth times its start tags.
|
|
21
|
+
The worst page within the cap is the depth times its start tags.
|
|
22
|
+
|
|
23
|
+
parse5 can't read a numeric character reference of 309 or more decimal
|
|
24
|
+
digits, or of 256 or more hex ones, at all: BadReference. */
|
|
22
25
|
/** How deep elements may be open at once — Chrome's own limit of the tree it builds. */
|
|
23
26
|
export declare const MAX_OPEN = 512;
|
|
24
27
|
export declare class TooDeep extends Error {
|
|
25
28
|
}
|
|
29
|
+
/** A numeric character reference parse5 can't read: its decoder (entities)
|
|
30
|
+
multiplies by 10 or 16 to the power of the digits — Infinity past 308
|
|
31
|
+
decimal or 255 hex ones — and 0 × Infinity is NaN, on which parse5
|
|
32
|
+
throws RangeError. Browsers read it as a character. The same guard is
|
|
33
|
+
in the preview proxy's reader (apps/api/src/lib/previewProxyHtml.ts). */
|
|
34
|
+
export declare class BadReference extends Error {
|
|
35
|
+
}
|
|
26
36
|
export type Html5Attr = Token.Attribute;
|
|
27
37
|
/** A node of the tree: an element (tagName), text, a comment, a doctype,
|
|
28
38
|
the document or a template's content — children linked both ways. Its
|
|
@@ -61,6 +71,7 @@ type Map_ = TreeAdapterTypeMap<Html5Node, Html5Node, Html5Node, Html5Node, Html5
|
|
|
61
71
|
/** parse5's default tree adapter, method for method, on linked children. */
|
|
62
72
|
export declare const linked: TreeAdapter<Map_>;
|
|
63
73
|
/** The document, with scripting on — as the runtime sees it (a <noscript>
|
|
64
|
-
is text). Throws TooDeep past MAX_OPEN open elements
|
|
74
|
+
is text). Throws TooDeep past MAX_OPEN open elements, BadReference at a
|
|
75
|
+
numeric character reference parse5 can't read. */
|
|
65
76
|
export declare function parseDocument(text: string): Html5Node;
|
|
66
77
|
export {};
|
package/dist/html5.js
CHANGED
|
@@ -7853,6 +7853,9 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
7853
7853
|
var MAX_OPEN = 512;
|
|
7854
7854
|
var TooDeep = class extends Error {
|
|
7855
7855
|
};
|
|
7856
|
+
var BadReference = class extends Error {
|
|
7857
|
+
};
|
|
7858
|
+
var isCodePoint = (cp) => Number.isInteger(cp) && cp >= 0 && cp <= 1114111;
|
|
7856
7859
|
var Html5Node = class {
|
|
7857
7860
|
constructor(nodeName, extra = {}) {
|
|
7858
7861
|
this.nodeName = nodeName;
|
|
@@ -7991,6 +7994,11 @@ var Guarded = class extends Parser {
|
|
|
7991
7994
|
names.add(this.currentAttr.name);
|
|
7992
7995
|
tag.attrs.push(this.currentAttr);
|
|
7993
7996
|
};
|
|
7997
|
+
const reference = tokenizer._flushCodePointConsumedAsCharacterReference;
|
|
7998
|
+
tokenizer._flushCodePointConsumedAsCharacterReference = function(cp) {
|
|
7999
|
+
if (!isCodePoint(cp)) throw new BadReference();
|
|
8000
|
+
reference.call(this, cp);
|
|
8001
|
+
};
|
|
7994
8002
|
}
|
|
7995
8003
|
onItemPush(...args) {
|
|
7996
8004
|
if (this.openElements.stackTop >= MAX_OPEN) throw new TooDeep();
|
|
@@ -8001,6 +8009,7 @@ function parseDocument(text) {
|
|
|
8001
8009
|
return Guarded.parse(text, { scriptingEnabled: true, treeAdapter: linked });
|
|
8002
8010
|
}
|
|
8003
8011
|
export {
|
|
8012
|
+
BadReference,
|
|
8004
8013
|
Html5Node,
|
|
8005
8014
|
MAX_OPEN,
|
|
8006
8015
|
TooDeep,
|
package/dist/report.d.ts
CHANGED
|
@@ -122,6 +122,10 @@ export type PreviewAnswer = {
|
|
|
122
122
|
status: "not_set_up";
|
|
123
123
|
origin: string;
|
|
124
124
|
path: string | null;
|
|
125
|
+
} | {
|
|
126
|
+
status: "no_route";
|
|
127
|
+
origin: string;
|
|
128
|
+
path: string | null;
|
|
125
129
|
};
|
|
126
130
|
/** "5 minutes" until the link stops working, or null when unknown. */
|
|
127
131
|
export declare function linkLifetime(expiresAt: string | undefined, now?: number): string | null;
|
package/dist/scanHtml.d.ts
CHANGED
|
@@ -20,7 +20,8 @@ export type HtmlElement = {
|
|
|
20
20
|
};
|
|
21
21
|
/** The elements of a page and their attributes — parse5's tree (html5.ts),
|
|
22
22
|
a <template>'s children being its content. Built without recursion:
|
|
23
|
-
a page nests up to MAX_OPEN elements, deeper throws TooDeep
|
|
23
|
+
a page nests up to MAX_OPEN elements, deeper throws TooDeep; a
|
|
24
|
+
numeric character reference parse5 can't read throws BadReference. */
|
|
24
25
|
export declare function parseHtml(text: string): HtmlElement;
|
|
25
26
|
/** Where a file is served and the key its bindings start with:
|
|
26
27
|
index.html → "/" (index), blog/index.html → "/blog/" (blog/index),
|
package/dist/scanHtml.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readdir, readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { MAX_OPEN, parseDocument, TooDeep } from "./html5.js";
|
|
4
|
+
import { BadReference, MAX_OPEN, parseDocument, TooDeep } from "./html5.js";
|
|
5
5
|
import { targetFor } from "./manifest.js";
|
|
6
6
|
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
7
7
|
const MAX_DEPTH = MAX_OPEN;
|
|
8
8
|
/** The elements of a page and their attributes — parse5's tree (html5.ts),
|
|
9
9
|
a <template>'s children being its content. Built without recursion:
|
|
10
|
-
a page nests up to MAX_OPEN elements, deeper throws TooDeep
|
|
10
|
+
a page nests up to MAX_OPEN elements, deeper throws TooDeep; a
|
|
11
|
+
numeric character reference parse5 can't read throws BadReference. */
|
|
11
12
|
export function parseHtml(text) {
|
|
12
13
|
const root = { name: "#document", attrs: new Map(), children: [] };
|
|
13
14
|
const pending = [[parseDocument(text), root]];
|
|
@@ -148,6 +149,7 @@ export async function scanHtml(dir, opts) {
|
|
|
148
149
|
const noTemplate = [];
|
|
149
150
|
const unusableRoutes = [];
|
|
150
151
|
const tooDeep = [];
|
|
152
|
+
const badReferences = [];
|
|
151
153
|
const notGroups = [];
|
|
152
154
|
const seenRoutes = new Set();
|
|
153
155
|
const pageKeys = new Set();
|
|
@@ -170,9 +172,12 @@ export async function scanHtml(dir, opts) {
|
|
|
170
172
|
doc = parseHtml(text);
|
|
171
173
|
}
|
|
172
174
|
catch (e) {
|
|
173
|
-
if (
|
|
175
|
+
if (e instanceof TooDeep)
|
|
176
|
+
tooDeep.push(file);
|
|
177
|
+
else if (e instanceof BadReference)
|
|
178
|
+
badReferences.push(file);
|
|
179
|
+
else
|
|
174
180
|
throw e;
|
|
175
|
-
tooDeep.push(file);
|
|
176
181
|
continue;
|
|
177
182
|
}
|
|
178
183
|
seenRoutes.add(served);
|
|
@@ -422,6 +427,8 @@ export async function scanHtml(dir, opts) {
|
|
|
422
427
|
notes.push(`A list or an each without a <template> isn't filled: ${list(noTemplate)}.`);
|
|
423
428
|
if (tooDeep.length > 0)
|
|
424
429
|
notes.push(`Elements nest deeper than ${MAX_OPEN} levels, so the scan didn't read ${count(tooDeep) === 1 ? "this page" : "these pages"}: ${list(tooDeep)}.`);
|
|
430
|
+
if (badReferences.length > 0)
|
|
431
|
+
notes.push(`A numeric character reference (&#…;) is too long to read, so the scan didn't read ${count(badReferences) === 1 ? "this page" : "these pages"}: ${list(badReferences)}.`);
|
|
425
432
|
if (unusableRoutes.length > 0)
|
|
426
433
|
notes.push(`Preview can't open ${count(unusableRoutes) === 1 ? "this address" : "these addresses"} — rename the file or the slug parameter: ${list(unusableRoutes)}.`);
|
|
427
434
|
// keys within the manifest's 120 characters, and still one per binding
|
package/dist/types.js
CHANGED
|
@@ -153,7 +153,9 @@ function renderedField(field, owner, names, extras) {
|
|
|
153
153
|
if (field.type === "computed" && field.computed) {
|
|
154
154
|
return { required: false, rendered: computedType(field.computed.resultType) };
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
const scalar = scalarType(field.type, field.options);
|
|
157
|
+
// translated (§28.2): one language per read — `locale` on the read picks it
|
|
158
|
+
return { required: field.required, rendered: field.localized === true ? { ...scalar, note: `${scalar.note}, translated` } : scalar };
|
|
157
159
|
}
|
|
158
160
|
/** Unique type names: the singular PascalCase of the key; the raw
|
|
159
161
|
PascalCase when two keys meet there; a numeric suffix as a last resort. */
|
package/dist/vanillaDigests.js
CHANGED
|
@@ -8,4 +8,7 @@
|
|
|
8
8
|
export const VANILLA_DIGESTS = {
|
|
9
9
|
"0.1.0": "sha384-mbuMcQAueviAbkTzgvxc8oDtspuYH6lFLUgE+gocGexnI8ehgSgdjnNMNL7JPk4q",
|
|
10
10
|
"0.1.1": "sha384-2vgQ4g9re/eiYxEa/H3WKpWI5C9L4wCB/62c8Kq+LOfZDzmqc2ozqMGC8mZoOUqk",
|
|
11
|
+
"0.1.2": "sha384-bhIJoFuEGouAZtHbYeNZeN0m6fqFVWpQw+YkSMJhfk/7m5bUwS/qVWZ3xczw/1du",
|
|
12
|
+
"0.2.0": "sha384-HJ5XG9AhAlbKe6jPRVaef3whiVup/5WhprMwqC6RwWhpq6Pb0OsRLzbLmLJ8WH0f",
|
|
13
|
+
"0.2.1": "sha384-6apTHYxXrozzwFCqNU+70Z9pa/FDnhArNomcKQNWbeKRX4scjFiOc9d7wWKCOvTU",
|
|
11
14
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapled/cli",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Mapled CLI — sign in, link a project, generate TypeScript types for its content, create forms, preview drafts and check the site's integration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://mapled.io",
|