@xtrable-ltd/nanoesis 0.1.10 → 0.1.12
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/adapter-azure-blob.js +1 -1
- package/dist/chunk-EN5SMEWJ.js +1221 -0
- package/dist/{chunk-UZQ7UP2B.js → chunk-XO3CT6GL.js} +167 -15
- package/dist/editor-api.js +21 -1197
- package/dist/index.d.ts +139 -76
- package/dist/index.js +5 -1
- package/dist/mcp.d.ts +48 -0
- package/dist/mcp.js +76 -0
- package/editor/assets/{MigrationsPane-_FGonx4-.js → MigrationsPane-BYGqWBAA.js} +1 -1
- package/editor/assets/{TemplatesPane-Z6Bn69Hb.js → TemplatesPane-B5hn_v0Z.js} +168 -164
- package/editor/assets/{TemplatesPane-CiLiMCc8.css → TemplatesPane-D0gGehUt.css} +1 -1
- package/editor/assets/{cssMode-dkQrIPWx.js → cssMode-BbIf5k6I.js} +1 -1
- package/editor/assets/{freemarker2-DEqcFFWa.js → freemarker2-DoW0pSYV.js} +1 -1
- package/editor/assets/{handlebars-C6ojANWr.js → handlebars-DLlET-qc.js} +1 -1
- package/editor/assets/{html-BmiAmVUD.js → html-4khbqrhe.js} +1 -1
- package/editor/assets/{htmlMode-BBmUqToI.js → htmlMode-DblHkZ-k.js} +1 -1
- package/editor/assets/index-CkESQLMV.css +7 -0
- package/editor/assets/index-Do1drqEQ.js +138 -0
- package/editor/assets/{javascript-Cxm2TfJy.js → javascript-CgPO2Hmj.js} +1 -1
- package/editor/assets/{jsonMode-CW5012Hx.js → jsonMode-BrWh2436.js} +1 -1
- package/editor/assets/{liquid-DrS7ilHv.js → liquid-BsQJXwPT.js} +1 -1
- package/editor/assets/{mdx-CwdSU5o1.js → mdx-AO8t67gx.js} +1 -1
- package/editor/assets/{python-CALCR0yC.js → python-3w4sZj5c.js} +1 -1
- package/editor/assets/{razor-SVCo2LoM.js → razor-BFsvo06w.js} +1 -1
- package/editor/assets/{tsMode-CzXfTR_Q.js → tsMode-QrC4ERjp.js} +1 -1
- package/editor/assets/{typescript-CP0Ovrv7.js → typescript-BXJ3QLad.js} +1 -1
- package/editor/assets/{xml-B2yqloTa.js → xml-CxKYn1FP.js} +1 -1
- package/editor/assets/{yaml-DTLJhzgY.js → yaml-BmWLvF7Q.js} +1 -1
- package/editor/index.html +2 -2
- package/package.json +7 -1
- package/editor/assets/index-DEz8GUII.css +0 -7
- package/editor/assets/index-LtCzUHAw.js +0 -138
package/dist/index.d.ts
CHANGED
|
@@ -458,22 +458,108 @@ interface CompileInput {
|
|
|
458
458
|
declare function compileTemplate(input: CompileInput): string;
|
|
459
459
|
|
|
460
460
|
/**
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
461
|
+
* The field-type registry (DESIGN §6.7). Field types and their rules are defined
|
|
462
|
+
* *once* here and shared by the compiler, the editor's form generator, and (later)
|
|
463
|
+
* Monaco's IntelliSense. This is the OCP extension point (CLAUDE.md §3): adding a
|
|
464
|
+
* field type means adding an entry here, never editing a switch in the compiler or
|
|
465
|
+
* the inference cascade.
|
|
466
|
+
*/
|
|
467
|
+
type FieldType = 'image' | 'file' | 'url' | 'email' | 'phone' | 'date' | 'time' | 'code' | 'richtext' | 'authors' | 'text' | 'shorttext';
|
|
468
|
+
/** How a resolved value is placed into output, the compiler reads this, never the type name. */
|
|
469
|
+
type ValueKind = 'text' | 'html' | 'url' | 'asset' | 'authors';
|
|
470
|
+
interface FieldTypeDef {
|
|
471
|
+
readonly type: FieldType;
|
|
472
|
+
readonly valueKind: ValueKind;
|
|
473
|
+
/** Default editor control hint, consumed by the form generator (DESIGN §7). */
|
|
474
|
+
readonly control: string;
|
|
475
|
+
readonly multiline: boolean;
|
|
476
|
+
}
|
|
477
|
+
declare const FIELD_TYPES: Readonly<Record<FieldType, FieldTypeDef>>;
|
|
478
|
+
declare function isFieldType(value: string): value is FieldType;
|
|
479
|
+
declare function valueKindOf(type: FieldType): ValueKind;
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Derive the editor's form from a template, "the template is the schema"
|
|
483
|
+
* (DESIGN §5.5/§6). Walking the same parse the compiler uses, each page-scope
|
|
484
|
+
* token becomes one field whose control is inferred from where it sits, deduped by
|
|
485
|
+
* name and labelled. This is the single source of truth the editor's form
|
|
486
|
+
* generator and the compiler share (DESIGN §6.7).
|
|
487
|
+
*
|
|
488
|
+
* Inference is **component-aware**: when a component is used (`<doc file="{x}">`),
|
|
489
|
+
* the bound field's type comes from how that prop is used *inside* the component,
|
|
490
|
+
* not from the attribute's position on the usage. A component's prop types are
|
|
491
|
+
* simply the field types of its own body, so the same derivation resolves them,
|
|
492
|
+
* recursively, through nested components, with a cycle guard.
|
|
493
|
+
*/
|
|
494
|
+
interface DerivedField {
|
|
495
|
+
readonly name: string;
|
|
496
|
+
readonly type: FieldType;
|
|
497
|
+
readonly label: string;
|
|
498
|
+
readonly required: boolean;
|
|
499
|
+
readonly multiline: boolean;
|
|
500
|
+
readonly help?: string;
|
|
501
|
+
/** Minimum character length (`data-minlength`); the gate warns when shorter. */
|
|
502
|
+
readonly minLength?: number;
|
|
503
|
+
/** Maximum character length (`data-maxlength`); the gate warns when longer. */
|
|
504
|
+
readonly maxLength?: number;
|
|
505
|
+
/** A curated multi-reference (a `data-each` loop field). */
|
|
506
|
+
readonly multiple?: boolean;
|
|
507
|
+
/** Collection the reference picker is scoped to (`data-pick-from`). */
|
|
508
|
+
readonly pickFrom?: string;
|
|
509
|
+
}
|
|
510
|
+
/** Author-declared length bounds on a field value (`data-minlength`/`data-maxlength`). */
|
|
511
|
+
interface LengthConstraints {
|
|
512
|
+
readonly minLength?: number;
|
|
513
|
+
readonly maxLength?: number;
|
|
514
|
+
}
|
|
515
|
+
declare function deriveFields(template: string, components?: ComponentMap): DerivedField[];
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Stamping decisions (PROPOSAL-template-versioning §4.1, PROPOSAL-llm-guardrails §4).
|
|
519
|
+
* `detectStamp` is pure — given the old and new template sources, it decides whether a
|
|
520
|
+
* destructive change is taking place and reports the schema delta (added / removed
|
|
521
|
+
* fields, plus per-token type changes).
|
|
522
|
+
*
|
|
523
|
+
* Two destructive shapes (PROPOSAL-llm-guardrails §1, both share the same recovery
|
|
524
|
+
* story — auto-stamp a snapshot, flag for migration):
|
|
469
525
|
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
526
|
+
* 1. **Token-set asymmetric.** A token removed or renamed. The token *doesn't exist*
|
|
527
|
+
* in the new schema, so content authored against it has nowhere to render.
|
|
528
|
+
* 2. **Token retained, type changed destructively.** The token *still exists*, but
|
|
529
|
+
* its inferred type can't losslessly render data authored under the old type
|
|
530
|
+
* (`richtext → shorttext` silently escapes HTML; `shorttext → image` reinterprets
|
|
531
|
+
* free text as a path). The §4 rule in {@link isDestructiveTypeChange} encodes
|
|
532
|
+
* which transitions are destructive vs widening.
|
|
533
|
+
*
|
|
534
|
+
* Both flow through `IndexedStore.write`'s auto-stamp path identically — the editor
|
|
535
|
+
* UI and MCP both see the same recovery affordance, regardless of which destructive
|
|
536
|
+
* shape triggered it.
|
|
475
537
|
*/
|
|
476
538
|
type TemplateKind = 'template' | 'component';
|
|
539
|
+
/** A field reference (name + inferred type) in the schema delta returned by `computeSchemaDelta`. */
|
|
540
|
+
interface SchemaFieldRef {
|
|
541
|
+
readonly name: string;
|
|
542
|
+
readonly type: FieldType;
|
|
543
|
+
}
|
|
544
|
+
/** A type change on a token retained across the edit (PROPOSAL-llm-guardrails §4-§5). */
|
|
545
|
+
interface TypeChange {
|
|
546
|
+
readonly name: string;
|
|
547
|
+
readonly from: FieldType;
|
|
548
|
+
readonly to: FieldType;
|
|
549
|
+
/** True when the change can't losslessly render data authored under `from`. */
|
|
550
|
+
readonly destructive: boolean;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Structured "what changed" report (PROPOSAL-llm-guardrails §5). Returned by
|
|
554
|
+
* `IndexedStore.write` for template/component writes so callers (MCP, editor UI)
|
|
555
|
+
* can react without re-deriving themselves. Empty arrays everywhere when an edit
|
|
556
|
+
* changes only whitespace, comments, or non-token markup.
|
|
557
|
+
*/
|
|
558
|
+
interface SchemaDelta {
|
|
559
|
+
readonly added: readonly SchemaFieldRef[];
|
|
560
|
+
readonly removed: readonly SchemaFieldRef[];
|
|
561
|
+
readonly typeChanged: readonly TypeChange[];
|
|
562
|
+
}
|
|
477
563
|
/** What `detectStamp` learned from comparing two template sources. */
|
|
478
564
|
interface StampDecision {
|
|
479
565
|
readonly destructive: boolean;
|
|
@@ -481,6 +567,8 @@ interface StampDecision {
|
|
|
481
567
|
readonly removedTokens: readonly string[];
|
|
482
568
|
/** Tokens present in `newSource` but absent in `oldSource`, sorted for stability. */
|
|
483
569
|
readonly addedTokens: readonly string[];
|
|
570
|
+
/** Tokens retained but whose inferred type changed (PROPOSAL-llm-guardrails §1). */
|
|
571
|
+
readonly typeChanged: readonly TypeChange[];
|
|
484
572
|
}
|
|
485
573
|
/** The record `stampSnapshot` returns (and that the write path surfaces as `stamped`). */
|
|
486
574
|
interface StampRecord {
|
|
@@ -491,13 +579,35 @@ interface StampRecord {
|
|
|
491
579
|
/** The full path the snapshot was written to. */
|
|
492
580
|
readonly snapshotPath: string;
|
|
493
581
|
}
|
|
582
|
+
/**
|
|
583
|
+
* Whether a field's type change from `from` to `to` can't losslessly render content
|
|
584
|
+
* authored against `from`. Drives both auto-stamp (destructive triggers a snapshot)
|
|
585
|
+
* and the validation gate's `content.type-drift` warning per-item.
|
|
586
|
+
*
|
|
587
|
+
* The rule (PROPOSAL-llm-guardrails §4) reduces to:
|
|
588
|
+
* - `anything → richtext` is safe (HTML escapes text fine).
|
|
589
|
+
* - `richtext → anything else` is destructive (HTML becomes escaped text).
|
|
590
|
+
* - Free-text → strict date/time is destructive (ISO required, free text won't parse).
|
|
591
|
+
* - `date ↔ time` is destructive (both ISO but different shapes; values don't transfer).
|
|
592
|
+
* - Same `valueKind` otherwise is non-destructive (text ↔ text, asset ↔ asset).
|
|
593
|
+
* - Cross-`valueKind` into text is non-destructive (text representation works).
|
|
594
|
+
* - Everything else cross-kind is destructive (text → asset/url/authors; asset ↔ url; …).
|
|
595
|
+
*/
|
|
596
|
+
declare function isDestructiveTypeChange(from: FieldType, to: FieldType): boolean;
|
|
597
|
+
/**
|
|
598
|
+
* Compute the schema delta between two field lists. The richer counterpart to the
|
|
599
|
+
* token-name diff in {@link detectStamp} — used by `IndexedStore.write` to surface
|
|
600
|
+
* `schemaDelta` (PROPOSAL-llm-guardrails §5) without re-deriving on the caller side.
|
|
601
|
+
* Pure; component-aware via `deriveFields`.
|
|
602
|
+
*/
|
|
603
|
+
declare function computeSchemaDelta(oldFields: readonly DerivedField[], newFields: readonly DerivedField[]): SchemaDelta;
|
|
494
604
|
/**
|
|
495
605
|
* Decide whether the change from `oldSource` to `newSource` is destructive, and report
|
|
496
|
-
*
|
|
497
|
-
* the same `deriveFields` the editor's form generator uses
|
|
498
|
-
* is taken against is identical to what the form shows
|
|
499
|
-
*
|
|
500
|
-
*
|
|
606
|
+
* the schema diff (added / removed / typeChanged). Pure — no I/O. The field-name +
|
|
607
|
+
* type set is derived via the same `deriveFields` the editor's form generator uses
|
|
608
|
+
* (so the "schema" the decision is taken against is identical to what the form shows).
|
|
609
|
+
* Component-aware: fields bound to component props are categorised by how that
|
|
610
|
+
* component uses them internally, matching the compiler's resolution.
|
|
501
611
|
*/
|
|
502
612
|
declare function detectStamp(oldSource: string, newSource: string, components?: ComponentMap): StampDecision;
|
|
503
613
|
|
|
@@ -533,6 +643,16 @@ interface WriteResult {
|
|
|
533
643
|
* is known to be unavailable for items affected by this particular stamp.
|
|
534
644
|
*/
|
|
535
645
|
readonly stampIncomplete?: boolean;
|
|
646
|
+
/**
|
|
647
|
+
* The schema diff between the old and new bytes for template/component writes
|
|
648
|
+
* (PROPOSAL-llm-guardrails §5). Present whenever the target is a template or
|
|
649
|
+
* component and there was a prior version; undefined for content writes, public
|
|
650
|
+
* files, and brand-new templates. Carries `added`/`removed` (with types) and
|
|
651
|
+
* `typeChanged` (with per-change `destructive` flag). MCP callers consume this to
|
|
652
|
+
* react to schema impact without re-deriving; the editor surfaces a summary in the
|
|
653
|
+
* stamp banner.
|
|
654
|
+
*/
|
|
655
|
+
readonly schemaDelta?: SchemaDelta;
|
|
536
656
|
}
|
|
537
657
|
/**
|
|
538
658
|
* The editor's working store (DESIGN §11c): a read {@link ContentSource} for
|
|
@@ -802,27 +922,6 @@ declare const DOCUMENT_SHELL = "document";
|
|
|
802
922
|
*/
|
|
803
923
|
declare function loadDocumentShell(source: ContentSource, templatesDir?: string): Promise<string | undefined>;
|
|
804
924
|
|
|
805
|
-
/**
|
|
806
|
-
* The field-type registry (DESIGN §6.7). Field types and their rules are defined
|
|
807
|
-
* *once* here and shared by the compiler, the editor's form generator, and (later)
|
|
808
|
-
* Monaco's IntelliSense. This is the OCP extension point (CLAUDE.md §3): adding a
|
|
809
|
-
* field type means adding an entry here, never editing a switch in the compiler or
|
|
810
|
-
* the inference cascade.
|
|
811
|
-
*/
|
|
812
|
-
type FieldType = 'image' | 'file' | 'url' | 'email' | 'phone' | 'date' | 'time' | 'code' | 'richtext' | 'authors' | 'text' | 'shorttext';
|
|
813
|
-
/** How a resolved value is placed into output, the compiler reads this, never the type name. */
|
|
814
|
-
type ValueKind = 'text' | 'html' | 'url' | 'asset' | 'authors';
|
|
815
|
-
interface FieldTypeDef {
|
|
816
|
-
readonly type: FieldType;
|
|
817
|
-
readonly valueKind: ValueKind;
|
|
818
|
-
/** Default editor control hint, consumed by the form generator (DESIGN §7). */
|
|
819
|
-
readonly control: string;
|
|
820
|
-
readonly multiline: boolean;
|
|
821
|
-
}
|
|
822
|
-
declare const FIELD_TYPES: Readonly<Record<FieldType, FieldTypeDef>>;
|
|
823
|
-
declare function isFieldType(value: string): value is FieldType;
|
|
824
|
-
declare function valueKindOf(type: FieldType): ValueKind;
|
|
825
|
-
|
|
826
925
|
/**
|
|
827
926
|
* Contextual token inference (DESIGN §6.2). A token's control type is inferred from
|
|
828
927
|
* *where it sits*, via a precedence cascade:
|
|
@@ -1047,42 +1146,6 @@ declare function buildRss(entries: readonly PageEntry[], options: RssOptions): A
|
|
|
1047
1146
|
*/
|
|
1048
1147
|
declare function buildContentIndex(entries: readonly PageEntry[]): Artifact;
|
|
1049
1148
|
|
|
1050
|
-
/**
|
|
1051
|
-
* Derive the editor's form from a template, "the template is the schema"
|
|
1052
|
-
* (DESIGN §5.5/§6). Walking the same parse the compiler uses, each page-scope
|
|
1053
|
-
* token becomes one field whose control is inferred from where it sits, deduped by
|
|
1054
|
-
* name and labelled. This is the single source of truth the editor's form
|
|
1055
|
-
* generator and the compiler share (DESIGN §6.7).
|
|
1056
|
-
*
|
|
1057
|
-
* Inference is **component-aware**: when a component is used (`<doc file="{x}">`),
|
|
1058
|
-
* the bound field's type comes from how that prop is used *inside* the component,
|
|
1059
|
-
* not from the attribute's position on the usage. A component's prop types are
|
|
1060
|
-
* simply the field types of its own body, so the same derivation resolves them,
|
|
1061
|
-
* recursively, through nested components, with a cycle guard.
|
|
1062
|
-
*/
|
|
1063
|
-
interface DerivedField {
|
|
1064
|
-
readonly name: string;
|
|
1065
|
-
readonly type: FieldType;
|
|
1066
|
-
readonly label: string;
|
|
1067
|
-
readonly required: boolean;
|
|
1068
|
-
readonly multiline: boolean;
|
|
1069
|
-
readonly help?: string;
|
|
1070
|
-
/** Minimum character length (`data-minlength`); the gate warns when shorter. */
|
|
1071
|
-
readonly minLength?: number;
|
|
1072
|
-
/** Maximum character length (`data-maxlength`); the gate warns when longer. */
|
|
1073
|
-
readonly maxLength?: number;
|
|
1074
|
-
/** A curated multi-reference (a `data-each` loop field). */
|
|
1075
|
-
readonly multiple?: boolean;
|
|
1076
|
-
/** Collection the reference picker is scoped to (`data-pick-from`). */
|
|
1077
|
-
readonly pickFrom?: string;
|
|
1078
|
-
}
|
|
1079
|
-
/** Author-declared length bounds on a field value (`data-minlength`/`data-maxlength`). */
|
|
1080
|
-
interface LengthConstraints {
|
|
1081
|
-
readonly minLength?: number;
|
|
1082
|
-
readonly maxLength?: number;
|
|
1083
|
-
}
|
|
1084
|
-
declare function deriveFields(template: string, components?: ComponentMap): DerivedField[];
|
|
1085
|
-
|
|
1086
1149
|
/**
|
|
1087
1150
|
* Static analysis of a template's structure, used by the validation gate, the
|
|
1088
1151
|
* media phase, and (later) the editor. Extracts the signals downstream needs:
|
|
@@ -1597,4 +1660,4 @@ declare function createDiagnosticRegistry(): DiagnosticRegistry;
|
|
|
1597
1660
|
|
|
1598
1661
|
declare const workingStoreRoundTripDiagnostic: Diagnostic;
|
|
1599
1662
|
|
|
1600
|
-
export { type Artifact, type ArtifactSink, type AuthEndpoints, type AuthResult, type AuthorDirectory, type AuthorEntry, type AuthorOption, type AuthorRef, type AuthoringReference, type BlobStore, type BoundItem, type ChangePasswordRequest, type ChangePasswordSuccess, type CollectionConfig, type CollectionQuery, type CompileInput, type CompilePageOptions, type CompileSiteOptions, type CompiledPage, type ComponentMap, type ContentIndex, type ContentItem, ContentParseError, type ContentSource, type CreateTokenSuccess, type CreateUserRequest, DEFAULT_DIRS, DOCUMENT_SHELL, type DerivedField, type DiagnoseDeps, type Severity as DiagnoseSeverity, type Source as DiagnoseSource, type Diagnostic$1 as Diagnostic, type Diagnostic as DiagnosticCheck, type DiagnosticRegistry, type DirEntry, type DirNode, type EncodeRequest, type EncodedImage, type EncodedVariant, type EntryKind, FIELD_TYPES, type FieldPrimitive, type FieldRecord, type FieldType, type FieldTypeDef, type FieldValue, type Finding, type IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type MigrationResolution, type PageEntry, type PendingMigrationItem, type PendingMigrations, type PreBuildHook, type Principal, type PublishOptions, type PublishResult, type PublishSummary, type PurgeService, RESERVED_PREFIX, type ReconcileResult, type RedirectRule, type ReferenceContext, type ReferenceEntry, type ReferenceSection, type RefreshSuccess, type RenameResult, type Repair, type RepairArgs, type ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type Scope, type Severity$1 as Severity, type SiteConfig, type SortFile, type StampDecision, type StampRecord, type TemplateAnalysis, type TemplateKind, type TokenContext, type TokenRef, type TreeNode, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type WorkingStore, analyzeTemplate, applyMigration, baseTemplateName, bestFitSnapshot, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, canEdit, compilePage, compileSite, compileTemplate, contentHash, contentTypeFor, createDiagnosticRegistry, deriveFields, detectStamp, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isFieldType, isReservedVersionedPath, isVersionedTemplateName, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadRedirects, loadSiteConfig, loadTemplate, nextVersionNumber, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, pendingMigrations, processImage, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, slugify, snapshotName, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, versionNumber, wholeValueToken, workingStoreRoundTripDiagnostic };
|
|
1663
|
+
export { type Artifact, type ArtifactSink, type AuthEndpoints, type AuthResult, type AuthorDirectory, type AuthorEntry, type AuthorOption, type AuthorRef, type AuthoringReference, type BlobStore, type BoundItem, type ChangePasswordRequest, type ChangePasswordSuccess, type CollectionConfig, type CollectionQuery, type CompileInput, type CompilePageOptions, type CompileSiteOptions, type CompiledPage, type ComponentMap, type ContentIndex, type ContentItem, ContentParseError, type ContentSource, type CreateTokenSuccess, type CreateUserRequest, DEFAULT_DIRS, DOCUMENT_SHELL, type DerivedField, type DiagnoseDeps, type Severity as DiagnoseSeverity, type Source as DiagnoseSource, type Diagnostic$1 as Diagnostic, type Diagnostic as DiagnosticCheck, type DiagnosticRegistry, type DirEntry, type DirNode, type EncodeRequest, type EncodedImage, type EncodedVariant, type EntryKind, FIELD_TYPES, type FieldPrimitive, type FieldRecord, type FieldType, type FieldTypeDef, type FieldValue, type Finding, type IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type MigrationResolution, type PageEntry, type PendingMigrationItem, type PendingMigrations, type PreBuildHook, type Principal, type PublishOptions, type PublishResult, type PublishSummary, type PurgeService, RESERVED_PREFIX, type ReconcileResult, type RedirectRule, type ReferenceContext, type ReferenceEntry, type ReferenceSection, type RefreshSuccess, type RenameResult, type Repair, type RepairArgs, type ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type SchemaDelta, type SchemaFieldRef, type Scope, type Severity$1 as Severity, type SiteConfig, type SortFile, type StampDecision, type StampRecord, type TemplateAnalysis, type TemplateKind, type TokenContext, type TokenRef, type TreeNode, type TypeChange, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type WorkingStore, analyzeTemplate, applyMigration, baseTemplateName, bestFitSnapshot, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, canEdit, compilePage, compileSite, compileTemplate, computeSchemaDelta, contentHash, contentTypeFor, createDiagnosticRegistry, deriveFields, detectStamp, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isDestructiveTypeChange, isFieldType, isReservedVersionedPath, isVersionedTemplateName, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadRedirects, loadSiteConfig, loadTemplate, nextVersionNumber, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, pendingMigrations, processImage, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, slugify, snapshotName, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, versionNumber, wholeValueToken, workingStoreRoundTripDiagnostic };
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
compilePage,
|
|
24
24
|
compileSite,
|
|
25
25
|
compileTemplate,
|
|
26
|
+
computeSchemaDelta,
|
|
26
27
|
contentHash,
|
|
27
28
|
contentTypeFor,
|
|
28
29
|
createDiagnosticRegistry,
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
hasRole,
|
|
37
38
|
humanize,
|
|
38
39
|
inferControl,
|
|
40
|
+
isDestructiveTypeChange,
|
|
39
41
|
isFieldType,
|
|
40
42
|
isReservedVersionedPath,
|
|
41
43
|
isVersionedTemplateName,
|
|
@@ -73,7 +75,7 @@ import {
|
|
|
73
75
|
versionNumber,
|
|
74
76
|
wholeValueToken,
|
|
75
77
|
workingStoreRoundTripDiagnostic
|
|
76
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-XO3CT6GL.js";
|
|
77
79
|
export {
|
|
78
80
|
ContentParseError,
|
|
79
81
|
DEFAULT_DIRS,
|
|
@@ -99,6 +101,7 @@ export {
|
|
|
99
101
|
compilePage,
|
|
100
102
|
compileSite,
|
|
101
103
|
compileTemplate,
|
|
104
|
+
computeSchemaDelta,
|
|
102
105
|
contentHash,
|
|
103
106
|
contentTypeFor,
|
|
104
107
|
createDiagnosticRegistry,
|
|
@@ -112,6 +115,7 @@ export {
|
|
|
112
115
|
hasRole,
|
|
113
116
|
humanize,
|
|
114
117
|
inferControl,
|
|
118
|
+
isDestructiveTypeChange,
|
|
115
119
|
isFieldType,
|
|
116
120
|
isReservedVersionedPath,
|
|
117
121
|
isVersionedTemplateName,
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ApiDeps } from '@nanoesis/editor-api';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Identity reported to MCP clients on `initialize`. Defaults: `{ name: 'nanoesis', version:
|
|
5
|
+
* '0.0.0' }`. Adopters embedding the HTTP route in their own host typically override `name`
|
|
6
|
+
* with their site identifier and `version` with their app version so client UIs identify
|
|
7
|
+
* the deployment, not the framework.
|
|
8
|
+
*/
|
|
9
|
+
interface McpServerIdentity {
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly version?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Options for {@link handleMcpRequest}. Both fields are passed straight through to the
|
|
16
|
+
* MCP `Server`'s `initialize` response so client UIs (Claude Desktop, Cursor, …) identify
|
|
17
|
+
* the deployment rather than the framework.
|
|
18
|
+
*/
|
|
19
|
+
type HandleMcpRequestOptions = McpServerIdentity;
|
|
20
|
+
/**
|
|
21
|
+
* Handle a single MCP HTTP request over the SDK's web-standard Streamable HTTP transport
|
|
22
|
+
* (DESIGN §11c/§14). Stateless: each call builds a fresh `Server` + `Transport` pair, so
|
|
23
|
+
* the caller's per-request `Authorization: Bearer …` header — propagated by the SDK into
|
|
24
|
+
* the request handlers as `extra.requestInfo.headers` — drives the editor's per-user role
|
|
25
|
+
* gate exactly as `/api/*` does.
|
|
26
|
+
*
|
|
27
|
+
* The signature is Fetch-API neutral: any runtime that hands a handler a standard
|
|
28
|
+
* `Request` (Azure Functions v4, Cloudflare Workers, plain Node 18+, Bun, Deno, Hono)
|
|
29
|
+
* wires it the same way:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { handleMcpRequest } from '@xtrable-ltd/nanoesis/mcp';
|
|
33
|
+
* // ... build `deps` once at startup
|
|
34
|
+
* app.http('mcp', {
|
|
35
|
+
* methods: ['POST', 'GET', 'DELETE'],
|
|
36
|
+
* handler: (req) => handleMcpRequest(deps, req, { name: 'my-site', version: pkg.version }),
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* Runtimes whose request shape is not a standard `Request` (e.g. Azure Functions' enhanced
|
|
41
|
+
* HttpRequest, Express' IncomingMessage) translate to/from `Request`/`Response` at the
|
|
42
|
+
* boundary — that translation is adopter-side because it depends on the host runtime; the
|
|
43
|
+
* MCP server construction and transport handling, which used to be ~120 lines of inlined
|
|
44
|
+
* boilerplate per adopter, is now this one call.
|
|
45
|
+
*/
|
|
46
|
+
declare function handleMcpRequest(deps: ApiDeps, request: Request, opts?: HandleMcpRequestOptions): Promise<Response>;
|
|
47
|
+
|
|
48
|
+
export { type HandleMcpRequestOptions, handleMcpRequest };
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MCP_RESOURCES,
|
|
3
|
+
MCP_TOOLS,
|
|
4
|
+
callMcpTool,
|
|
5
|
+
readMcpResource
|
|
6
|
+
} from "./chunk-EN5SMEWJ.js";
|
|
7
|
+
import "./chunk-XO3CT6GL.js";
|
|
8
|
+
|
|
9
|
+
// ../../hosts/host-mcp/src/http.ts
|
|
10
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
11
|
+
|
|
12
|
+
// ../../hosts/host-mcp/src/server.ts
|
|
13
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
14
|
+
import {
|
|
15
|
+
CallToolRequestSchema,
|
|
16
|
+
ListResourcesRequestSchema,
|
|
17
|
+
ListToolsRequestSchema,
|
|
18
|
+
ReadResourceRequestSchema
|
|
19
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
20
|
+
var BEARER_PREFIX = /^Bearer\s+/i;
|
|
21
|
+
function bearerFrom(headers) {
|
|
22
|
+
if (headers === void 0) return void 0;
|
|
23
|
+
const raw = headers["authorization"] ?? headers["Authorization"];
|
|
24
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
25
|
+
if (value === void 0) return void 0;
|
|
26
|
+
const match = BEARER_PREFIX.exec(value);
|
|
27
|
+
return match ? value.slice(match[0].length).trim() : void 0;
|
|
28
|
+
}
|
|
29
|
+
function createMcpServer(deps, identity) {
|
|
30
|
+
const server = new Server(
|
|
31
|
+
{ name: identity?.name ?? "nanoesis", version: identity?.version ?? "0.0.0" },
|
|
32
|
+
{ capabilities: { tools: {}, resources: {} } }
|
|
33
|
+
);
|
|
34
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [...MCP_TOOLS] }));
|
|
35
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
36
|
+
const args = req.params.arguments ?? {};
|
|
37
|
+
const token = bearerFrom(extra.requestInfo?.headers);
|
|
38
|
+
const result = await callMcpTool(
|
|
39
|
+
deps,
|
|
40
|
+
req.params.name,
|
|
41
|
+
args,
|
|
42
|
+
token !== void 0 ? { token } : {}
|
|
43
|
+
);
|
|
44
|
+
return { content: [{ type: "text", text: result.text }], isError: result.isError };
|
|
45
|
+
});
|
|
46
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
47
|
+
resources: [...MCP_RESOURCES]
|
|
48
|
+
}));
|
|
49
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
|
|
50
|
+
const { uri } = req.params;
|
|
51
|
+
const resource = readMcpResource(uri);
|
|
52
|
+
if (resource === void 0) throw new Error(`Unknown resource: ${uri}`);
|
|
53
|
+
return { contents: [{ uri, mimeType: resource.mimeType, text: resource.text }] };
|
|
54
|
+
});
|
|
55
|
+
return server;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ../../hosts/host-mcp/src/http.ts
|
|
59
|
+
var DEFAULT_VERSION = true ? "0.1.12" : "0.0.0-workspace";
|
|
60
|
+
async function handleMcpRequest(deps, request, opts) {
|
|
61
|
+
const server = createMcpServer(deps, {
|
|
62
|
+
name: opts?.name ?? "nanoesis",
|
|
63
|
+
version: opts?.version ?? DEFAULT_VERSION
|
|
64
|
+
});
|
|
65
|
+
const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true });
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
try {
|
|
68
|
+
return await transport.handleRequest(request);
|
|
69
|
+
} finally {
|
|
70
|
+
await transport.close();
|
|
71
|
+
await server.close();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
handleMcpRequest
|
|
76
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a3 as Ie,ao as F,a1 as Te,V as g,J as k,G as e,f as n,W as Ye,l as a,B as Q,ap as h,t as j,ak as o,E as _,ad as v,m as ze,y as U,s as He,g as Qe,au as Ue,ai as c,aq as W,ae as X,af as _e,K as Xe,ac as Ze,Y as ea}from"./index-
|
|
1
|
+
import{a3 as Ie,ao as F,a1 as Te,V as g,J as k,G as e,f as n,W as Ye,l as a,B as Q,ap as h,t as j,ak as o,E as _,ad as v,m as ze,y as U,s as He,g as Qe,au as Ue,ai as c,aq as W,ae as X,af as _e,K as Xe,ac as Ze,Y as ea}from"./index-Do1drqEQ.js";var aa=_('<p class="placeholder svelte-1lpfi31">Loading preview…</p>'),ta=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),la=_("<option> </option>"),sa=_('<select class="svelte-1lpfi31"></select>'),ra=_('<li class="orphan svelte-1lpfi31"><div class="orphan-head svelte-1lpfi31"><code class="orphan-name svelte-1lpfi31"> </code> <span class="orphan-value svelte-1lpfi31"> </span></div> <div class="orphan-actions svelte-1lpfi31" role="radiogroup"><label class="svelte-1lpfi31"><input type="radio" value="drop"/> Drop</label> <label class="svelte-1lpfi31"><input type="radio" value="keep"/> Keep (unrendered)</label> <label class="svelte-1lpfi31"><input type="radio" value="rename"/> Rename to</label> <!></div></li>'),ia=_(`<section class="resolutions svelte-1lpfi31" aria-label="Orphan field resolutions"><h3 class="svelte-1lpfi31">Orphan fields</h3> <p class="hint svelte-1lpfi31">These fields exist in this item's JSON but the current template doesn't render them.
|
|
2
2
|
Pick what to do with each.</p> <ul class="orphans svelte-1lpfi31"></ul></section>`),na=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),oa=_('<div class="diff svelte-1lpfi31"><section class="pane svelte-1lpfi31" aria-label="Previous version (left)"><header class="pane-head svelte-1lpfi31"><!></header> <pre class="source svelte-1lpfi31"> </pre></section> <section class="pane svelte-1lpfi31" aria-label="Current template (right)"><header class="pane-head svelte-1lpfi31"> </header> <pre class="source svelte-1lpfi31"> </pre></section></div> <!> <!> <div class="commit-bar svelte-1lpfi31"><button type="button" class="primary svelte-1lpfi31"> </button></div>',1),va=_('<header class="detail-head svelte-1lpfi31"><button type="button" class="back svelte-1lpfi31">← Back</button> <h2 class="svelte-1lpfi31"> </h2></header> <!>',1),pa=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),ca=_('<p class="placeholder svelte-1lpfi31">Loading…</p>'),fa=_(`<div class="empty svelte-1lpfi31"><h3 class="svelte-1lpfi31">All caught up</h3> <p>Every content item's fields match its bound template. Migrations show up here when a
|
|
3
3
|
destructive template edit (or a manual hand-edit) leaves an item with orphan fields.</p></div>`),da=_('<li class="item"><button class="item-row svelte-1lpfi31" type="button"><span class="item-path svelte-1lpfi31"><code> </code></span> <span class="item-summary svelte-1lpfi31"><!> <!> <!></span> <span class="open-icon svelte-1lpfi31">→</span></button></li>'),ua=_('<section class="group svelte-1lpfi31"><h3 class="group-title svelte-1lpfi31"><code class="svelte-1lpfi31"> </code> <span class="count svelte-1lpfi31"> </span></h3> <ul class="items svelte-1lpfi31"></ul></section>'),ma=_('<header class="list-head svelte-1lpfi31"><h2>Migrations</h2> <button type="button" class="svelte-1lpfi31"> </button></header> <!>',1),_a=_('<div class="migrations svelte-1lpfi31"><!> <!></div>');function ga(Ee,Le){Ie(Le,!0);let M=F(null),d=F(null),Z=F(!1),R=F(null),r=F(Te({})),he=F(Te({})),A=F(!1),K=F(null);g.ensureLoaded();async function Re(s){v(M,s,!0),v(r,{},!0),v(he,{},!0),v(d,null),v(R,null),v(Z,!0);try{v(d,await ea(s),!0);const f={};for(const l of e(d).orphans){const u=Se(l.name,e(d).currentTemplateFields);f[l.name]=u?{rename:u}:"keep"}v(r,f,!0)}catch(f){v(R,f instanceof Error?f.message:String(f),!0)}finally{v(Z,!1)}}function ge(){v(M,null),v(d,null),v(R,null)}function Se(s,f){const l=s.toLowerCase();for(const u of f)if(u.toLowerCase().startsWith(l)||u.toLowerCase().endsWith(l))return u;return null}async function Ce(){if(!(e(M)===null||e(d)===null)){v(A,!0),v(K,null);try{const s={drop:Object.entries(e(r)).filter(([,l])=>l==="drop").map(([l])=>l),keep:Object.entries(e(r)).filter(([,l])=>l==="keep").map(([l])=>l),rename:Object.fromEntries(Object.entries(e(r)).filter(([,l])=>typeof l=="object"&&l!==null&&"rename"in l).map(([l,u])=>[l,u.rename])),fill:{...e(he)}},f=await Qe(e(M),s);g.refresh().catch(()=>{}),ge()}catch(s){v(K,s instanceof Error?s.message:String(s),!0)}finally{v(A,!1)}}}function Pe(s){return typeof s=="string"?s:JSON.stringify(s)}const qe=Ue(()=>g.list===null?[]:Object.entries(g.list.byTemplate).map(([s,f])=>({template:s,items:[...f].sort((l,u)=>l.path.localeCompare(u.path))})));var be=_a(),ye=a(be);{var Be=s=>{var f=va(),l=Q(f),u=a(l),ee=o(u,2),ae=a(ee),te=o(l,2);{var le=i=>{var m=aa();n(i,m)},se=i=>{var m=ta(),w=a(m);h(()=>c(w,e(R))),n(i,m)},re=i=>{var m=oa(),w=Q(m),E=a(w),O=a(E),N=a(O);{var V=p=>{var y=W();h(()=>c(y,`Before — ${e(d).left.template??""}`)),n(p,y)},$=p=>{var y=W("Before — no snapshot available");n(p,y)};k(N,p=>{e(d).left?p(V):p($,-1)})}var ie=o(O,2),ne=a(ie),oe=o(E,2),D=a(oe),S=a(D),b=o(D,2),G=a(b),C=o(w,2);{var I=p=>{var y=ia(),P=o(a(y),4);U(P,21,()=>e(d).orphans,q=>q.name,(q,t)=>{var x=ra(),z=a(x),xe=a(z),Ke=a(xe),Ne=o(xe,2),Ve=a(Ne),ke=o(z,2),we=a(ke),fe=a(we),Fe=o(we,2),de=a(Fe),je=o(Fe,2),ue=a(je),$e=o(je,2);{var De=B=>{var T=sa();U(T,20,()=>e(d).currentTemplateFields,J=>J,(J,me)=>{var H=la(),Ge=a(H),Oe={};h(()=>{c(Ge,me),Oe!==(Oe=me)&&(H.value=(H.__value=me)??"")}),n(J,H)});var Me;Xe(T),h(()=>{Me!==(Me=e(r)[e(t).name].rename)&&(T.value=(T.__value=e(r)[e(t).name].rename)??"",Ze(T,e(r)[e(t).name].rename))}),j("change",T,J=>v(r,{...e(r),[e(t).name]:{rename:J.currentTarget.value}},!0)),n(B,T)};k($e,B=>{typeof e(r)[e(t).name]=="object"&&e(r)[e(t).name]!==null&&"rename"in e(r)[e(t).name]&&B(De)})}h(B=>{c(Ke,e(t).name),c(Ve,B),X(ke,"aria-label",`Resolution for ${e(t).name}`),X(fe,"name",`d-${e(t).name}`),_e(fe,e(r)[e(t).name]==="drop"),X(de,"name",`d-${e(t).name}`),_e(de,e(r)[e(t).name]==="keep"),X(ue,"name",`d-${e(t).name}`),_e(ue,typeof e(r)[e(t).name]=="object"&&e(r)[e(t).name]!==null&&"rename"in e(r)[e(t).name])},[()=>Pe(e(t).value)]),j("change",fe,()=>v(r,{...e(r),[e(t).name]:"drop"},!0)),j("change",de,()=>v(r,{...e(r),[e(t).name]:"keep"},!0)),j("change",ue,()=>v(r,{...e(r),[e(t).name]:{rename:e(d).currentTemplateFields[0]??""}},!0)),n(q,x)}),n(p,y)};k(C,p=>{e(d).orphans.length>0&&p(I)})}var Y=o(C,2);{var ve=p=>{var y=na(),P=a(y);h(()=>c(P,e(K))),n(p,y)};k(Y,p=>{e(K)&&p(ve)})}var pe=o(Y,2),L=a(pe),ce=a(L);h(()=>{var p;c(ne,((p=e(d).left)==null?void 0:p.html)??"(no snapshot covers this item)"),c(S,`After — ${e(d).right.template??""}`),c(G,e(d).right.html),L.disabled=e(A)||e(d).orphans.length===0,c(ce,e(A)?"Migrating…":"Migrate item")}),j("click",L,Ce),n(i,m)};k(te,i=>{e(Z)?i(le):e(R)?i(se,1):e(d)&&i(re,2)})}h(()=>c(ae,e(M))),j("click",u,ge),n(s,f)},Je=s=>{var f=ma(),l=Q(f),u=o(a(l),2),ee=a(u),ae=o(l,2);{var te=i=>{var m=pa(),w=a(m);h(()=>c(w,g.error)),n(i,m)},le=i=>{var m=ca();n(i,m)},se=i=>{var m=fa();n(i,m)},re=i=>{var m=ze(),w=Q(m);U(w,17,()=>e(qe),E=>E.template,(E,O)=>{var N=ua(),V=a(N),$=a(V),ie=a($),ne=o($,2),oe=a(ne),D=o(V,2);U(D,21,()=>e(O).items,S=>S.path,(S,b)=>{var G=da(),C=a(G),I=a(C),Y=a(I),ve=a(Y),pe=o(I,2),L=a(pe);{var ce=t=>{var x=W();h(z=>c(x,`${e(b).orphanFields.length??""} orphan field${e(b).orphanFields.length===1?"":"s"}:
|
|
4
4
|
${z??""}`),[()=>e(b).orphanFields.join(", ")]),n(t,x)};k(L,t=>{e(b).orphanFields.length>0&&t(ce)})}var p=o(L,2);{var y=t=>{var x=W();h(()=>c(x,`· ${e(b).missingRequiredFields.length??""} missing required`)),n(t,x)};k(p,t=>{e(b).missingRequiredFields.length>0&&t(y)})}var P=o(p,2);{var q=t=>{var x=W();h(()=>c(x,`· best-fit: ${e(b).bestFitSnapshot??""}`)),n(t,x)};k(P,t=>{e(b).bestFitSnapshot&&t(q)})}h(()=>c(ve,e(b).path)),j("click",C,()=>Re(e(b).path)),n(S,G)}),h(()=>{c(ie,e(O).template),c(oe,`${e(O).items.length??""} item${e(O).items.length===1?"":"s"}`)}),n(E,N)}),n(i,m)};k(ae,i=>{g.error?i(te):g.loading&&g.list===null?i(le,1):g.count===0?i(se,2):i(re,-1)})}h(()=>{u.disabled=g.loading,c(ee,g.loading?"Refreshing…":"Refresh")}),j("click",u,()=>g.refresh()),n(s,f)};k(ye,s=>{e(M)!==null?s(Be):s(Je,-1)})}var We=o(ye,2);{var Ae=s=>{};k(We,s=>{!e(M)&&g.list===null&&s(Ae)})}n(Ee,be),Ye()}He(["click","change"]);export{ga as default};
|