@xtrable-ltd/nanoesis 0.1.2 → 0.1.5
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-22WHPW5E.js → chunk-S23S4ZAK.js} +25 -2
- package/dist/editor-api.d.ts +25 -9
- package/dist/editor-api.js +32 -45
- package/dist/index.d.ts +21 -1
- package/dist/index.js +1 -1
- package/editor/assets/{TemplatesPane-zK8lIC02.js → TemplatesPane-CEKbBX1Y.js} +172 -172
- package/editor/assets/{cssMode-Dx60SobP.js → cssMode-q1Nw_pOI.js} +1 -1
- package/editor/assets/{freemarker2-DGQjpiaU.js → freemarker2-D4uWo9kP.js} +1 -1
- package/editor/assets/{handlebars-BltQV8dV.js → handlebars-DIXKS_PM.js} +1 -1
- package/editor/assets/{html-Dcoxpshq.js → html-WMfbPtFq.js} +1 -1
- package/editor/assets/{htmlMode-CVqSJo7C.js → htmlMode-D1MWdaop.js} +1 -1
- package/editor/assets/{index-Dj_8wB_d.css → index-BRPY7tEn.css} +1 -1
- package/editor/assets/{index-BSlglIW6.js → index-erqFXslE.js} +69 -71
- package/editor/assets/{javascript-Bl74P5-A.js → javascript-C0daj-se.js} +1 -1
- package/editor/assets/{jsonMode-CTxdbzE_.js → jsonMode-F4j8hmn2.js} +1 -1
- package/editor/assets/{liquid-TXEIIcAb.js → liquid-BmXUpyt6.js} +1 -1
- package/editor/assets/{mdx-C7X2Fz3X.js → mdx-wzY123NO.js} +1 -1
- package/editor/assets/{python-BIiW5QXV.js → python-WOKQ0Svl.js} +1 -1
- package/editor/assets/{razor-CUdWEQ3M.js → razor-B9Yg1Ydt.js} +1 -1
- package/editor/assets/{tsMode-D_2_BwYS.js → tsMode-966q_lbW.js} +1 -1
- package/editor/assets/{typescript-BdSyn6PC.js → typescript-dxbYO44F.js} +1 -1
- package/editor/assets/{xml-JVU5PVkk.js → xml-BHa7-pyl.js} +1 -1
- package/editor/assets/{yaml-D2YDV-us.js → yaml-CcgAVYu7.js} +1 -1
- package/editor/index.html +2 -2
- package/package.json +1 -1
|
@@ -2430,8 +2430,9 @@ var noopPurgeService = {
|
|
|
2430
2430
|
var DEFAULT_WRITE_CONCURRENCY = 8;
|
|
2431
2431
|
async function publishSite(source, sink, options = {}) {
|
|
2432
2432
|
const validation = await validateSite(source);
|
|
2433
|
+
const summary = summarizeTree(await loadContentTree(source));
|
|
2433
2434
|
if (!validation.ok) {
|
|
2434
|
-
return { ok: false, validation, written: [] };
|
|
2435
|
+
return { ok: false, validation, written: [], summary };
|
|
2435
2436
|
}
|
|
2436
2437
|
const {
|
|
2437
2438
|
purge = noopPurgeService,
|
|
@@ -2454,7 +2455,29 @@ async function publishSite(source, sink, options = {}) {
|
|
|
2454
2455
|
([path, contents]) => sink.write(path, contents)
|
|
2455
2456
|
);
|
|
2456
2457
|
await purge.purgeAll();
|
|
2457
|
-
return { ok: true, validation, written: [...byPath.keys()].sort() };
|
|
2458
|
+
return { ok: true, validation, written: [...byPath.keys()].sort(), summary };
|
|
2459
|
+
}
|
|
2460
|
+
function summarizeTree(root) {
|
|
2461
|
+
let published = 0;
|
|
2462
|
+
let drafts = 0;
|
|
2463
|
+
const walk = (node) => {
|
|
2464
|
+
for (const child of node.children) {
|
|
2465
|
+
if (child.kind === "dir") {
|
|
2466
|
+
walk(child);
|
|
2467
|
+
} else if (child.item.isPublished) {
|
|
2468
|
+
published += 1;
|
|
2469
|
+
} else {
|
|
2470
|
+
drafts += 1;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
walk(root);
|
|
2475
|
+
if (published > 0) return { published, drafts };
|
|
2476
|
+
return {
|
|
2477
|
+
published,
|
|
2478
|
+
drafts,
|
|
2479
|
+
firstPublishWarning: drafts > 0 ? `Your site has no published pages \u2014 ${drafts} draft${drafts === 1 ? "" : "s"} were skipped. Toggle Publish on at least one page to go live.` : "Your site has no published pages. Create a page and toggle Publish on to go live."
|
|
2480
|
+
};
|
|
2458
2481
|
}
|
|
2459
2482
|
async function collectPublic(source, publicDir) {
|
|
2460
2483
|
if (!await source.exists(publicDir)) return [];
|
package/dist/editor-api.d.ts
CHANGED
|
@@ -140,8 +140,12 @@ interface ApiDeps {
|
|
|
140
140
|
*/
|
|
141
141
|
readonly authors?: () => Promise<readonly AuthorOption[]>;
|
|
142
142
|
}
|
|
143
|
-
/**
|
|
144
|
-
*
|
|
143
|
+
/**
|
|
144
|
+
* Dispatch one API request. The editor is private, so every route requires an editing
|
|
145
|
+
* role (author/developer/admin); writes are further partitioned by path (DESIGN §11).
|
|
146
|
+
* Every response then passes through {@link withDefaultHeaders} so that no `/api/*`
|
|
147
|
+
* response is silently cached (DESIGN §13).
|
|
148
|
+
*/
|
|
145
149
|
declare function handleApi(deps: ApiDeps, req: ApiRequest): Promise<ApiResponse>;
|
|
146
150
|
|
|
147
151
|
/** The byline picker's options, display name + stable handle, sorted by display name. */
|
|
@@ -212,16 +216,28 @@ declare function readMcpResource(uri: string): {
|
|
|
212
216
|
* §11d) and bundled here as **pure data**, so the engine's purity is untouched and the
|
|
213
217
|
* scaffold works identically for every host and the MCP server with no per-host wiring.
|
|
214
218
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
219
|
+
* Auto-fires on first sign-in to an empty store (revised 2026-05-28). The earlier behaviour
|
|
220
|
+
* — a confirm prompt that the user could dismiss — left a user who said no with no path
|
|
221
|
+
* forward (the empty Content workspace has no signposted route to the Dev workspace, and
|
|
222
|
+
* every alternative to scaffolding needs templates to already exist). Removing the choice
|
|
223
|
+
* removes a concept; the scaffold is idempotent and gate-clean, so doing it always is safe.
|
|
224
|
+
*
|
|
225
|
+
* Deliberately minimal (revised 2026-05-28, owner's call):
|
|
226
|
+
* - `templates/home.html` is a **full HTML document** (DESIGN §6.10: with no
|
|
227
|
+
* `templates/document.html`, a page template is the whole document) — no shared shell.
|
|
228
|
+
* The user can extract one later when they add a second page; for the bootstrap state,
|
|
229
|
+
* three files is simpler than four.
|
|
230
|
+
* - `public/styles.css` for baseline readability — a one-page site without any CSS reads
|
|
231
|
+
* poorly, and the styles.css path is the editor's canonical "your site's CSS" location.
|
|
232
|
+
* - `content/index.json` with `isPublished: true` (revised 2026-05-28). The earlier
|
|
233
|
+
* "draft, so going live is deliberate" framing turned out to be a footgun: a new user
|
|
234
|
+
* would hit Publish and get the "nothing went live" warning without obvious cause. A
|
|
235
|
+
* published placeholder is honest about what a publish will do; the user's first edit
|
|
236
|
+
* is to replace the placeholder copy, not to also remember to toggle a flag.
|
|
220
237
|
*/
|
|
221
238
|
/**
|
|
222
239
|
* The starter files, keyed by working-store path. Written through the store's `write`
|
|
223
|
-
* (so the index records each)
|
|
224
|
-
* that depends on them, though the store has no cross-file ordering requirement.
|
|
240
|
+
* (so the index records each). The store has no cross-file ordering requirement.
|
|
225
241
|
*/
|
|
226
242
|
declare const SCAFFOLD_FILES: Readonly<Record<string, string>>;
|
|
227
243
|
|
package/dist/editor-api.js
CHANGED
|
@@ -8,45 +8,32 @@ import {
|
|
|
8
8
|
loadTemplate,
|
|
9
9
|
renderReferenceMarkdown,
|
|
10
10
|
validateSite
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-S23S4ZAK.js";
|
|
12
12
|
|
|
13
13
|
// ../editor-api/src/scaffold.ts
|
|
14
|
-
var
|
|
14
|
+
var HOME_HTML = `<!doctype html>
|
|
15
15
|
<html lang="en">
|
|
16
16
|
<head>
|
|
17
17
|
<meta charset="utf-8" />
|
|
18
18
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
19
19
|
<title>{title}</title>
|
|
20
|
-
<meta name="description" content="{meta_description}" />
|
|
21
20
|
<link rel="stylesheet" href="/styles.css" />
|
|
22
21
|
</head>
|
|
23
22
|
<body>
|
|
24
|
-
<header class="site-header">
|
|
25
|
-
<a class="brand" href="/">Your site</a>
|
|
26
|
-
</header>
|
|
27
23
|
<main>
|
|
28
|
-
<
|
|
24
|
+
<h1>{title}</h1>
|
|
25
|
+
<div class="prose" data-type="richtext">{body}</div>
|
|
29
26
|
</main>
|
|
30
|
-
<footer class="site-footer">
|
|
31
|
-
<p>Built with nanoesis \u2014 static HTML, no runtime.</p>
|
|
32
|
-
</footer>
|
|
33
27
|
</body>
|
|
34
28
|
</html>
|
|
35
29
|
`;
|
|
36
|
-
var HOME_HTML = `<section class="hero">
|
|
37
|
-
<h1>{title}</h1>
|
|
38
|
-
<p class="lead">{lead}</p>
|
|
39
|
-
</section>
|
|
40
|
-
<div class="prose" data-type="richtext">{body}</div>
|
|
41
|
-
`;
|
|
42
30
|
var HOME_JSON = `${JSON.stringify(
|
|
43
31
|
{
|
|
44
32
|
template: "home",
|
|
45
33
|
title: "Welcome",
|
|
46
|
-
isPublished:
|
|
34
|
+
isPublished: true,
|
|
47
35
|
fields: {
|
|
48
|
-
|
|
49
|
-
body: "<p>This is your new site. It compiles to plain static HTML \u2014 there is no server and no client framework, and nothing of the editor survives into production.</p>"
|
|
36
|
+
body: "<p>This is your starter home page. Edit it in the nanoesis editor and click Publish to update your site.</p>"
|
|
50
37
|
}
|
|
51
38
|
},
|
|
52
39
|
null,
|
|
@@ -67,30 +54,16 @@ body {
|
|
|
67
54
|
margin: 0;
|
|
68
55
|
}
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
main,
|
|
72
|
-
.site-footer {
|
|
57
|
+
main {
|
|
73
58
|
max-width: var(--max);
|
|
74
59
|
margin-inline: auto;
|
|
75
60
|
padding: 1.5rem 1.25rem;
|
|
76
61
|
}
|
|
77
62
|
|
|
78
|
-
|
|
79
|
-
font-weight: 700;
|
|
80
|
-
text-decoration: none;
|
|
81
|
-
color: var(--ink);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.hero h1 {
|
|
63
|
+
h1 {
|
|
85
64
|
font-size: 2.25rem;
|
|
86
65
|
letter-spacing: -0.01em;
|
|
87
|
-
margin: 0 0
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.lead {
|
|
91
|
-
font-size: 1.2rem;
|
|
92
|
-
color: var(--muted);
|
|
93
|
-
margin: 0 0 2rem;
|
|
66
|
+
margin: 0 0 1rem;
|
|
94
67
|
}
|
|
95
68
|
|
|
96
69
|
.prose {
|
|
@@ -100,15 +73,8 @@ main,
|
|
|
100
73
|
a {
|
|
101
74
|
color: var(--accent);
|
|
102
75
|
}
|
|
103
|
-
|
|
104
|
-
.site-footer {
|
|
105
|
-
color: var(--muted);
|
|
106
|
-
font-size: 0.9rem;
|
|
107
|
-
border-top: 1px solid #eee;
|
|
108
|
-
}
|
|
109
76
|
`;
|
|
110
77
|
var SCAFFOLD_FILES = {
|
|
111
|
-
"templates/document.html": DOCUMENT_HTML,
|
|
112
78
|
"templates/home.html": HOME_HTML,
|
|
113
79
|
"public/styles.css": STYLES_CSS,
|
|
114
80
|
"content/index.json": HOME_JSON
|
|
@@ -136,6 +102,14 @@ function json(status, data) {
|
|
|
136
102
|
function methodNotAllowed() {
|
|
137
103
|
return json(405, { ok: false, error: "POST only" });
|
|
138
104
|
}
|
|
105
|
+
function withDefaultHeaders(response) {
|
|
106
|
+
const headers = { ...response.headers ?? {} };
|
|
107
|
+
if (headers["cache-control"] === void 0) {
|
|
108
|
+
headers["cache-control"] = "no-store";
|
|
109
|
+
if (headers["vary"] === void 0) headers["vary"] = "Authorization";
|
|
110
|
+
}
|
|
111
|
+
return { ...response, headers };
|
|
112
|
+
}
|
|
139
113
|
var BEARER_PREFIX = /^Bearer\s+/i;
|
|
140
114
|
function bearerToken(getHeader) {
|
|
141
115
|
const raw = getHeader("authorization") ?? getHeader("Authorization");
|
|
@@ -304,6 +278,9 @@ async function handleBrandingRoute(deps, req) {
|
|
|
304
278
|
return json(405, { ok: false, error: "method not allowed" });
|
|
305
279
|
}
|
|
306
280
|
async function handleApi(deps, req) {
|
|
281
|
+
return withDefaultHeaders(await dispatchApi(deps, req));
|
|
282
|
+
}
|
|
283
|
+
async function dispatchApi(deps, req) {
|
|
307
284
|
const authResponse = await handleAuthRoute(deps, req);
|
|
308
285
|
if (authResponse !== void 0) return authResponse;
|
|
309
286
|
const brandingResponse = await handleBrandingRoute(deps, req);
|
|
@@ -384,8 +361,18 @@ async function handleApi(deps, req) {
|
|
|
384
361
|
case "/api/publish": {
|
|
385
362
|
if (req.method !== "POST") return methodNotAllowed();
|
|
386
363
|
const result = await deps.publish();
|
|
387
|
-
if (result.ok)
|
|
388
|
-
|
|
364
|
+
if (result.ok) {
|
|
365
|
+
return json(200, {
|
|
366
|
+
ok: true,
|
|
367
|
+
written: result.written.length,
|
|
368
|
+
...result.summary !== void 0 && { summary: result.summary }
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
return json(422, {
|
|
372
|
+
ok: false,
|
|
373
|
+
errors: result.validation.errors.map((e) => e.message),
|
|
374
|
+
...result.summary !== void 0 && { summary: result.summary }
|
|
375
|
+
});
|
|
389
376
|
}
|
|
390
377
|
case "/api/scaffold": {
|
|
391
378
|
if (req.method !== "POST") return methodNotAllowed();
|
package/dist/index.d.ts
CHANGED
|
@@ -994,6 +994,24 @@ interface PublishOptions extends CompileSiteOptions {
|
|
|
994
994
|
/** Max sink writes in flight at once (default {@link DEFAULT_WRITE_CONCURRENCY}). */
|
|
995
995
|
readonly writeConcurrency?: number;
|
|
996
996
|
}
|
|
997
|
+
/**
|
|
998
|
+
* What the publish actually did to *content*, as opposed to artifacts. Counts come from a
|
|
999
|
+
* walk of the content tree (the same definition the compiler uses, `item.isPublished`).
|
|
1000
|
+
* Surfaced so a host/UI can explain a publish whose written-file count looks surprising,
|
|
1001
|
+
* the silent first-publish footgun: a published site with no published pages.
|
|
1002
|
+
*/
|
|
1003
|
+
interface PublishSummary {
|
|
1004
|
+
/** Content items with `isPublished: true` — the pages the publish included. */
|
|
1005
|
+
readonly published: number;
|
|
1006
|
+
/** Content items with `isPublished` false/absent — the pages the publish skipped. */
|
|
1007
|
+
readonly drafts: number;
|
|
1008
|
+
/**
|
|
1009
|
+
* A friendly one-liner when `published === 0`, so a UI can warn an operator who just
|
|
1010
|
+
* scaffolded a draft home and hit Publish that nothing went live. Absent when at least
|
|
1011
|
+
* one page is published.
|
|
1012
|
+
*/
|
|
1013
|
+
readonly firstPublishWarning?: string;
|
|
1014
|
+
}
|
|
997
1015
|
interface PublishResult {
|
|
998
1016
|
/** True when the validation gate passed and the site was published. */
|
|
999
1017
|
readonly ok: boolean;
|
|
@@ -1001,6 +1019,8 @@ interface PublishResult {
|
|
|
1001
1019
|
readonly validation: ValidationResult;
|
|
1002
1020
|
/** Output paths written to the sink, sorted; empty when validation blocked the publish. */
|
|
1003
1021
|
readonly written: readonly string[];
|
|
1022
|
+
/** Per-content counts (the human-readable side of `written`); present when the tree loaded. */
|
|
1023
|
+
readonly summary?: PublishSummary;
|
|
1004
1024
|
}
|
|
1005
1025
|
/**
|
|
1006
1026
|
* Run the Phase-1 publish pipeline (DESIGN §11) through ports: **validate → compile →
|
|
@@ -1267,4 +1287,4 @@ declare function escapeJsonStringContent(value: string): string;
|
|
|
1267
1287
|
*/
|
|
1268
1288
|
declare function sanitizeUrl(url: string): string;
|
|
1269
1289
|
|
|
1270
|
-
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 Diagnostic, 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 IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type PageEntry, type PreBuildHook, type Principal, type PublishOptions, type PublishResult, type PurgeService, RESERVED_PREFIX, type ReconcileResult, type RedirectRule, type ReferenceContext, type ReferenceEntry, type ReferenceSection, type RefreshSuccess, type RenameResult, type ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type Scope, type Severity, type SiteConfig, type SortFile, type TemplateAnalysis, type TokenContext, type TokenRef, type TreeNode, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type WorkingStore, analyzeTemplate, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, canEdit, compilePage, compileSite, compileTemplate, contentHash, contentTypeFor, deriveFields, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isFieldType, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadRedirects, loadSiteConfig, loadTemplate, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, processImage, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, slugify, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, wholeValueToken };
|
|
1290
|
+
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 Diagnostic, 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 IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type PageEntry, 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 ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type Scope, type Severity, type SiteConfig, type SortFile, type TemplateAnalysis, type TokenContext, type TokenRef, type TreeNode, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type WorkingStore, analyzeTemplate, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, canEdit, compilePage, compileSite, compileTemplate, contentHash, contentTypeFor, deriveFields, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isFieldType, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadRedirects, loadSiteConfig, loadTemplate, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, processImage, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, slugify, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, wholeValueToken };
|