@xtrable-ltd/nanoesis 0.1.20 → 0.1.22

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.
Files changed (31) hide show
  1. package/dist/adapter-azure-blob.d.ts +12 -3
  2. package/dist/adapter-azure-blob.js +16 -1
  3. package/dist/adapter-fs.d.ts +11 -2
  4. package/dist/adapter-fs.js +14 -1
  5. package/dist/{chunk-26VCV3IE.js → chunk-SHGYQTZ7.js} +317 -203
  6. package/dist/editor-api.d.ts +102 -2
  7. package/dist/editor-api.js +7 -1
  8. package/dist/index.d.ts +17 -1
  9. package/dist/mcp.js +2 -2
  10. package/editor/assets/{MigrationsPane-BW2LrxHZ.js → MigrationsPane-BuDy6yfL.js} +1 -1
  11. package/editor/assets/{TemplatesPane-Ac_wIaRF.js → TemplatesPane-B0p3MU6k.js} +7 -7
  12. package/editor/assets/{cssMode-cUeZlGLn.js → cssMode-QvwrYsqW.js} +1 -1
  13. package/editor/assets/{freemarker2-D3MVrofV.js → freemarker2-Dv-zJ_IC.js} +1 -1
  14. package/editor/assets/{handlebars-CXQ8CbWL.js → handlebars-C1cz1CE1.js} +1 -1
  15. package/editor/assets/{html-BwjQWZKo.js → html-Bzw5MVgw.js} +1 -1
  16. package/editor/assets/{htmlMode-BiXiNHEB.js → htmlMode-BVD0ozaS.js} +1 -1
  17. package/editor/assets/index-B55NpHIl.css +7 -0
  18. package/editor/assets/{index-C_48fmnL.js → index-CLQXsAlc.js} +3 -3
  19. package/editor/assets/{javascript-CtdcxuAO.js → javascript-CmaCtnu1.js} +1 -1
  20. package/editor/assets/{jsonMode-a-sHGDu1.js → jsonMode-CDzmaDvb.js} +1 -1
  21. package/editor/assets/{liquid-DOcONXN7.js → liquid-DelfLp1i.js} +1 -1
  22. package/editor/assets/{mdx-DX8hBNLk.js → mdx-BfB8QRKT.js} +1 -1
  23. package/editor/assets/{python-Ctckq5kU.js → python-ZH9O8Nnr.js} +1 -1
  24. package/editor/assets/{razor-BWm5ktlO.js → razor-CpsZTRhn.js} +1 -1
  25. package/editor/assets/{tsMode-PwP0Hlwi.js → tsMode-DnMjBpsC.js} +1 -1
  26. package/editor/assets/{typescript-BqxeJCPE.js → typescript-Cb9pXSMO.js} +1 -1
  27. package/editor/assets/{xml-P0PtTkph.js → xml-1ERPoWKr.js} +1 -1
  28. package/editor/assets/{yaml-Dq7ZSJMS.js → yaml-YVqB6TxT.js} +1 -1
  29. package/editor/index.html +2 -2
  30. package/package.json +1 -1
  31. package/editor/assets/index-BzxvxQfA.css +0 -7
@@ -1,4 +1,5 @@
1
- import { WorkingStore, IdentityProvider, PublishResult, ReconcileResult, AuthEndpoints, UserAdminEndpoints, AuthorOption, DiagnosticRegistry, UserSummary, AuthorDirectory, Repair, DiagnosticCheck } from '@nanoesis/engine';
1
+ import { WorkingStore, IdentityProvider, PublishResult, ReconcileResult, AuthEndpoints, UserAdminEndpoints, AuthorOption, DiagnosticRegistry, Storage, ImageEncoder, PurgeService, UserSummary, PreBuildHook, AuthorDirectory, Repair, DiagnosticCheck } from '@nanoesis/engine';
2
+ export { Storage } from '@nanoesis/engine';
2
3
 
3
4
  /**
4
5
  * Editor white-labelling storage (DESIGN §11, Phase B). This is the *editor app's*
@@ -158,6 +159,105 @@ interface ApiDeps {
158
159
  */
159
160
  declare function handleApi(deps: ApiDeps, req: ApiRequest): Promise<ApiResponse>;
160
161
 
