@nxgt/material-core 0.3.0 → 0.3.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/CHANGELOG.md +139 -0
- package/README.md +39 -4
- package/docs/roadmap.md +16 -12
- package/docs/troubleshooting.md +65 -0
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @nxgt/material-core
|
|
2
|
+
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#429](https://github.com/softistx/nxgt-material/pull/429) [`13c3eda`](https://github.com/softistx/nxgt-material/commit/13c3edad01f08656ca196aca7c37a21e8c003466) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The package ships its `CHANGELOG.md` (now in `files`), so the notes of every
|
|
8
|
+
version are in `node_modules/<package>/CHANGELOG.md` next to the docs, for
|
|
9
|
+
reading offline and for the upgrade agents of the Claude Code plugins.
|
|
10
|
+
The getting-started pages of `@nxgt/material` and `@nxgt/material-vue`
|
|
11
|
+
list it among the tarball's contents.
|
|
12
|
+
|
|
13
|
+
## 0.3.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#427](https://github.com/softistx/nxgt-material/pull/427) [`d4e953f`](https://github.com/softistx/nxgt-material/commit/d4e953fd4fc147b366c5d9d70ebfb1aa3a3c0ba7) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Docs: the roadmap lists what 0.3.0 shipped (`/date-range`, `/file-preview`, `/slider-ticks`) under Shipped, newest first. Troubleshooting has entries for `FilePreviewHttpError` (`Could not read <url>: HTTP <status>`) and `FilePreviewUnsafeUrlError` (`Refused to preview a URL with an unsafe scheme`), so every message the package prints is there again. The README's `/pdf-viewer` section documents `pinToPage`'s `onRelease` and `pinHolds`, with an example.
|
|
18
|
+
|
|
19
|
+
## 0.3.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- [#424](https://github.com/softistx/nxgt-material/pull/424) [`d90a68b`](https://github.com/softistx/nxgt-material/commit/d90a68b8f16759b44929effc426b6c3964e92a4c) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New subpath `/date-range`, the pure half of both libraries' `DateRangeField`
|
|
24
|
+
presets and times: `DATE_RANGE_PRESET_IDS` (`today`, `yesterday`,
|
|
25
|
+
`last-7-days`, `last-30-days`, `this-month`, `last-month`, `this-year`),
|
|
26
|
+
`presetRange(id, now?)`, `resolvePresetRange(preset, now?, { withTime })`,
|
|
27
|
+
`isSameDayRange`, `isRangeDisabled(range, { min, max, isDayDisabled })`
|
|
28
|
+
(also true for a range whose end comes before its start),
|
|
29
|
+
`withTimeOf`, `endOfDayTime`, `clampRangeEnd`, `keepRangeTimes` (a new end
|
|
30
|
+
at 23:59), and the types
|
|
31
|
+
`DayRange`, `PartialDayRange`, `DateRangePreset`, `DateRangePresetId`,
|
|
32
|
+
`DateRangePresetOption` and `DateRangeRules`.
|
|
33
|
+
|
|
34
|
+
- [#426](https://github.com/softistx/nxgt-material/pull/426) [`812c101`](https://github.com/softistx/nxgt-material/commit/812c10115278480852852084ddf06b016239e6d4) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New subpath `/file-preview`, the pure half of both libraries' `FilePreview`:
|
|
35
|
+
`fileKind({ type, name, url })` picks a `FileKind` (`image`, `pdf`, `video`,
|
|
36
|
+
`audio`, `text`, `json`, `csv`, `markdown` or `other`) from the MIME type
|
|
37
|
+
when it names one (a `data:` URL's included), else from the extension of the
|
|
38
|
+
name, then of the URL; `describeFile(file, { type, name })` does it for a
|
|
39
|
+
`File` / `Blob` or a URL and returns its name, type and size;
|
|
40
|
+
`safePreviewUrl(url)` returns the URL when it may reach an `href` or a `src`
|
|
41
|
+
(`http(s):`, relative, `blob:`, or a `data:` URL of an image, video, audio
|
|
42
|
+
file, plain text, CSV, Markdown, JSON or PDF) and `null` for anything else
|
|
43
|
+
(`javascript:`, `data:text/html`, and also a `data:` URL of XML, TSV or
|
|
44
|
+
YAML), with `FilePreviewUnsafeUrlError` ("Refused to preview a URL with an unsafe scheme") for the one refused;
|
|
45
|
+
`readTextPreview(source, { maxBytes, signal })` reads the first `maxBytes`
|
|
46
|
+
(`TEXT_PREVIEW_MAX_BYTES`, 256 KB, by default) of a `Blob` or of what a URL
|
|
47
|
+
answers, decoded with the `charset` of the `Content-Type` (or of the `Blob`'s
|
|
48
|
+
`type`) when `TextDecoder` supports it and as UTF-8 otherwise, stopping the
|
|
49
|
+
download past the cap; it throws `FilePreviewHttpError` (with its `status`)
|
|
50
|
+
on an HTTP error, and rejects with the signal's reason once aborted, for a
|
|
51
|
+
`Blob` too. Also
|
|
52
|
+
`fileExtension`, `fileNameFromUrl`, `dataUrlType`, `kindOfMimeType`,
|
|
53
|
+
`normaliseMimeType`, `isTextFileKind`, `TEXT_FILE_KINDS` and the types
|
|
54
|
+
`FileKind`, `FileKindInput`, `DescribedFile`, `FilePreviewSource` and
|
|
55
|
+
`TextPreview`. Nothing runs at import.
|
|
56
|
+
|
|
57
|
+
- [#420](https://github.com/softistx/nxgt-material/pull/420) [`f4ca69b`](https://github.com/softistx/nxgt-material/commit/f4ca69ba5dd7b80f92cdd5374cf6fd01f155784d) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New subpath `/slider-ticks`: `tickValues(min, max, ticks, step?)`, the values a slider's tick marks sit at. Both libraries' `SliderField` (`ticks`) now read it from here instead of keeping a copy each.
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- [#419](https://github.com/softistx/nxgt-material/pull/419) [`99878c9`](https://github.com/softistx/nxgt-material/commit/99878c9bdb0d4c33fd6a777970c4f3735bd5ef3b) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `PdfReader`: opening on an `initialPage` no longer reports another page on a
|
|
62
|
+
slow device. The placement scroll could land after the scroll spy's hold had
|
|
63
|
+
run out, and near the end of the document it read as the last page. While
|
|
64
|
+
the view stays where the opening page's pin put it (that page at the top,
|
|
65
|
+
or the page area at its end with that page not above the top), a scroll is the reader's own and is not
|
|
66
|
+
reported; a scroll that moves the view elsewhere — the user's, find in page,
|
|
67
|
+
a screen reader's cursor — lets go of the pin and is reported. A wheel,
|
|
68
|
+
touch, pointer or key in the page area also ends the hold on the reader's
|
|
69
|
+
own scroll, so the scrolling after it is reported at once. In
|
|
70
|
+
`@nxgt/material-core/pdf-viewer`, `pinToPage` takes an optional `onRelease`,
|
|
71
|
+
called once when the pin lets go, and `pinHolds(node)` tells whether the view
|
|
72
|
+
is still where the pin puts it.
|
|
73
|
+
|
|
74
|
+
## 0.2.0
|
|
75
|
+
|
|
76
|
+
### Minor Changes
|
|
77
|
+
|
|
78
|
+
- [#406](https://github.com/softistx/nxgt-material/pull/406) [`b890457`](https://github.com/softistx/nxgt-material/commit/b8904573f18dc6d0cdd16f62146183ff0b7aef18) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Two new subpaths, each the one copy of code `@nxgt/material` and
|
|
79
|
+
`@nxgt/material-vue` used to keep twice:
|
|
80
|
+
|
|
81
|
+
- **`@nxgt/material-core/format-file-size`**: `formatFileSize(bytes)`, the
|
|
82
|
+
byte count both libraries' `FileList`, `NetworkUploadField`, `FileCard` and
|
|
83
|
+
chat attachments show (`'1.5 KB'`; `''` for a negative, `NaN` or infinite
|
|
84
|
+
size).
|
|
85
|
+
- **`@nxgt/material-core/pdfkit-fonts`** (Node only): `pdfkitStandardFontDirs`,
|
|
86
|
+
`pdfkitStandardFontFiles` and `PDFKIT_STANDARD_FONTS` find the real files of
|
|
87
|
+
pdfkit's standard fonts as an app loads them, through `@react-pdf/renderer`
|
|
88
|
+
and `@react-pdf/font`, for a server tracer (`@nxgt/material/next`, the Nuxt
|
|
89
|
+
module of `@nxgt/material-vue`). Without `@react-pdf/renderer` they return
|
|
90
|
+
`[]` silently; any other failure reaches your `warn` callback once per
|
|
91
|
+
call. It is the only subpath that imports `node:` built-ins: never import it
|
|
92
|
+
from browser code.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { formatFileSize } from '@nxgt/material-core/format-file-size';
|
|
96
|
+
import { pdfkitStandardFontDirs } from '@nxgt/material-core/pdfkit-fonts';
|
|
97
|
+
|
|
98
|
+
formatFileSize(1536); // '1.5 KB'
|
|
99
|
+
pdfkitStandardFontDirs(process.cwd(), console.warn); // ['/app/node_modules/pdfkit/js/standard-fonts']
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Patch Changes
|
|
103
|
+
|
|
104
|
+
- [#407](https://github.com/softistx/nxgt-material/pull/407) [`bf43a14`](https://github.com/softistx/nxgt-material/commit/bf43a14abb147e6dcd2bcac5f1e0e359b0aae6a2) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `pdfkitStandardFontDirs` and `pdfkitStandardFontFiles` (`/pdfkit-fonts`) keep
|
|
105
|
+
only the first line of each error in the one warning they give. Node's
|
|
106
|
+
`Cannot find module` error carries a multi-line `Require stack:`, and joined
|
|
107
|
+
whole into the `; `-separated message it made one warning dozens of lines
|
|
108
|
+
long; it now reads `could not resolve @react-pdf/font: Error: Cannot find
|
|
109
|
+
module '@react-pdf/font'; could not resolve pdfkit's fonts for …`.
|
|
110
|
+
|
|
111
|
+
## 0.1.1
|
|
112
|
+
|
|
113
|
+
### Patch Changes
|
|
114
|
+
|
|
115
|
+
- [#399](https://github.com/softistx/nxgt-material/pull/399) [`1abb908`](https://github.com/softistx/nxgt-material/commit/1abb90800ec213d8ec98abd7df5dda9f65c14204) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The package manifest no longer carries a `repository` field. The source
|
|
116
|
+
repository is private, so the link npm showed for it led to a 404; the
|
|
117
|
+
README and the `docs/` shipped in the tarball remain the public reference.
|
|
118
|
+
|
|
119
|
+
- [#398](https://github.com/softistx/nxgt-material/pull/398) [`b4e5770`](https://github.com/softistx/nxgt-material/commit/b4e5770922ad4582a1ad2dcca439f7c8c999a0c7) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Docs: the roadmap's Shipped list now has 0.1.0 — the first release, holding the framework-free code `@nxgt/material` and `@nxgt/material-vue` share.
|
|
120
|
+
|
|
121
|
+
## 0.1.0
|
|
122
|
+
|
|
123
|
+
### Minor Changes
|
|
124
|
+
|
|
125
|
+
- [#391](https://github.com/softistx/nxgt-material/pull/391) [`deaf0c4`](https://github.com/softistx/nxgt-material/commit/deaf0c49cbc2268fd20e9e2272104dbd27e4ce7f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - First release of `@nxgt/material-core`: the framework-free core that
|
|
126
|
+
`@nxgt/material` (React) and `@nxgt/material-vue` (Vue) share, as one copy.
|
|
127
|
+
The PDF document model (`/pdf/model`) and its react-pdf renderer
|
|
128
|
+
(`/pdf/render`, both also from `/pdf`), the print formatters (`/print-format`, `/print-value`,
|
|
129
|
+
`/print-table`, `/print-fraction-digits`), the PDF file helpers
|
|
130
|
+
(`/pdf-source`, `/pdf-file-name`, `/pdf-download`), serving a PDF
|
|
131
|
+
(`/pdf/http`, `/pdf/file-loader`), the PDF viewer's framework-free modules
|
|
132
|
+
(`/pdf-viewer`: page geometry, page sizes, scroll spy, text search), the
|
|
133
|
+
currency field's decimals (`/currency-digits`), the fields' blur layers
|
|
134
|
+
(`/field-blur-layers`) and the pdfkit fonts plugin (`/vite`).
|
|
135
|
+
`react` and `@react-pdf/renderer` are optional peers, needed only to render;
|
|
136
|
+
`vite` (6, 7 or 8) is one too, for the types of `/vite`.
|
|
137
|
+
Most apps get it through `@nxgt/material` or `@nxgt/material-vue`; a server
|
|
138
|
+
bundle that inlines either library (`ssr.noExternal`) must list
|
|
139
|
+
`@nxgt/material-core` beside it.
|
package/README.md
CHANGED
|
@@ -279,6 +279,37 @@ const page = pageTextFromItems([{ str: 'Café au', hasEOL: true }, { str: 'lait'
|
|
|
279
279
|
findTextMatches(page.text, 'cafe au lait'); // [{ start: 0, end: 12 }] — case, accents and line breaks ignored
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
+
To open a reader on a page, `pinToPage(node, beforeScroll, onRelease?)`
|
|
283
|
+
keeps that page at the top of the page area (an element inside the
|
|
284
|
+
`[data-slot="scroll-area-viewport"]` of a `[data-slot="scroll-area"]`) while
|
|
285
|
+
the pages above it change size, until a wheel, touch, pointer or key in the
|
|
286
|
+
page area, or the function it returns. `beforeScroll` runs before each
|
|
287
|
+
correction (hold your scroll spy there); `onRelease` runs once when the pin
|
|
288
|
+
lets go — at once when there is nothing to pin, or no `ResizeObserver` (a
|
|
289
|
+
server). `pinHolds(node)` tells whether the view still shows `node` where the
|
|
290
|
+
pin puts it: at the top, or as near as the area can scroll at its end. A
|
|
291
|
+
scroll that leaves it elsewhere came from find in page, a screen reader's
|
|
292
|
+
cursor or your own `scrollTop`, none of which the pin hears: treat it as the
|
|
293
|
+
user's.
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import { pinHolds, pinToPage } from '@nxgt/material-core/pdf-viewer';
|
|
297
|
+
|
|
298
|
+
// pages: Map<number, HTMLElement>; spy: from createScrollSpy
|
|
299
|
+
let pinned = true;
|
|
300
|
+
const unpin = pinToPage(
|
|
301
|
+
() => pages.get(3), // the page's element, looked up again on each correction
|
|
302
|
+
() => spy.hold(), // the corrections are not the user's scrolling
|
|
303
|
+
() => { pinned = false; }, // the pin let go
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
function onScroll(page: number) {
|
|
307
|
+
if (pinned && pinHolds(pages.get(3))) return; // still the reader's own scroll
|
|
308
|
+
unpin(); // the view moved elsewhere: let go, then report
|
|
309
|
+
reportPage(page);
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
282
313
|
### A currency's decimals: `/currency-digits`
|
|
283
314
|
|
|
284
315
|
```ts
|
|
@@ -377,14 +408,16 @@ and a `data:` URL of an image, video, audio file, plain text, CSV, Markdown,
|
|
|
377
408
|
JSON or PDF; it returns `null` for anything else (`javascript:`,
|
|
378
409
|
`vbscript:`, `data:text/html`, …), after removing what the browser ignores
|
|
379
410
|
(spaces and control characters at the ends, tabs and newlines anywhere), and
|
|
380
|
-
`FilePreviewUnsafeUrlError`
|
|
411
|
+
`FilePreviewUnsafeUrlError` ("Refused to preview a URL with an unsafe
|
|
412
|
+
scheme") is what `FilePreview` reports for one it refused.
|
|
381
413
|
`readTextPreview` reads the first bytes of a `Blob`, or of what a URL answers
|
|
382
414
|
(it stops downloading past the cap), decoded with the `charset` of the
|
|
383
415
|
response's `Content-Type` (or of the `Blob`'s `type`) when `TextDecoder`
|
|
384
416
|
supports it, else as UTF-8, and says whether there was more; an HTTP error
|
|
385
|
-
throws `FilePreviewHttpError`
|
|
386
|
-
rejects with its reason, for a `Blob`
|
|
387
|
-
safe on a server; only
|
|
417
|
+
throws `FilePreviewHttpError` (`Could not read <url>: HTTP <status>`) with
|
|
418
|
+
its `status`, and an aborted `signal` rejects with its reason, for a `Blob`
|
|
419
|
+
too. Nothing runs at import, so it is safe on a server; only
|
|
420
|
+
`readTextPreview` touches `fetch`.
|
|
388
421
|
|
|
389
422
|
```ts
|
|
390
423
|
import {
|
|
@@ -496,6 +529,8 @@ of `@nxgt/material-vue` adds the files to `nitro.externals.traceInclude`.
|
|
|
496
529
|
| `Cannot find package '@react-pdf/renderer'` (or `'react'`) when importing `/pdf` or `/pdf/render` | `bun add react @react-pdf/renderer@^4.9` — or import from `/pdf/model` where you only build documents |
|
|
497
530
|
| `Cannot find module '#standard-fonts/Helvetica'` on every request of a bundled server | `pdfkitStandardFonts()` from `/vite`, or keep the renderer external |
|
|
498
531
|
| `Cannot find module '…/pdfkit/js/standard-fonts/Helvetica.cjs'` from a traced server output | add `pdfkitStandardFontFiles()` (or the directories' `**/*.cjs`) to the tracer's includes — `withNxgtPrint` and the Nuxt module do |
|
|
532
|
+
| `Could not read <url>: HTTP 401` (`FilePreviewHttpError`) for a file behind authentication | fetch it with your credentials and pass the `Blob` to `readTextPreview` / `FilePreview` |
|
|
533
|
+
| `Refused to preview a URL with an unsafe scheme` (`FilePreviewUnsafeUrlError`) | pass an `https:` or relative URL, or the content as a `Blob` |
|
|
499
534
|
|
|
500
535
|
Every message, with its cause, is in [troubleshooting](https://cdn.jsdelivr.net/npm/@nxgt/material-core@0/docs/troubleshooting.md).
|
|
501
536
|
|
package/docs/roadmap.md
CHANGED
|
@@ -5,13 +5,7 @@ version an item shipped in is the only number on this page.
|
|
|
5
5
|
|
|
6
6
|
## Now
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
ranges, whether a field's rules rule a range out, and the time of day on
|
|
10
|
-
each end, for both libraries' `DateRangeField`.
|
|
11
|
-
- **File preview** (`/file-preview`) — which kind of preview a file gets from
|
|
12
|
-
its MIME type or extension, which URLs it may link to or load, and the
|
|
13
|
-
first bytes of a text file read with a size cap in its own charset, for
|
|
14
|
-
both libraries' `FilePreview`.
|
|
8
|
+
Nothing in progress right now; see Next.
|
|
15
9
|
|
|
16
10
|
## Next
|
|
17
11
|
|
|
@@ -37,14 +31,24 @@ version an item shipped in is the only number on this page.
|
|
|
37
31
|
|
|
38
32
|
## Shipped
|
|
39
33
|
|
|
34
|
+
- **Date range presets and times** (`/date-range`) — the built-in presets'
|
|
35
|
+
ranges, whether a field's rules rule a range out, and the time of day on
|
|
36
|
+
each end, for both libraries' `DateRangeField`. 0.3.0.
|
|
37
|
+
- **File preview** (`/file-preview`) — which kind of preview a file gets from
|
|
38
|
+
its MIME type or extension, which URLs it may link to or load, and the
|
|
39
|
+
first bytes of a text file read with a size cap in its own charset, for
|
|
40
|
+
both libraries' `FilePreview`. 0.3.0.
|
|
41
|
+
- **Slider ticks** (`/slider-ticks`) — the values a slider's tick marks sit
|
|
42
|
+
at, which both libraries' `SliderField` (`ticks`) read from here instead of
|
|
43
|
+
keeping a copy each. 0.3.0.
|
|
44
|
+
- **`formatFileSize` and the pdfkit fonts resolution** — the byte-count
|
|
45
|
+
formatter both libraries' file list and upload field use
|
|
46
|
+
(`/format-file-size`), and the Node-only resolution of pdfkit's standard
|
|
47
|
+
fonts behind `@nxgt/material/next` and `@nxgt/material-vue`'s Nuxt module
|
|
48
|
+
(`/pdfkit-fonts`), each kept once instead of in both libraries. 0.2.0.
|
|
40
49
|
- **A first release** — the PDF model and renderer, the print formatters,
|
|
41
50
|
the PDF file helpers, the PDF reader's framework-free modules
|
|
42
51
|
(`/pdf-viewer`: search, geometry, page sizes, scroll spy), the currency
|
|
43
52
|
digits, the fields' blur layers and the fonts plugin, which
|
|
44
53
|
`@nxgt/material` and `@nxgt/material-vue` shared file by file, are this one
|
|
45
54
|
package, and both libraries depend on it. 0.1.0.
|
|
46
|
-
- **`formatFileSize` and the pdfkit fonts resolution** — the byte-count
|
|
47
|
-
formatter both libraries' file list and upload field use
|
|
48
|
-
(`/format-file-size`), and the Node-only resolution of pdfkit's standard
|
|
49
|
-
fonts behind `@nxgt/material/next` and `@nxgt/material-vue`'s Nuxt module
|
|
50
|
-
(`/pdfkit-fonts`), each kept once instead of in both libraries. 0.2.0.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -17,6 +17,11 @@ file) is an example — search for the words around it.
|
|
|
17
17
|
|
|
18
18
|
- [`PdfReader cannot open …: pass a URL, a Blob, an ArrayBuffer, a Uint8Array or { url, httpHeaders }.`](#pdfreader-cannot-open--pass-a-url-a-blob-an-arraybuffer-a-uint8array-or--url-httpheaders-)
|
|
19
19
|
|
|
20
|
+
**File preview**
|
|
21
|
+
|
|
22
|
+
- [`Could not read <url>: HTTP <status>` (`FilePreviewHttpError`)](#could-not-read-url-http-status-filepreviewhttperror)
|
|
23
|
+
- [`Refused to preview a URL with an unsafe scheme` (`FilePreviewUnsafeUrlError`)](#refused-to-preview-a-url-with-an-unsafe-scheme-filepreviewunsafeurlerror)
|
|
24
|
+
|
|
20
25
|
**Build**
|
|
21
26
|
|
|
22
27
|
- [`… still references '#standard-fonts/' after the transform — …`](#-still-references-standard-fonts-after-the-transform--)
|
|
@@ -92,6 +97,66 @@ yet, or a `Response` instead of its bytes:
|
|
|
92
97
|
const bytes = await (await fetch(url)).arrayBuffer(); // not the Response
|
|
93
98
|
```
|
|
94
99
|
|
|
100
|
+
## File preview
|
|
101
|
+
|
|
102
|
+
### `Could not read <url>: HTTP <status>` (`FilePreviewHttpError`)
|
|
103
|
+
|
|
104
|
+
**When:** `readTextPreview(url)` from `/file-preview` — behind both
|
|
105
|
+
libraries' `FilePreview`, for a text, JSON, CSV or Markdown file given as a
|
|
106
|
+
URL — rejects with a `FilePreviewHttpError`, its message the URL as passed
|
|
107
|
+
and the status, as in `Could not read /files/notes.txt: HTTP 404`, and its
|
|
108
|
+
`status` the number. `FilePreview` shows "This file could not be previewed."
|
|
109
|
+
and hands this error to `onError` (`@error` in Vue).
|
|
110
|
+
**Why:** the server answered, but not with a `2xx`: a missing file (`404`),
|
|
111
|
+
a URL that needs credentials the request did not carry (`401`, `403` —
|
|
112
|
+
`fetch` sends cookies to the same origin only, and no `Authorization`
|
|
113
|
+
header), or a server error (`5xx`). Nothing of the body is read.
|
|
114
|
+
**Fix:** check the URL in the message. For a file behind authentication,
|
|
115
|
+
fetch it yourself with your credentials and pass the `Blob`, which is read
|
|
116
|
+
without a request; branch on `status` to tell a missing file from the rest:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { FilePreviewHttpError, readTextPreview } from '@nxgt/material-core/file-preview';
|
|
120
|
+
|
|
121
|
+
const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
122
|
+
const preview = await readTextPreview(await response.blob()); // a Blob: no request
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
await readTextPreview(url);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (error instanceof FilePreviewHttpError && error.status === 404) showMissing();
|
|
128
|
+
else throw error;
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
A cross-origin URL whose server sends no CORS headers is not this error: it
|
|
133
|
+
is `fetch`'s own `TypeError` (`Failed to fetch` in Chrome), with no status.
|
|
134
|
+
|
|
135
|
+
### `Refused to preview a URL with an unsafe scheme` (`FilePreviewUnsafeUrlError`)
|
|
136
|
+
|
|
137
|
+
**When:** both libraries' `FilePreview` is given a URL that
|
|
138
|
+
`safePreviewUrl` returns `null` for: it shows "This file could not be
|
|
139
|
+
previewed." with no Download link, and `onError` (`@error` in Vue) receives
|
|
140
|
+
this error. Nothing was linked, loaded or fetched.
|
|
141
|
+
**Why:** only `http:`, `https:`, a relative URL, `blob:` and a `data:` URL
|
|
142
|
+
of an image, video, audio file, plain text, CSV, Markdown, JSON or PDF may
|
|
143
|
+
reach an `href`, a `src` or `fetch`. Anything else — `javascript:`,
|
|
144
|
+
`data:text/html`, `file:`, and also a `data:` URL of XML, TSV or YAML — could
|
|
145
|
+
run script in your page or reach what it should not, so it is refused
|
|
146
|
+
whatever the file would have been. A URL with a colon before its first `/`,
|
|
147
|
+
`?` or `#` (`c:/files/a.txt`) reads as a scheme and is refused too.
|
|
148
|
+
**Fix:** serve the file over `https:` (or from your own origin), or turn its
|
|
149
|
+
content into a `Blob` and pass that — a `Blob` is previewed
|
|
150
|
+
through a `blob:` URL. Check a URL before rendering with `safePreviewUrl`:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { safePreviewUrl } from '@nxgt/material-core/file-preview';
|
|
154
|
+
|
|
155
|
+
safePreviewUrl('https://example.com/a.csv'); // 'https://example.com/a.csv'
|
|
156
|
+
safePreviewUrl('javascript:alert(1)'); // null
|
|
157
|
+
const file = safePreviewUrl(url) ?? new Blob([text], { type: 'text/yaml' });
|
|
158
|
+
```
|
|
159
|
+
|
|
95
160
|
## Build
|
|
96
161
|
|
|
97
162
|
### `… still references '#standard-fonts/' after the transform — …`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/material-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "The framework-free core of @nxgt/material and @nxgt/material-vue: the PDF document model and its react-pdf renderer, print formatters, PDF file helpers, the PDF viewer's pure modules, the currency digits, the file-size formatter, the field-blur layers, the date range presets, the file preview's kind detection and text reader, the pdfkit fonts Vite plugin and the Node-only pdfkit fonts resolution for Next.js and Nuxt builds",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"dist",
|
|
14
14
|
"docs",
|
|
15
15
|
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
16
17
|
"package.json",
|
|
17
18
|
"LICENSE"
|
|
18
19
|
],
|