@xtrable-ltd/nanoesis 0.1.12 → 0.1.13
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-XO3CT6GL.js → chunk-7TB5ANIS.js} +58 -4
- package/dist/{chunk-EN5SMEWJ.js → chunk-LXNOLO66.js} +6 -3
- package/dist/editor-api.js +2 -2
- package/dist/index.d.ts +50 -12
- package/dist/index.js +1 -1
- package/dist/mcp.js +3 -3
- package/editor/assets/{MigrationsPane-BYGqWBAA.js → MigrationsPane-BnVflp7I.js} +1 -1
- package/editor/assets/{TemplatesPane-B5hn_v0Z.js → TemplatesPane-DPcXg8ZA.js} +12 -8
- package/editor/assets/{cssMode-BbIf5k6I.js → cssMode-CA8TzUhD.js} +1 -1
- package/editor/assets/{freemarker2-DoW0pSYV.js → freemarker2-BVvYxc4P.js} +1 -1
- package/editor/assets/{handlebars-DLlET-qc.js → handlebars-mDJMZKVv.js} +1 -1
- package/editor/assets/{html-4khbqrhe.js → html-D6Gw0A_W.js} +1 -1
- package/editor/assets/{htmlMode-DblHkZ-k.js → htmlMode-BD8QBoPu.js} +1 -1
- package/editor/assets/index-DAuQQi22.js +138 -0
- package/editor/assets/{javascript-CgPO2Hmj.js → javascript-CT1GQ3oq.js} +1 -1
- package/editor/assets/{jsonMode-BrWh2436.js → jsonMode-CBS8chp_.js} +1 -1
- package/editor/assets/{liquid-BsQJXwPT.js → liquid-BywhH4Kg.js} +1 -1
- package/editor/assets/{mdx-AO8t67gx.js → mdx-VnQOs-88.js} +1 -1
- package/editor/assets/{python-3w4sZj5c.js → python-vRZdM7SD.js} +1 -1
- package/editor/assets/{razor-BFsvo06w.js → razor--qLVVNOO.js} +1 -1
- package/editor/assets/{tsMode-QrC4ERjp.js → tsMode-CLwp9V4R.js} +1 -1
- package/editor/assets/{typescript-BXJ3QLad.js → typescript-DUO5mANL.js} +1 -1
- package/editor/assets/{xml-CxKYn1FP.js → xml-CcxvqYR1.js} +1 -1
- package/editor/assets/{yaml-BmWLvF7Q.js → yaml-BpCmDgZz.js} +1 -1
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/editor/assets/index-Do1drqEQ.js +0 -138
|
@@ -43,6 +43,15 @@ var ContentParseError = class extends Error {
|
|
|
43
43
|
this.name = "ContentParseError";
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
|
+
var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
47
|
+
"template",
|
|
48
|
+
"title",
|
|
49
|
+
"isPublished",
|
|
50
|
+
"fields",
|
|
51
|
+
"created",
|
|
52
|
+
"published",
|
|
53
|
+
"updated"
|
|
54
|
+
]);
|
|
46
55
|
function isPlainObject(value) {
|
|
47
56
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48
57
|
}
|
|
@@ -72,6 +81,9 @@ function parseOptionalString(raw, key) {
|
|
|
72
81
|
return value;
|
|
73
82
|
}
|
|
74
83
|
function parseContentItem(raw) {
|
|
84
|
+
return parseContentItemWithDiagnostics(raw).item;
|
|
85
|
+
}
|
|
86
|
+
function parseContentItemWithDiagnostics(raw) {
|
|
75
87
|
if (!isPlainObject(raw)) {
|
|
76
88
|
throw new ContentParseError("A content item must be a JSON object.");
|
|
77
89
|
}
|
|
@@ -100,7 +112,8 @@ function parseContentItem(raw) {
|
|
|
100
112
|
const created = parseOptionalString(raw, "created");
|
|
101
113
|
const published = parseOptionalString(raw, "published");
|
|
102
114
|
const updated = parseOptionalString(raw, "updated");
|
|
103
|
-
|
|
115
|
+
const unknownTopLevelKeys = Object.keys(raw).filter((key) => !KNOWN_TOP_LEVEL_KEYS.has(key)).sort();
|
|
116
|
+
const item = {
|
|
104
117
|
title: raw.title,
|
|
105
118
|
isPublished,
|
|
106
119
|
fields,
|
|
@@ -109,6 +122,7 @@ function parseContentItem(raw) {
|
|
|
109
122
|
...published !== void 0 && { published },
|
|
110
123
|
...updated !== void 0 && { updated }
|
|
111
124
|
};
|
|
125
|
+
return { item, diagnostics: { unknownTopLevelKeys } };
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
// ../engine/src/content/sort.ts
|
|
@@ -776,10 +790,15 @@ var IndexedStore = class {
|
|
|
776
790
|
}
|
|
777
791
|
}
|
|
778
792
|
this.index = nextIndex;
|
|
793
|
+
let parseDiagnostics;
|
|
794
|
+
if (isContentItemPath(target)) {
|
|
795
|
+
parseDiagnostics = contentParseDiagnosticsFor(bytes);
|
|
796
|
+
}
|
|
779
797
|
return {
|
|
780
798
|
...stamped !== void 0 && { stamped },
|
|
781
799
|
...stampIncomplete === true && { stampIncomplete: true },
|
|
782
|
-
...schemaDelta !== void 0 && { schemaDelta }
|
|
800
|
+
...schemaDelta !== void 0 && { schemaDelta },
|
|
801
|
+
...parseDiagnostics !== void 0 && { parseDiagnostics }
|
|
783
802
|
};
|
|
784
803
|
});
|
|
785
804
|
}
|
|
@@ -897,6 +916,20 @@ function stampTargetOf(target) {
|
|
|
897
916
|
if (stem === "" || stem.includes("@v")) return void 0;
|
|
898
917
|
return { dir, name: stem };
|
|
899
918
|
}
|
|
919
|
+
function isContentItemPath(target) {
|
|
920
|
+
if (!target.startsWith("content/") || !target.endsWith(".json")) return false;
|
|
921
|
+
const tail = target.slice(target.lastIndexOf("/") + 1);
|
|
922
|
+
return tail !== "_sort.json" && tail !== "_redirects.json" && tail !== "_site.json";
|
|
923
|
+
}
|
|
924
|
+
function contentParseDiagnosticsFor(bytes) {
|
|
925
|
+
try {
|
|
926
|
+
const text = new TextDecoder().decode(bytes);
|
|
927
|
+
const { diagnostics } = parseContentItemWithDiagnostics(JSON.parse(text));
|
|
928
|
+
return diagnostics.unknownTopLevelKeys.length > 0 ? diagnostics : void 0;
|
|
929
|
+
} catch {
|
|
930
|
+
return void 0;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
900
933
|
function guarded(key) {
|
|
901
934
|
if (key === "" || key.startsWith(RESERVED_PREFIX)) {
|
|
902
935
|
throw new Error(`Refusing to mutate a reserved key: ${key === "" ? "(root)" : key}`);
|
|
@@ -1081,8 +1114,14 @@ async function loadDir(source, dirPath, slug, treePath) {
|
|
|
1081
1114
|
async function loadItem(source, filePath, slug, parentPath2) {
|
|
1082
1115
|
const raw = await source.readText(filePath);
|
|
1083
1116
|
try {
|
|
1084
|
-
const item =
|
|
1085
|
-
return {
|
|
1117
|
+
const { item, diagnostics } = parseContentItemWithDiagnostics(JSON.parse(raw));
|
|
1118
|
+
return {
|
|
1119
|
+
kind: "item",
|
|
1120
|
+
slug,
|
|
1121
|
+
path: join(parentPath2, slug),
|
|
1122
|
+
item,
|
|
1123
|
+
...diagnostics.unknownTopLevelKeys.length > 0 && { parseDiagnostics: diagnostics }
|
|
1124
|
+
};
|
|
1086
1125
|
} catch (error) {
|
|
1087
1126
|
throw new Error(`Failed to load ${filePath}: ${error.message}`);
|
|
1088
1127
|
}
|
|
@@ -2598,6 +2637,12 @@ function guardrailsSection() {
|
|
|
2598
2637
|
{
|
|
2599
2638
|
name: "richtext values are HTML, shorttext/text are plain text",
|
|
2600
2639
|
summary: "For a `richtext` field, write the value as HTML (`<p>...</p>` etc). For `shorttext` or `text`, write plain text \u2014 any HTML you include is escaped at render time. If the gate emits a `content.type-drift` warning, a field's type changed destructively (commonly richtext \u2192 shorttext) and the old HTML content now renders as escaped text."
|
|
2640
|
+
},
|
|
2641
|
+
{
|
|
2642
|
+
name: "Content fields nest under `fields`, not at the top level",
|
|
2643
|
+
summary: "A content/*.json item has system keys at the top level (`template`, `title`, `isPublished`, `created`, `published`, `updated`) and ALL template-specific values under `fields`. Writing `{ template, title, body, tagline }` at the top level silently drops `body`/`tagline` because the parser is tolerant of unknown keys; the page publishes with empty placeholders. After write_file, check the response for `parseDiagnostics.unknownTopLevelKeys` and the gate for `content.unknown-top-level-key` \u2014 both list what was dropped.",
|
|
2644
|
+
detail: 'System keys are case-sensitive: `IsPublished` is not the same as `isPublished` (the typo silently defaults to false), and `Fields` is not `fields`. The same drop-and-flag applies. The published HTML for a tolerated-drift item will render with empty `<div class="prose"></div>` etc., which is the smoking-gun symptom.',
|
|
2645
|
+
example: '<!-- WRONG (body and tagline silently dropped) -->\n{ "template": "about", "title": "Hi", "body": "...", "tagline": "..." }\n\n<!-- RIGHT -->\n{ "template": "about", "title": "Hi", "fields": { "title": "Hi", "body": "...", "tagline": "..." } }'
|
|
2601
2646
|
}
|
|
2602
2647
|
]
|
|
2603
2648
|
};
|
|
@@ -2780,6 +2825,15 @@ async function validateSite(source) {
|
|
|
2780
2825
|
const owners = urlOwners.get(urlForItem(node.path)) ?? [];
|
|
2781
2826
|
owners.push(node.path);
|
|
2782
2827
|
urlOwners.set(urlForItem(node.path), owners);
|
|
2828
|
+
const dropped = node.parseDiagnostics?.unknownTopLevelKeys ?? [];
|
|
2829
|
+
if (dropped.length > 0) {
|
|
2830
|
+
add(
|
|
2831
|
+
"warning",
|
|
2832
|
+
"content.unknown-top-level-key",
|
|
2833
|
+
`"${node.path}" has top-level key${dropped.length === 1 ? "" : "s"} the parser does not recognise: ${dropped.map((k) => `"${k}"`).join(", ")}. They were dropped \u2014 content values belong under "fields" (and system keys are case-sensitive: "isPublished", not "IsPublished").`,
|
|
2834
|
+
node.path
|
|
2835
|
+
);
|
|
2836
|
+
}
|
|
2783
2837
|
if (templateName === void 0) {
|
|
2784
2838
|
add(
|
|
2785
2839
|
"error",
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
renderReferenceMarkdown,
|
|
16
16
|
validateSite,
|
|
17
17
|
workingStoreRoundTripDiagnostic
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7TB5ANIS.js";
|
|
19
19
|
|
|
20
20
|
// ../editor-api/src/scaffold.ts
|
|
21
21
|
var HOME_HTML = `<!doctype html>
|
|
@@ -500,7 +500,10 @@ async function dispatchApi(deps, req) {
|
|
|
500
500
|
ok: true,
|
|
501
501
|
...result.stamped !== void 0 && { stamped: result.stamped },
|
|
502
502
|
...result.stampIncomplete === true && { stampIncomplete: true },
|
|
503
|
-
...result.schemaDelta !== void 0 && { schemaDelta: result.schemaDelta }
|
|
503
|
+
...result.schemaDelta !== void 0 && { schemaDelta: result.schemaDelta },
|
|
504
|
+
...result.parseDiagnostics !== void 0 && {
|
|
505
|
+
parseDiagnostics: result.parseDiagnostics
|
|
506
|
+
}
|
|
504
507
|
});
|
|
505
508
|
} catch (error) {
|
|
506
509
|
return json(500, { ok: false, error: String(error) });
|
|
@@ -694,7 +697,7 @@ var TOOL_SPECS = [
|
|
|
694
697
|
},
|
|
695
698
|
{
|
|
696
699
|
name: "write_file",
|
|
697
|
-
description: "Create or overwrite a text file. content/ requires the author role; templates/, components/, and public/ require the developer role. Read the nanoesis://reference resource first for the authoring syntax. For template/component paths the response includes `schemaDelta` (added/removed/typeChanged fields) \u2014 if `typeChanged` contains `destructive: true` or `removed` is non-empty, an auto-stamp has been written and authored content may need migration, so surface to the user before further edits. See the reference's 'Authoring guardrails for LLMs' section for the common pitfalls (notably: `data-*` annotations bind to the element, not the token inside it \u2014 moving a token out of its annotated container silently strips them).",
|
|
700
|
+
description: "Create or overwrite a text file. content/ requires the author role; templates/, components/, and public/ require the developer role. Read the nanoesis://reference resource first for the authoring syntax. For template/component paths the response includes `schemaDelta` (added/removed/typeChanged fields) \u2014 if `typeChanged` contains `destructive: true` or `removed` is non-empty, an auto-stamp has been written and authored content may need migration, so surface to the user before further edits. For content/*.json writes the response may include `parseDiagnostics.unknownTopLevelKeys` \u2014 top-level keys the parser dropped because they are not system keys; content values belong under `fields` (system keys are case-sensitive: `isPublished`, not `IsPublished`). See the reference's 'Authoring guardrails for LLMs' section for the common pitfalls (notably: `data-*` annotations bind to the element, not the token inside it \u2014 moving a token out of its annotated container silently strips them).",
|
|
698
701
|
inputSchema: {
|
|
699
702
|
type: "object",
|
|
700
703
|
properties: {
|
package/dist/editor-api.js
CHANGED
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
recreateHomeTemplateRepair,
|
|
19
19
|
templateSnapshotIntegrityDiagnostic,
|
|
20
20
|
templateSuffixConflictDiagnostic
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-LXNOLO66.js";
|
|
22
|
+
import "./chunk-7TB5ANIS.js";
|
|
23
23
|
export {
|
|
24
24
|
FileBrandingStore,
|
|
25
25
|
InMemoryBrandingStore,
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,38 @@ declare function humanize(name: string): string;
|
|
|
18
18
|
/** Best-effort content type from a path's extension; defaults to octet-stream. */
|
|
19
19
|
declare function contentTypeFor(path: string): string;
|
|
20
20
|
|
|
21
|
+
/** Thrown when raw content JSON cannot be coerced into a {@link ContentItem}. */
|
|
22
|
+
declare class ContentParseError extends Error {
|
|
23
|
+
constructor(message: string);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse-time diagnostics that survive into the validation gate. Distinct from
|
|
27
|
+
* {@link ContentParseError} (which signals a *malformed* file) — diagnostics describe
|
|
28
|
+
* a successfully parsed item that nonetheless carried something the parser dropped.
|
|
29
|
+
*/
|
|
30
|
+
interface ContentParseDiagnostics {
|
|
31
|
+
/**
|
|
32
|
+
* Top-level keys present in the JSON but not recognised by the parser. Sorted for
|
|
33
|
+
* deterministic message ordering. Empty when the file is clean. Typical cause: an
|
|
34
|
+
* author (especially an LLM) wrote a content field (`body`, `tagline`, ...) at the
|
|
35
|
+
* top level instead of nesting it under `fields`, or typo'd a system key
|
|
36
|
+
* (`IsPublished` instead of `isPublished`).
|
|
37
|
+
*/
|
|
38
|
+
readonly unknownTopLevelKeys: readonly string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate untrusted content JSON into a typed {@link ContentItem}, the single
|
|
42
|
+
* boundary where content data is checked (CLAUDE.md §4). Tolerant of drift
|
|
43
|
+
* (unknown keys ignored, missing isPublished/fields defaulted; DESIGN §5.4) but
|
|
44
|
+
* strict on the system keys that carry meaning.
|
|
45
|
+
*
|
|
46
|
+
* The thin wrapper around {@link parseContentItemWithDiagnostics} for the call
|
|
47
|
+
* sites that don't need to know what the parser dropped (the editor, tests, …).
|
|
48
|
+
* The validation gate uses the diagnostics-returning variant so it can warn about
|
|
49
|
+
* silent drops (e.g. `body` written at the top level instead of under `fields`).
|
|
50
|
+
*/
|
|
51
|
+
declare function parseContentItem(raw: unknown): ContentItem;
|
|
52
|
+
|
|
21
53
|
/**
|
|
22
54
|
* The content model (DESIGN §5). Content JSON is *pure data*: a value's type
|
|
23
55
|
* comes from the template, never from the file, so these types model only the
|
|
@@ -75,6 +107,14 @@ interface ItemNode {
|
|
|
75
107
|
/** Content path from the root, e.g. "blog/going-static". */
|
|
76
108
|
readonly path: string;
|
|
77
109
|
readonly item: ContentItem;
|
|
110
|
+
/**
|
|
111
|
+
* What the parser dropped while reading this item (DESIGN §5.4 tolerance). Optional
|
|
112
|
+
* because not every ItemNode goes through the diagnostics-returning parser (compile
|
|
113
|
+
* tests construct nodes directly). The validation gate uses this to surface
|
|
114
|
+
* `content.unknown-top-level-key` warnings rather than letting `body`-outside-`fields`
|
|
115
|
+
* silently ship an empty page.
|
|
116
|
+
*/
|
|
117
|
+
readonly parseDiagnostics?: ContentParseDiagnostics;
|
|
78
118
|
}
|
|
79
119
|
/** A directory in the tree; the file/folder layout *is* the site structure. */
|
|
80
120
|
interface DirNode {
|
|
@@ -92,18 +132,6 @@ interface DirNode {
|
|
|
92
132
|
}
|
|
93
133
|
type TreeNode = DirNode | ItemNode;
|
|
94
134
|
|
|
95
|
-
/** Thrown when raw content JSON cannot be coerced into a {@link ContentItem}. */
|
|
96
|
-
declare class ContentParseError extends Error {
|
|
97
|
-
constructor(message: string);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Validate untrusted content JSON into a typed {@link ContentItem}, the single
|
|
101
|
-
* boundary where content data is checked (CLAUDE.md §4). Tolerant of drift
|
|
102
|
-
* (unknown keys ignored, missing isPublished/fields defaulted; DESIGN §5.4) but
|
|
103
|
-
* strict on the system keys that carry meaning.
|
|
104
|
-
*/
|
|
105
|
-
declare function parseContentItem(raw: unknown): ContentItem;
|
|
106
|
-
|
|
107
135
|
/**
|
|
108
136
|
* Parse a directory's sort file (DESIGN §5.2). Deliberately tolerant: a stale or
|
|
109
137
|
* malformed sort file never blocks a publish, it just falls back to defaults.
|
|
@@ -653,6 +681,16 @@ interface WriteResult {
|
|
|
653
681
|
* stamp banner.
|
|
654
682
|
*/
|
|
655
683
|
readonly schemaDelta?: SchemaDelta;
|
|
684
|
+
/**
|
|
685
|
+
* Parse diagnostics for content writes (smoke test 2026-05-29 silent-drop fix).
|
|
686
|
+
* Present only for `content/*.json` writes whose JSON parsed successfully but
|
|
687
|
+
* carried top-level keys the parser dropped (e.g. `body` written outside
|
|
688
|
+
* `fields`). Undefined when the write is not a content item, parsing threw, or
|
|
689
|
+
* everything was recognised. MCP `write_file` surfaces this immediately so an
|
|
690
|
+
* LLM author sees the silent-drop the moment it happens rather than discovering
|
|
691
|
+
* empty rendered pages later.
|
|
692
|
+
*/
|
|
693
|
+
readonly parseDiagnostics?: ContentParseDiagnostics;
|
|
656
694
|
}
|
|
657
695
|
/**
|
|
658
696
|
* The editor's working store (DESIGN §11c): a read {@link ContentSource} for
|
package/dist/index.js
CHANGED
package/dist/mcp.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
MCP_TOOLS,
|
|
4
4
|
callMcpTool,
|
|
5
5
|
readMcpResource
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-LXNOLO66.js";
|
|
7
|
+
import "./chunk-7TB5ANIS.js";
|
|
8
8
|
|
|
9
9
|
// ../../hosts/host-mcp/src/http.ts
|
|
10
10
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
@@ -56,7 +56,7 @@ function createMcpServer(deps, identity) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// ../../hosts/host-mcp/src/http.ts
|
|
59
|
-
var DEFAULT_VERSION = true ? "0.1.
|
|
59
|
+
var DEFAULT_VERSION = true ? "0.1.13" : "0.0.0-workspace";
|
|
60
60
|
async function handleMcpRequest(deps, request, opts) {
|
|
61
61
|
const server = createMcpServer(deps, {
|
|
62
62
|
name: opts?.name ?? "nanoesis",
|
|
@@ -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-DAuQQi22.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};
|