162
+ /** Everything {@link createEditor} needs. Three things are required; the rest light up features. */
163
+ interface EditorConfig {
164
+ /** Where the editor reads and writes your editable files (content, templates, assets). */
165
+ readonly editorFiles: Storage;
166
+ /** Where the built website is written on publish (your live site, a folder, a CDN origin). */
167
+ readonly website: Storage;
168
+ /** Who may edit. Use {@link devNoAuth} locally; swap for a real provider in production. */
169
+ readonly login: IdentityProvider;
170
+ /**
171
+ * Optional full key scan of `editorFiles`. When supplied, the editor can self-heal its
172
+ * content index (`POST /api/reconcile`) and warn about files that bypassed it. Pass the
173
+ * adapter's native listing (e.g. an Azure container's `list`); omit on a store that
174
+ * cannot enumerate.
175
+ */
176
+ readonly enumerate?: () => Promise<readonly string[]>;
177
+ /** Turns `<img>` into responsive `<picture>` (AVIF/WebP/JPG). Pass the sharp adapter. */
178
+ readonly images?: ImageEncoder;
179
+ /** Clears a CDN cache after a successful publish. */
180
+ readonly purge?: PurgeService;
181
+ /** Absolute site URL; enables `sitemap.xml` and absolute links. */
182
+ readonly baseUrl?: string;
183
+ /** The users a byline may name (DESIGN §6.11): powers the authors picker and bylines. */
184
+ readonly users?: () => Promise<readonly UserSummary[]>;
185
+ /** Editor white-labelling (name + logo). */
186
+ readonly branding?: BrandingStore;
187
+ /** Credential routes (login/refresh/logout); omit for trusted-header / gateway auth. */
188
+ readonly authEndpoints?: AuthEndpoints;
189
+ /** Admin user-management routes; omit when users are managed upstream. */
190
+ readonly userAdmin?: UserAdminEndpoints;
191
+ /**
192
+ * A build step (Tailwind, esbuild, …) run before each publish. Pass a {@link PreBuildHook}
193
+ * for a fixed command, or a function resolved on every publish so a host can pick up a
194
+ * site's build-command change without a restart.
195
+ */
196
+ readonly prebuild?: PreBuildHook | (() => Promise<PreBuildHook | undefined>);
197
+ /** Admin diagnostics/self-heal; defaults to {@link buildDefaultDiagnostics}. */
198
+ readonly diagnostics?: DiagnosticRegistry;
199
+ /** Clear the website before republishing (default true). Needs `website.wipe`. */
200
+ readonly wipeBeforePublish?: boolean;
201
+ }
202
+ /** A wired editor: mount {@link handleApi} at `/api/*` and call {@link publish} to go live. */
203
+ interface Editor {
204
+ /** Handle one editor API request. Mount at `/api/*` in your HTTP server. */
205
+ handleApi(req: ApiRequest): Promise<ApiResponse>;
206
+ /** Validate, then (optionally wipe and) build the site into the website store. */
207
+ publish(): Promise<PublishResult>;
208
+ /** The underlying working store, for advanced hosts that need direct access. */
209
+ readonly store: WorkingStore;
210
+ /**
211
+ * The assembled {@link ApiDeps}, an escape hatch for advanced transports (e.g. the MCP
212
+ * server) that dispatch through the dependencies directly rather than via `handleApi`.
213
+ * Most hosts ignore this.
214
+ */
215
+ readonly deps: ApiDeps;
216
+ }
217
+ /**
218
+ * Wire a complete nanoesis editor from a storage pair, a login, and a few optional
219
+ * capabilities. This is the whole integration surface (DESIGN §11c): everything that used
220
+ * to be hand-assembled per host, the content index over the store, the publish source/sink,
221
+ * index reconcile, the wipe-before-publish, and the {@link ApiDeps} bag, is built here, so
222
+ * internals (`IndexedStore`, `ArtifactSink`, reconcile plumbing) never reach the adopter.
223
+ *
224
+ * `publish()` validates **before** it wipes: an invalid site returns its errors and never
225
+ * touches the live files, so a failed publish can never blank the website (the footgun the
226
+ * old "host wipes, then publishes" wiring carried).
227
+ */
228
+ declare function createEditor(config: EditorConfig): Editor;
229
+ /**
230
+ * An {@link IdentityProvider} that treats every request as a full admin, no login. For
231
+ * **local development only**, it prints a warning on use. Swap for a real provider (e.g.
232
+ * `@nanoesis/adapter-local-jwt`) before exposing the editor to anyone.
233
+ */
234
+ declare function devNoAuth(): IdentityProvider;
235
+
236
+ /** A transport-agnostic response: a host maps this onto its own framework's response. */
237
+ interface AssetResponse {
238
+ readonly status: number;
239
+ readonly headers: Record<string, string>;
240
+ readonly body: Uint8Array | string;
241
+ }
242
+ /** Options for {@link serveEditorAsset}. */
243
+ interface ServeEditorOptions {
244
+ /**
245
+ * Served verbatim as `/config.json` (JSON, never cached). The editor SPA fetches this at
246
+ * boot to learn its API base URL, e.g. `{ apiUrl: 'https://editor.example.com' }`. Omit
247
+ * for a same-origin host where the SPA and API share a domain.
248
+ */
249
+ readonly config?: Record<string, unknown>;
250
+ }
251
+ /**
252
+ * Serve one request for the bundled editor SPA from `distDir` (the `editorDist` shipped in
253
+ * `@xtrable-ltd/nanoesis`). Returns the requested file, or falls back to `index.html` for
254
+ * any unknown path so the editor's client-side router takes over (DESIGN §11c). Mount it on
255
+ * every non-`/api/*` GET. A path that escapes `distDir` is refused (403).
256
+ *
257
+ * This is the SPA-serving glue every host used to hand-write; one helper replaces it.
258
+ */
259
+ declare function serveEditorAsset(distDir: string, pathname: string, options?: ServeEditorOptions): Promise<AssetResponse>;
260
+
161
261
  /** The byline picker's options, display name + stable handle, sorted by display name. */
