@pipelex/mthds-form 0.11.0 → 0.12.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/dist/{chunk-E2IVBAW3.js → chunk-2D4NEFUH.js} +293 -104
- package/dist/chunk-2D4NEFUH.js.map +1 -0
- package/dist/chunk-7KQXGG6J.js +127 -0
- package/dist/chunk-7KQXGG6J.js.map +1 -0
- package/dist/{chunk-TID7ZN63.js → chunk-CM4KVG53.js} +13 -10
- package/dist/chunk-CM4KVG53.js.map +1 -0
- package/dist/{chunk-4JQAJT7C.js → chunk-RRTI7AIR.js} +25 -38
- package/dist/chunk-RRTI7AIR.js.map +1 -0
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +3 -2
- package/dist/core/native-content.d.ts +6 -1
- package/dist/core/native-content.js +1 -1
- package/dist/core/save-plan.d.ts +145 -0
- package/dist/core/save-plan.js +6 -0
- package/dist/core/save-plan.js.map +1 -0
- package/dist/core/stuff-files.d.ts +26 -3
- package/dist/core/stuff-files.js +2 -2
- package/dist/generative/index.js +7 -5
- package/dist/generative/index.js.map +1 -1
- package/dist/react/index.d.ts +177 -108
- package/dist/react/index.js +4 -3
- package/package.json +1 -1
- package/dist/chunk-4JQAJT7C.js.map +0 -1
- package/dist/chunk-E2IVBAW3.js.map +0 -1
- package/dist/chunk-TID7ZN63.js.map +0 -1
package/dist/react/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { a as FieldRenderer, b as FieldRendererProps } from '../field-renderer-C
|
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
import { BooleanRunField, DateRunField, EnumRunField, FileRunField, ListRunField, NumberRunField, ObjectRunField, ProseRunField, TextRunField, UnknownRunField, RunField, ConceptCategory } from '../core/descriptor.js';
|
|
6
|
+
import { SaveFiles, SaveFile, SaveResult } from '../core/save-plan.js';
|
|
7
|
+
import { StuffFileKind } from '../core/stuff-files.js';
|
|
6
8
|
import { HtmlContentView } from '../core/native-content.js';
|
|
7
9
|
import '../core/contracts.js';
|
|
8
10
|
import 'mthds/protocol';
|
|
@@ -217,115 +219,14 @@ interface ResultFieldProps {
|
|
|
217
219
|
*/
|
|
218
220
|
hideLabel?: boolean;
|
|
219
221
|
}
|
|
220
|
-
/** The single dispatch point, mirroring `FieldRenderer` on the input side. */
|
|
221
|
-
declare function ResultField({ field, value, depth, hideLabel }: ResultFieldProps): react.JSX.Element | null;
|
|
222
|
-
|
|
223
222
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* ## Two, and why not three
|
|
223
|
+
* The single dispatch point, mirroring `FieldRenderer` on the input side.
|
|
227
224
|
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* is debugging the pipe: what exactly came back, verbatim, copyable. Those are
|
|
232
|
-
* different jobs and neither substitutes for the other.
|
|
233
|
-
*
|
|
234
|
-
* They are deliberately NOT peers, and the toggle should not read as a menu of
|
|
235
|
-
* equal options. One is the result; the other is the receipt. Rendered opens
|
|
236
|
-
* first, always.
|
|
237
|
-
*
|
|
238
|
-
* A third view is the one to resist. An engine-rendered HTML or plain-text
|
|
239
|
-
* presentation — the shape the runtime's own viewer offers — is a second human
|
|
240
|
-
* rendering of the same payload, produced by another codebase, carrying no
|
|
241
|
-
* descriptor (so it cannot know a kind, a plurality or a nesting) and unable to
|
|
242
|
-
* match a host's design system. It is a renderer that cannot be improved without
|
|
243
|
-
* shipping the engine. If a plain-text form is wanted, it is a COPY FORMAT and
|
|
244
|
-
* belongs behind a copy control, not beside the view that reads the standard.
|
|
225
|
+
* The outermost one also marks the root of the result, when no panel above it
|
|
226
|
+
* has: a file's own download button names the file by its place in the result,
|
|
227
|
+
* and the place starts here. Every nested one finds the root already there.
|
|
245
228
|
*/
|
|
246
|
-
|
|
247
|
-
interface StuffViewerProps {
|
|
248
|
-
field: RunField;
|
|
249
|
-
value: unknown;
|
|
250
|
-
/**
|
|
251
|
-
* The STUFF's name, for the header — `report_pages`, not `output`.
|
|
252
|
-
*
|
|
253
|
-
* A result descriptor's root node is named by the engine that built it, and
|
|
254
|
-
* `build_output_form` calls it `output` for every pipe there has ever been.
|
|
255
|
-
* That is correct in the artifact: the descriptor describes a pipe's output
|
|
256
|
-
* slot, which has no name of its own. It is wrong on screen, where the reader
|
|
257
|
-
* is looking at ONE data item and every other surface — the graph node they
|
|
258
|
-
* clicked, the input panel beside it, the method's own code — calls that item
|
|
259
|
-
* by the name the author gave it.
|
|
260
|
-
*
|
|
261
|
-
* So the name comes from the caller, because only the caller knows it: the
|
|
262
|
-
* graph knows which node was opened, a run page knows which variable it is
|
|
263
|
-
* showing. Absent, the descriptor's own name stands, which keeps a host that
|
|
264
|
-
* has nothing better to say honest rather than blank.
|
|
265
|
-
*
|
|
266
|
-
* It also supplies `downloadBaseName`'s default, so the file a reader saves
|
|
267
|
-
* is named after the thing they were reading rather than `output.json`.
|
|
268
|
-
*/
|
|
269
|
-
name?: string;
|
|
270
|
-
/** Which view opens first. Rendered, unless a host has a reason. */
|
|
271
|
-
defaultView?: StuffViewerView;
|
|
272
|
-
/**
|
|
273
|
-
* Names the saved files: `<baseName>.json`, and any file inside the stuff
|
|
274
|
-
* that carries no name of its own. Defaults to the field's name, which is
|
|
275
|
-
* what the header shows.
|
|
276
|
-
*/
|
|
277
|
-
downloadBaseName?: string;
|
|
278
|
-
/**
|
|
279
|
-
* Hide the download control. For a host that saves results its own way, or a
|
|
280
|
-
* surface where saving makes no sense — a preview inside an editor, say.
|
|
281
|
-
*/
|
|
282
|
-
hideDownload?: boolean;
|
|
283
|
-
className?: string;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* The payload as JSON — the receipt, with the whole of it one click from the
|
|
287
|
-
* clipboard.
|
|
288
|
-
*
|
|
289
|
-
* Exported because it is also the honest FLOOR: a host that holds a value but
|
|
290
|
-
* not the artifacts describing it (an older engine, a spec restored without its
|
|
291
|
-
* validate report) should show the value and say why it is not laid out, rather
|
|
292
|
-
* than show nothing. That is a different thing from what `StuffViewer`'s JSON
|
|
293
|
-
* tab was — one labelled fallback, not one of three guesses offered as a
|
|
294
|
-
* choice.
|
|
295
|
-
*/
|
|
296
|
-
declare function JsonView({ value }: {
|
|
297
|
-
value: unknown;
|
|
298
|
-
}): react.JSX.Element;
|
|
299
|
-
declare function StuffViewer({ field, value, name, defaultView, downloadBaseName, hideDownload, className, }: StuffViewerProps): react.JSX.Element;
|
|
300
|
-
|
|
301
|
-
/** How a host turns a stored reference into something fetchable. */
|
|
302
|
-
type ResolveForDownload = (url: string) => string | undefined;
|
|
303
|
-
/**
|
|
304
|
-
* Everything a stuff contains, saved.
|
|
305
|
-
*
|
|
306
|
-
* The rule the caller asked for, and the one that matches what a result IS: the
|
|
307
|
-
* data goes down as JSON, and any image or document inside it goes down as
|
|
308
|
-
* ITSELF. A JSON file holding a URL to a picture is not the picture, and a
|
|
309
|
-
* reader who clicks download on a report with three attachments wants the three
|
|
310
|
-
* attachments — the reference is what the payload had, not what they asked for.
|
|
311
|
-
*
|
|
312
|
-
* The JSON is written whenever the stuff is anything more than its files: a
|
|
313
|
-
* result that IS one image has nothing left over once the image is saved, so
|
|
314
|
-
* writing `{"url": …}` beside it would be a second file saying less than the
|
|
315
|
-
* first. A result with fields around its files keeps both.
|
|
316
|
-
*
|
|
317
|
-
* A file that cannot be fetched is opened in a tab instead of failing. The
|
|
318
|
-
* fetch is same-origin for a host that proxies its storage, but a remote URL
|
|
319
|
-
* with no CORS header cannot be read into a blob at all, and handing the reader
|
|
320
|
-
* the file in a tab is the difference between an awkward download and none.
|
|
321
|
-
*/
|
|
322
|
-
declare function downloadStuff({ field, value, baseName, resolveUrl, }: {
|
|
323
|
-
field: RunField;
|
|
324
|
-
value: unknown;
|
|
325
|
-
/** Names the JSON file and prefixes any file that has no name of its own. */
|
|
326
|
-
baseName: string;
|
|
327
|
-
resolveUrl?: ResolveForDownload;
|
|
328
|
-
}): Promise<void>;
|
|
229
|
+
declare function ResultField(props: ResultFieldProps): react.JSX.Element;
|
|
329
230
|
|
|
330
231
|
/**
|
|
331
232
|
* The host's seam for turning a stored reference into something a browser can
|
|
@@ -401,10 +302,57 @@ type ResolveShareUrl = (url: string) => Promise<string | undefined>;
|
|
|
401
302
|
* Only `http:` and `https:` are ever painted or linked either way.
|
|
402
303
|
*/
|
|
403
304
|
type ProseImages = 'link' | 'load';
|
|
305
|
+
/**
|
|
306
|
+
* Which download controls a result view draws, each set on its own.
|
|
307
|
+
*
|
|
308
|
+
* Apps want different things here: one shows only the download of the whole
|
|
309
|
+
* result, another only a download on each image, a third both, a fourth
|
|
310
|
+
* neither because it saves results its own way. So the two are independent,
|
|
311
|
+
* and the per-file one can be narrowed to the kinds of file that should carry
|
|
312
|
+
* it.
|
|
313
|
+
*
|
|
314
|
+
* Set once on `ResultEnvProvider`, because a file's own button is drawn deep
|
|
315
|
+
* inside the result (a gallery tile, a table row's detail, a nested record) and
|
|
316
|
+
* has to follow the setting whether or not a `StuffViewer` wraps it.
|
|
317
|
+
* `StuffViewer`'s own `downloads` prop overrides it, key by key, for that one
|
|
318
|
+
* panel.
|
|
319
|
+
*
|
|
320
|
+
* Hiding a control never disables saving: a host with its own save UI still
|
|
321
|
+
* plans with `planStuffSave` and delivers through its own function.
|
|
322
|
+
*/
|
|
323
|
+
interface DownloadDisplay {
|
|
324
|
+
/** The header control that saves the whole result. Drawn unless `false`. */
|
|
325
|
+
result?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Each file's own download button: on every file when `true` (the default),
|
|
328
|
+
* on none when `false`, or only on the kinds listed — `'image'`,
|
|
329
|
+
* `'document'`, and `'markup'` for an HTML page.
|
|
330
|
+
*/
|
|
331
|
+
files?: boolean | readonly StuffFileKind[];
|
|
332
|
+
}
|
|
404
333
|
interface ResultEnv {
|
|
405
334
|
resolveUrl?: ResolveUrl;
|
|
406
335
|
resolveShareUrl?: ResolveShareUrl;
|
|
407
336
|
proseImages?: ProseImages;
|
|
337
|
+
/**
|
|
338
|
+
* How saved files reach the reader. Every download goes through it: the
|
|
339
|
+
* whole-result control and each file's own button alike, each handing it the
|
|
340
|
+
* files to save as a plan (a name, a media type, and the URL the gate
|
|
341
|
+
* admitted or the inline text).
|
|
342
|
+
*
|
|
343
|
+
* Unset, files are saved by the browser tab (`saveInBrowser`), which fetches
|
|
344
|
+
* each URL and saves the bytes through an object URL and a clicked link. A
|
|
345
|
+
* host whose view runs in a sandboxed frame is refused all of that, and
|
|
346
|
+
* supplies a function that asks the host to deliver the files instead —
|
|
347
|
+
* passing the URLs on as links, since a host's download bridge fetches links
|
|
348
|
+
* itself.
|
|
349
|
+
*
|
|
350
|
+
* It reports the files it could not deliver rather than throwing, so the
|
|
351
|
+
* control can tell the reader which ones did not arrive.
|
|
352
|
+
*/
|
|
353
|
+
saveFiles?: SaveFiles;
|
|
354
|
+
/** Which download controls are drawn. Both, on every kind of file, when unset. */
|
|
355
|
+
downloads?: DownloadDisplay;
|
|
408
356
|
/**
|
|
409
357
|
* How many data columns a table of records shows. Five when unset.
|
|
410
358
|
*
|
|
@@ -422,7 +370,7 @@ interface ResultEnv {
|
|
|
422
370
|
*/
|
|
423
371
|
tableColumns?: number;
|
|
424
372
|
}
|
|
425
|
-
declare function ResultEnvProvider({ resolveUrl, resolveShareUrl, proseImages, tableColumns, children, }: ResultEnv & {
|
|
373
|
+
declare function ResultEnvProvider({ resolveUrl, resolveShareUrl, proseImages, tableColumns, saveFiles, downloads, children, }: ResultEnv & {
|
|
426
374
|
children: ReactNode;
|
|
427
375
|
}): react.JSX.Element;
|
|
428
376
|
/**
|
|
@@ -443,6 +391,113 @@ declare function useResolveShareUrl(): ResolveShareUrl | undefined;
|
|
|
443
391
|
/** The prose-image policy, defaulted to the safe answer for a host that stated none. */
|
|
444
392
|
declare function useProseImages(): ProseImages;
|
|
445
393
|
|
|
394
|
+
/**
|
|
395
|
+
* A pipe's result, with the two views a result actually needs.
|
|
396
|
+
*
|
|
397
|
+
* ## Two, and why not three
|
|
398
|
+
*
|
|
399
|
+
* **Rendered** is the answer for a person: the descriptor-driven view, which
|
|
400
|
+
* knows a field is an enum, that a date arrived in the serializer's typed
|
|
401
|
+
* envelope, that fifteen records are a table. **JSON** is the answer for whoever
|
|
402
|
+
* is debugging the pipe: what exactly came back, verbatim, copyable. Those are
|
|
403
|
+
* different jobs and neither substitutes for the other.
|
|
404
|
+
*
|
|
405
|
+
* They are deliberately NOT peers, and the toggle should not read as a menu of
|
|
406
|
+
* equal options. One is the result; the other is the receipt. Rendered opens
|
|
407
|
+
* first, always.
|
|
408
|
+
*
|
|
409
|
+
* A third view is the one to resist. An engine-rendered HTML or plain-text
|
|
410
|
+
* presentation — the shape the runtime's own viewer offers — is a second human
|
|
411
|
+
* rendering of the same payload, produced by another codebase, carrying no
|
|
412
|
+
* descriptor (so it cannot know a kind, a plurality or a nesting) and unable to
|
|
413
|
+
* match a host's design system. It is a renderer that cannot be improved without
|
|
414
|
+
* shipping the engine. If a plain-text form is wanted, it is a COPY FORMAT and
|
|
415
|
+
* belongs behind a copy control, not beside the view that reads the standard.
|
|
416
|
+
*/
|
|
417
|
+
type StuffViewerView = 'rendered' | 'json';
|
|
418
|
+
interface StuffViewerProps {
|
|
419
|
+
field: RunField;
|
|
420
|
+
value: unknown;
|
|
421
|
+
/**
|
|
422
|
+
* The STUFF's name, for the header — `report_pages`, not `output`.
|
|
423
|
+
*
|
|
424
|
+
* A result descriptor's root node is named by the engine that built it, and
|
|
425
|
+
* `build_output_form` calls it `output` for every pipe there has ever been.
|
|
426
|
+
* That is correct in the artifact: the descriptor describes a pipe's output
|
|
427
|
+
* slot, which has no name of its own. It is wrong on screen, where the reader
|
|
428
|
+
* is looking at ONE data item and every other surface — the graph node they
|
|
429
|
+
* clicked, the input panel beside it, the method's own code — calls that item
|
|
430
|
+
* by the name the author gave it.
|
|
431
|
+
*
|
|
432
|
+
* So the name comes from the caller, because only the caller knows it: the
|
|
433
|
+
* graph knows which node was opened, a run page knows which variable it is
|
|
434
|
+
* showing. Absent, the descriptor's own name stands, which keeps a host that
|
|
435
|
+
* has nothing better to say honest rather than blank.
|
|
436
|
+
*
|
|
437
|
+
* It also supplies `downloadBaseName`'s default, so the file a reader saves
|
|
438
|
+
* is named after the thing they were reading rather than `output.json`.
|
|
439
|
+
*/
|
|
440
|
+
name?: string;
|
|
441
|
+
/** Which view opens first. Rendered, unless a host has a reason. */
|
|
442
|
+
defaultView?: StuffViewerView;
|
|
443
|
+
/**
|
|
444
|
+
* Names the saved files, whichever control saved them: the base name names
|
|
445
|
+
* the whole stuff, so the JSON copy is `<baseName>.json`, a file inside the
|
|
446
|
+
* stuff that carries no name of its own is `<baseName>-<place>`, and a stuff
|
|
447
|
+
* that is one file saves as `<baseName>.<ext>`. Defaults to the field's name,
|
|
448
|
+
* which is what the header shows. Give each stuff a distinct base name, as
|
|
449
|
+
* the default already is: two panels handed the same one save their unnamed
|
|
450
|
+
* files under the same names.
|
|
451
|
+
*/
|
|
452
|
+
downloadBaseName?: string;
|
|
453
|
+
/**
|
|
454
|
+
* Which download controls this panel draws, laid key by key over what
|
|
455
|
+
* `ResultEnvProvider` says: `{ result: false }` drops the header's Download
|
|
456
|
+
* and keeps each file's own button, `{ files: false }` the reverse. For a
|
|
457
|
+
* surface where saving makes no sense (a preview inside an editor, say), set
|
|
458
|
+
* both to `false`.
|
|
459
|
+
*/
|
|
460
|
+
downloads?: DownloadDisplay;
|
|
461
|
+
className?: string;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* The payload as JSON — the receipt, with the whole of it one click from the
|
|
465
|
+
* clipboard.
|
|
466
|
+
*
|
|
467
|
+
* Exported because it is also the honest FLOOR: a host that holds a value but
|
|
468
|
+
* not the artifacts describing it (an older engine, a spec restored without its
|
|
469
|
+
* validate report) should show the value and say why it is not laid out, rather
|
|
470
|
+
* than show nothing. That is a different thing from what `StuffViewer`'s JSON
|
|
471
|
+
* tab was — one labelled fallback, not one of three guesses offered as a
|
|
472
|
+
* choice.
|
|
473
|
+
*/
|
|
474
|
+
declare function JsonView({ value }: {
|
|
475
|
+
value: unknown;
|
|
476
|
+
}): react.JSX.Element;
|
|
477
|
+
declare function StuffViewer({ downloads, ...props }: StuffViewerProps): react.JSX.Element;
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* The default delivery: the planned files, saved by this browser tab.
|
|
481
|
+
*
|
|
482
|
+
* Inline content is written straight into a blob. A URL is fetched and its
|
|
483
|
+
* bytes saved under the planned name. The fetch is same-origin for a host that
|
|
484
|
+
* proxies its storage, and works cross-origin only where the server sends a
|
|
485
|
+
* CORS header, so a file that cannot be read is REPORTED rather than recovered.
|
|
486
|
+
*
|
|
487
|
+
* There used to be a recovery: open the URL in a new tab when the fetch failed.
|
|
488
|
+
* It could not run. The fetch is awaited, so by the time it failed the click
|
|
489
|
+
* that started the download was spent, and a popup blocker suppresses a window
|
|
490
|
+
* opened outside a click, silently, inside a `catch` that also swallowed the
|
|
491
|
+
* reason. Reporting the file instead is what lets the control that asked tell
|
|
492
|
+
* the reader, and the reader still has the file's own link in the rendered
|
|
493
|
+
* view.
|
|
494
|
+
*
|
|
495
|
+
* This is also what a host gets from `ResultEnvProvider` when it supplies no
|
|
496
|
+
* `saveFiles` of its own, and it is exported for a host that wants to fall back
|
|
497
|
+
* to it, from a bridge that is not always there.
|
|
498
|
+
*/
|
|
499
|
+
declare function saveInBrowser(files: readonly SaveFile[]): Promise<SaveResult>;
|
|
500
|
+
|
|
446
501
|
interface HtmlPreviewProps {
|
|
447
502
|
content: HtmlContentView;
|
|
448
503
|
/**
|
|
@@ -622,6 +677,20 @@ interface FieldStrings {
|
|
|
622
677
|
download: string;
|
|
623
678
|
/** Announced while the files are being fetched. */
|
|
624
679
|
downloading: string;
|
|
680
|
+
/**
|
|
681
|
+
* What the whole-result download says when some files did not arrive: the
|
|
682
|
+
* ones no URL could be found for, and the ones the delivery reported. Takes
|
|
683
|
+
* the names the files would have been saved under.
|
|
684
|
+
*/
|
|
685
|
+
downloadIncomplete: (names: readonly string[]) => string;
|
|
686
|
+
/**
|
|
687
|
+
* The button beside each file that saves that one file, given the name it
|
|
688
|
+
* saves under: a gallery of buttons all called "Download" would leave a
|
|
689
|
+
* screen-reader user unable to tell which file each one saves.
|
|
690
|
+
*/
|
|
691
|
+
downloadFile: (name: string) => string;
|
|
692
|
+
/** What that button says when the file did not arrive. */
|
|
693
|
+
downloadFileFailed: string;
|
|
625
694
|
/** The result panel's two views, and the control that copies the payload. */
|
|
626
695
|
viewRendered: string;
|
|
627
696
|
viewJson: string;
|
|
@@ -708,4 +777,4 @@ declare function useFieldPresentation(): FieldPresentation;
|
|
|
708
777
|
*/
|
|
709
778
|
declare function humanizeFieldName(name: string): string;
|
|
710
779
|
|
|
711
|
-
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EnumField, FieldDomIdProvider, FieldEnv, type FieldPresentation, FieldPresentationProvider, FieldShell, type FieldStrings, FieldStringsProvider, type FileValue, HtmlPreview, type HtmlPreviewProps, ImageField, JsonView, ListField, Markdown, type MarkdownProps, NumberField, ObjectField, OptionalToggle, ProseField, type ProseImages, type
|
|
780
|
+
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, type DownloadDisplay, EnumField, FieldDomIdProvider, FieldEnv, type FieldPresentation, FieldPresentationProvider, FieldShell, type FieldStrings, FieldStringsProvider, type FileValue, HtmlPreview, type HtmlPreviewProps, ImageField, JsonView, ListField, Markdown, type MarkdownProps, NumberField, ObjectField, OptionalToggle, ProseField, type ProseImages, type ResolveShareUrl, type ResolveUrl, ResultEnvProvider, ResultField, type ResultFieldProps, StuffViewer, type StuffViewerProps, type StuffViewerView, TextField, UnknownField, fieldControlClass, humanizeFieldName, saveInBrowser, useFieldDomId, useFieldPresentation, useFieldStrings, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl };
|
package/dist/react/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EnumField, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, HtmlPreview, ImageField, JsonView, ListField, Markdown, NumberField, ObjectField, OptionalToggle, ProseField, ResultEnvProvider, ResultField, StuffViewer, TextField, UnknownField,
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EnumField, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, HtmlPreview, ImageField, JsonView, ListField, Markdown, NumberField, ObjectField, OptionalToggle, ProseField, ResultEnvProvider, ResultField, StuffViewer, TextField, UnknownField, fieldControlClass, humanizeFieldName, saveInBrowser, useFieldDomId, useFieldPresentation, useFieldStrings, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl } from '../chunk-2D4NEFUH.js';
|
|
3
|
+
import '../chunk-7KQXGG6J.js';
|
|
4
|
+
import '../chunk-RRTI7AIR.js';
|
|
5
|
+
import '../chunk-CM4KVG53.js';
|
|
5
6
|
import '../chunk-FABY3DEY.js';
|
|
6
7
|
import '../chunk-XCO6GTEC.js';
|
|
7
8
|
import '../chunk-PM55AHRO.js';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/stuff-files.ts"],"names":[],"mappings":"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","file":"chunk-4JQAJT7C.js","sourcesContent":["import { ownProp } from './own-property';\nimport {\n isNativeHtmlNode,\n readDocumentContent,\n readHtmlContent,\n readImageContent,\n} from './native-content';\nimport type { RunField } from './descriptor';\n\n/**\n * One file a stuff carries: what to fetch, and what to call it once saved.\n */\nexport interface StuffFile {\n /**\n * The durable reference or URL the value states, for a file held BY\n * REFERENCE. Absent for inline content, which needs no fetch.\n */\n url?: string;\n /**\n * The content itself, for a file the stuff carries INLINE — markup, today.\n * Exactly one of `url` and `text` is set.\n */\n text?: string;\n /** The extension to save inline content under, without the dot. */\n extension?: string;\n /**\n * The URL that works outside this session, when the value carries one. A host\n * whose display URL is session-scoped (an owner-checked proxy route) needs\n * this for anything that leaves the browser.\n */\n publicUrl?: string;\n /** The file's own name when it states one — otherwise the caller derives it. */\n filename?: string;\n mimeType?: string;\n /** Where it sat, dotted: `report.attachments.2.scan`. Names a saved file. */\n path: string;\n kind: 'image' | 'document' | 'markup';\n}\n\n/**\n * Every file inside a stuff, found by walking the DESCRIPTOR — never the value.\n *\n * The distinction is the whole point. A payload walk would have to decide what\n * a file is by looking at it: an object with a `url`, a string that ends in\n * `.pdf`. That is the guessing this package exists to remove, and it is wrong in\n * both directions — a method whose output legitimately has a `url` field of its\n * own is not a document, and a stored image whose reference carries no extension\n * is. The descriptor already states `kind: \"image\"` or `kind: \"document\"`, so\n * the walk reads the declaration and consults the value only for the members\n * that declaration promises.\n *\n * Ordering is the authored one, depth-first, which is the order the rendered\n * view puts them in — so a download of three images numbers them the way the\n * reader saw them.\n */\nexport function collectStuffFiles(field: RunField, value: unknown): StuffFile[] {\n const found: StuffFile[] = [];\n walk(field, value, [], found);\n return found;\n}\n\nfunction walk(field: RunField, raw: unknown, path: string[], out: StuffFile[]): void {\n const value = unwrapContent(field, raw);\n const here = path.length > 0 ? path : [field.name];\n\n // Markup, before the kind switch, exactly as the renderer takes it: a\n // `native.Html` node's KIND is `object` (its content model has two members),\n // so the switch below would walk into it looking for files and find none.\n //\n // It is a file even though nothing stores it as one. The stuff IS a page —\n // the reader is looking at a rendered report — and handing them a JSON\n // envelope with the page inside it as a string is the same mistake as handing\n // them a URL instead of a picture. `isNativeHtmlNode` asks the descriptor\n // whether the concept refines `native.Html`, which is the standard's own way\n // to ask; it never looks at the value to decide.\n if (isNativeHtmlNode(field)) {\n const content = readHtmlContent(value);\n if (content?.innerHtml) {\n out.push({\n text: content.innerHtml,\n extension: 'html',\n path: here.join('.'),\n kind: 'markup',\n });\n }\n return;\n }\n\n switch (field.kind) {\n case 'image': {\n const content = readImageContent(value);\n if (content?.url) {\n out.push({\n url: content.url,\n publicUrl: content.publicUrl,\n filename: content.filename,\n mimeType: content.mimeType,\n path: here.join('.'),\n kind: 'image',\n });\n }\n return;\n }\n case 'document': {\n const content = readDocumentContent(value);\n if (content?.url) {\n out.push({\n url: content.url,\n publicUrl: content.publicUrl,\n filename: content.filename,\n mimeType: content.mimeType,\n path: here.join('.'),\n kind: 'document',\n });\n }\n return;\n }\n case 'object': {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return;\n const record = value as Record<string, unknown>;\n for (const child of field.fields) {\n walk(child, ownProp(record, child.name), [...here, child.name], out);\n }\n return;\n }\n case 'list': {\n if (!Array.isArray(value)) return;\n // The element descriptor's own `name` is unused by the standard, so the\n // index is what identifies an entry — the same thing the rendered list\n // shows beside each row.\n value.forEach((entry, index) => walk(field.item, entry, [...here, String(index)], out));\n return;\n }\n default:\n // Every other kind is a scalar. It cannot contain a file, and a `native`\n // node with no declared members (an `unknown` kind — a composite, say)\n // states nothing a walk could follow, so there is nothing to look at.\n return;\n }\n}\n\n/**\n * The one unwrap path, matching the renderer's: a content model is opened by\n * the property the schema named, and by nothing else.\n */\nfunction unwrapContent(field: RunField, value: unknown): unknown {\n if (!field.contentKey) return value;\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return value;\n const unwrapped = ownProp(value as Record<string, unknown>, field.contentKey);\n return unwrapped === undefined ? value : unwrapped;\n}\n"]}
|