162
262
  declare function authorOptions(users: readonly UserSummary[]): AuthorOption[];
163
263
  /**
@@ -323,4 +423,4 @@ declare const copySnapshotToCurrentRepair: Repair;
323
423
  */
324
424
  declare const pendingMigrationsDiagnostic: DiagnosticCheck;
325
425
 
326
- export { type ApiDeps, type ApiRequest, type ApiResponse, type BrandingLogo, type BrandingLogoMeta, type BrandingState, type BrandingStore, FileBrandingStore, InMemoryBrandingStore, MCP_RESOURCES, MCP_TOOLS, type McpCallOptions, type McpResourceDef, type McpToolDef, type McpToolResult, SCAFFOLD_FILES, authorDirectory, authorOptions, buildDefaultDiagnostics, callMcpTool, copySnapshotToCurrentRepair, handleApi, homeTemplateMissingDiagnostic, noPublishedContentDiagnostic, pendingMigrationsDiagnostic, readMcpResource, rebindItemToCurrentRepair, recreateHomeTemplateRepair, templateSnapshotIntegrityDiagnostic, templateSuffixConflictDiagnostic };
426
+ export { type ApiDeps, type ApiRequest, type ApiResponse, type AssetResponse, type BrandingLogo, type BrandingLogoMeta, type BrandingState, type BrandingStore, type Editor, type EditorConfig, FileBrandingStore, InMemoryBrandingStore, MCP_RESOURCES, MCP_TOOLS, type McpCallOptions, type McpResourceDef, type McpToolDef, type McpToolResult, SCAFFOLD_FILES, type ServeEditorOptions, authorDirectory, authorOptions, buildDefaultDiagnostics, callMcpTool, copySnapshotToCurrentRepair, createEditor, devNoAuth, handleApi, homeTemplateMissingDiagnostic, noPublishedContentDiagnostic, pendingMigrationsDiagnostic, readMcpResource, rebindItemToCurrentRepair, recreateHomeTemplateRepair, serveEditorAsset, templateSnapshotIntegrityDiagnostic, templateSuffixConflictDiagnostic };
@@ -9,6 +9,8 @@ import {
9
9
  buildDefaultDiagnostics,
10
10
  callMcpTool,
11
11
  copySnapshotToCurrentRepair,
12
+ createEditor,
13
+ devNoAuth,
12
14
  handleApi,
13
15
  homeTemplateMissingDiagnostic,
14
16
  noPublishedContentDiagnostic,
@@ -16,9 +18,10 @@ import {
16
18
  readMcpResource,
17
19
  rebindItemToCurrentRepair,
18
20
  recreateHomeTemplateRepair,
21
+ serveEditorAsset,
19
22
  templateSnapshotIntegrityDiagnostic,
20
23
  templateSuffixConflictDiagnostic
21
- } from "./chunk-26VCV3IE.js";
24
+ } from "./chunk-SHGYQTZ7.js";
22
25
  import "./chunk-WHK3SBV7.js";
23
26
  export {
24
27
  FileBrandingStore,
@@ -31,6 +34,8 @@ export {
31
34
  buildDefaultDiagnostics,
32
35
  callMcpTool,
33
36
  copySnapshotToCurrentRepair,
37
+ createEditor,
38
+ devNoAuth,
34
39
  handleApi,
35
40
  homeTemplateMissingDiagnostic,
36
41
  noPublishedContentDiagnostic,
@@ -38,6 +43,7 @@ export {
38
43
  readMcpResource,
39
44
  rebindItemToCurrentRepair,
40
45
  recreateHomeTemplateRepair,
46
+ serveEditorAsset,
41
47
  templateSnapshotIntegrityDiagnostic,
42
48
  templateSuffixConflictDiagnostic
43
49
  };
package/dist/index.d.ts CHANGED
@@ -154,6 +154,22 @@ interface BlobStore {
154
154
  /** Remove `key`. Deleting an absent key is a no-op (idempotent). */
155
155
  delete(key: string): Promise<void>;
156
156
  }
157
+ /**
158
+ * The single storage contract an adopter implements (DESIGN §11c): a {@link BlobStore}
159
+ * (get/put/delete) plus an optional {@link wipe}. The same shape backs both the editor's
160
+ * working files and the published website, so there is one interface to learn, not a
161
+ * separate read port and write sink. `createEditor` (in `@nanoesis/editor-api`) consumes
162
+ * this; the ready-made adapters (e.g. `folderStorage`) implement it, so most adopters write
163
+ * none of it.
164
+ */
165
+ interface Storage extends BlobStore {
166
+ /**
167
+ * Optional: remove everything in the store. Used to clear the previous publish before
168
+ * re-emitting the website, so deleted pages disappear. A store that cannot enumerate
169
+ * (and so cannot clear itself) omits it; the publish then only overwrites.
170
+ */
171
+ wipe?(): Promise<void>;
172
+ }
157
173
  /**
158
174
  * In-memory {@link BlobStore} backed by a plain map, the test double the engine's
159
175
  * store and index tests run against (the LSP guarantee that real adapters are
@@ -1698,4 +1714,4 @@ declare function createDiagnosticRegistry(): DiagnosticRegistry;
1698
1714
 
1699
1715
  declare const workingStoreRoundTripDiagnostic: Diagnostic;
1700
1716
 
1701
- 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 };
1717
+ 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 Storage, 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/mcp.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  MCP_TOOLS,
4
4
  callMcpTool,
5
5
  readMcpResource
6
- } from "./chunk-26VCV3IE.js";
6
+ } from "./chunk-SHGYQTZ7.js";
7
7
  import "./chunk-WHK3SBV7.js";
8
8
 
9
9
  // ../../hosts/host-mcp/src/http.ts
@@ -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.20" : "0.0.0-workspace";
59
+ var DEFAULT_VERSION = true ? "0.1.22" : "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{af as Ie,aD as F,ad as Te,a7 as g,T as w,Q as e,f as n,a8 as Qe,o as a,N as H,aE as h,w as O,az as o,O as _,ar as v,p as Ue,G as X,v as Ve,g as He,aK as Xe,ax as c,aF as A,at as Y,au as _e,U as Ye,aq as Ze,a9 as ea}from"./index-C_48fmnL.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.
1
+ import{af as Ie,aD as F,ad as Te,a7 as g,T as w,Q as e,f as n,a8 as Qe,o as a,N as H,aE as h,w as O,az as o,O as _,ar as v,p as Ue,G as X,v as Ve,g as He,aK as Xe,ax as c,aF as A,at as Y,au as _e,U as Ye,aq as Ze,a9 as ea}from"./index-CLQXsAlc.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 j=F(null),d=F(null),Z=F(!1),R=F(null),r=F(Te({})),he=F(Te({})),D=F(!1),J=F(null);g.ensureLoaded();async function Re(s){v(j,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(j,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(j)===null||e(d)===null)){v(D,!0),v(J,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 He(e(j),s);g.refresh().catch(()=>{}),ge()}catch(s){v(J,s instanceof Error?s.message:String(s),!0)}finally{v(D,!1)}}}function Pe(s){return typeof s=="string"?s:JSON.stringify(s)}const qe=Xe(()=>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(),xe=a(be);{var Be=s=>{var f=va(),l=H(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(),k=a(m);h(()=>c(k,e(R))),n(i,m)},re=i=>{var m=oa(),k=H(m),E=a(k),M=a(E),K=a(M);{var W=p=>{var x=A();h(()=>c(x,`Before — ${e(d).left.template??""}`)),n(p,x)},$=p=>{var x=A("Before — no snapshot available");n(p,x)};w(K,p=>{e(d).left?p(W):p($,-1)})}var ie=o(M,2),ne=a(ie),oe=o(E,2),z=a(oe),S=a(z),b=o(z,2),G=a(b),C=o(k,2);{var I=p=>{var x=ia(),P=o(a(x),4);X(P,21,()=>e(d).orphans,q=>q.name,(q,t)=>{var y=ra(),U=a(y),ye=a(U),Je=a(ye),Ke=o(ye,2),We=a(Ke),we=o(U,2),ke=a(we),fe=a(ke),Fe=o(ke,2),de=a(Fe),Oe=o(Fe,2),ue=a(Oe),$e=o(Oe,2);{var ze=B=>{var T=sa();X(T,20,()=>e(d).currentTemplateFields,N=>N,(N,me)=>{var V=la(),Ge=a(V),Me={};h(()=>{c(Ge,me),Me!==(Me=me)&&(V.value=(V.__value=me)??"")}),n(N,V)});var je;Ye(T),h(()=>{je!==(je=e(r)[e(t).name].rename)&&(T.value=(T.__value=e(r)[e(t).name].rename)??"",Ze(T,e(r)[e(t).name].rename))}),O("change",T,N=>v(r,{...e(r),[e(t).name]:{rename:N.currentTarget.value}},!0)),n(B,T)};w($e,B=>{typeof e(r)[e(t).name]=="object"&&e(r)[e(t).name]!==null&&"rename"in e(r)[e(t).name]&&B(ze)})}h(B=>{c(Je,e(t).name),c(We,B),Y(we,"aria-label",`Resolution for ${e(t).name}`),Y(fe,"name",`d-${e(t).name}`),_e(fe,e(r)[e(t).name]==="drop"),Y(de,"name",`d-${e(t).name}`),_e(de,e(r)[e(t).name]==="keep"),Y(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)]),O("change",fe,()=>v(r,{...e(r),[e(t).name]:"drop"},!0)),O("change",de,()=>v(r,{...e(r),[e(t).name]:"keep"},!0)),O("change",ue,()=>v(r,{...e(r),[e(t).name]:{rename:e(d).currentTemplateFields[0]??""}},!0)),n(q,y)}),n(p,x)};w(C,p=>{e(d).orphans.length>0&&p(I)})}var Q=o(C,2);{var ve=p=>{var x=na(),P=a(x);h(()=>c(P,e(J))),n(p,x)};w(Q,p=>{e(J)&&p(ve)})}var pe=o(Q,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(D)||e(d).orphans.length===0,c(ce,e(D)?"Migrating…":"Migrate item")}),O("click",L,Ce),n(i,m)};w(te,i=>{e(Z)?i(le):e(R)?i(se,1):e(d)&&i(re,2)})}h(()=>c(ae,e(j))),O("click",u,ge),n(s,f)},Ne=s=>{var f=ma(),l=H(f),u=o(a(l),2),ee=a(u),ae=o(l,2);{var te=i=>{var m=pa(),k=a(m);h(()=>c(k,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=Ue(),k=H(m);X(k,17,()=>e(qe),E=>E.template,(E,M)=>{var K=ua(),W=a(K),$=a(W),ie=a($),ne=o($,2),oe=a(ne),z=o(W,2);X(z,21,()=>e(M).items,S=>S.path,(S,b)=>{var G=da(),C=a(G),I=a(C),Q=a(I),ve=a(Q),pe=o(I,2),L=a(pe);{var ce=t=>{var y=A();h(U=>c(y,`${e(b).orphanFields.length??""} orphan field${e(b).orphanFields.length===1?"":"s"}:
4
4
  ${U??""}`),[()=>e(b).orphanFields.join(", ")]),n(t,y)};w(L,t=>{e(b).orphanFields.length>0&&t(ce)})}var p=o(L,2);{var x=t=>{var y=A();h(()=>c(y,`· ${e(b).missingRequiredFields.length??""} missing required`)),n(t,y)};w(p,t=>{e(b).missingRequiredFields.length>0&&t(x)})}var P=o(p,2);{var q=t=>{var y=A();h(()=>c(y,`· best-fit: ${e(b).bestFitSnapshot??""}`)),n(t,y)};w(P,t=>{e(b).bestFitSnapshot&&t(q)})}h(()=>c(ve,e(b).path)),O("click",C,()=>Re(e(b).path)),n(S,G)}),h(()=>{c(ie,e(M).template),c(oe,`${e(M).items.length??""} item${e(M).items.length===1?"":"s"}`)}),n(E,K)}),n(i,m)};w(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")}),O("click",u,()=>g.refresh()),n(s,f)};w(xe,s=>{e(j)!==null?s(Be):s(Ne,-1)})}var Ae=o(xe,2);{var De=s=>{};w(Ae,s=>{!e(j)&&g.list===null&&s(De)})}n(Ee,be),Qe()}Ve(["click","change"]);export{ga as default};