@pagenary/publisher 2026.6.2 → 2026.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagenary/publisher",
3
- "version": "2026.6.2",
3
+ "version": "2026.6.3",
4
4
  "type": "module",
5
5
  "description": "Multi-tenant static publishing component for Pagenary platform.",
6
6
  "license": "AGPL-3.0-or-later",
@@ -959,6 +959,23 @@ async function applyBranding(distDir, config, tenantId) {
959
959
  }
960
960
  }
961
961
 
962
+ /**
963
+ * Replace the shell's `__PAGENARY_TENANT__` base-resolution placeholder with the
964
+ * real tenant id. Runs for every tenant so the runtime `<base href>` bootstrap
965
+ * can resolve asset/module URLs against the tenant root under subpath mounts
966
+ * (e.g. /tenant/) while domain-root deploys fall back to "/".
967
+ * @param {string} distDir - Tenant output directory
968
+ * @param {string} tenantId - Tenant identifier
969
+ */
970
+ async function injectTenantBase(distDir, tenantId) {
971
+ const indexPath = path.join(distDir, 'index.html');
972
+ if (!(await pathExists(indexPath))) return;
973
+ const html = await fsp.readFile(indexPath, 'utf8');
974
+ if (!html.includes('__PAGENARY_TENANT__')) return;
975
+ await fsp.writeFile(indexPath, html.split('__PAGENARY_TENANT__').join(tenantId), 'utf8');
976
+ console.log(` ↳ wired tenant base for ${tenantId}`);
977
+ }
978
+
962
979
  function hexToRgb(hex) {
963
980
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
964
981
  if (!result) return null;
@@ -2576,14 +2593,14 @@ async function materializeScannedSections(sections, context) {
2576
2593
  title,
2577
2594
  summary,
2578
2595
  ...metadata,
2579
- module: `/sections/${outFile}`,
2596
+ module: `./sections/${outFile}`,
2580
2597
  subsections: processedSubsections
2581
2598
  };
2582
2599
  if (type) entry.type = type;
2583
2600
  if (collapsed) entry.collapsed = true;
2584
2601
  processed.push(entry);
2585
2602
  } else {
2586
- const entry = { id, title, summary, ...metadata, module: `/sections/${outFile}` };
2603
+ const entry = { id, title, summary, ...metadata, module: `./sections/${outFile}` };
2587
2604
  if (type) entry.type = type;
2588
2605
  if (collapsed) entry.collapsed = true;
2589
2606
  processed.push(entry);
@@ -2896,7 +2913,7 @@ async function materializeSectionModule(entry, context) {
2896
2913
  return null;
2897
2914
  }
2898
2915
 
2899
- return `/sections/${outFile}`;
2916
+ return `./sections/${outFile}`;
2900
2917
  }
2901
2918
 
2902
2919
  function buildManifestModuleSource(manifestEntries, defaultSection, siteConfig = {}, exportConfig = {}) {
@@ -3313,6 +3330,11 @@ async function buildTenant(tenant, targetOverride, cacheDir, buildOptions) {
3313
3330
  await applyWelcome(distDir, config, tenantId);
3314
3331
  }
3315
3332
 
3333
+ // Inject the tenant id into the shell's base-resolution bootstrap for EVERY
3334
+ // tenant (regardless of branding config) so subpath mounts resolve assets
3335
+ // against the tenant root. Domain-root deploys fall back to "/".
3336
+ await injectTenantBase(distDir, tenantId);
3337
+
3316
3338
  // Copy static assets from .public/ directory
3317
3339
  await copyPublicAssets(sourceDir, distDir, tenantId);
3318
3340
 
package/site/index.html CHANGED
@@ -5,9 +5,23 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1" />
6
6
  <title>Pagenary Docs</title>
7
7
  <meta name="description" content="Pagenary developer documentation — building, configuring, deploying, and extending the multi-tenant documentation publisher, published with Pagenary itself." />
8
- <link rel="icon" type="image/png" href="/favicon.png" />
9
- <link rel="stylesheet" href="/styles.css" />
10
- <meta name="x-build" content="2026-06-15T18:50:34.132Z" />
8
+ <script>
9
+ // Resolve all asset/module URLs against the tenant root in both deploy
10
+ // modes: domain-per-tenant at root (production, with SPA fallback) and a
11
+ // subpath mount such as /<tenant>/ (the dev preview server). The tenant id
12
+ // is injected at build time. On a domain root the path never starts with
13
+ // "/<tenant>/", so the base falls back to "/". For the un-replaced default
14
+ // build the placeholder starts with "_", which also yields "/".
15
+ (function () {
16
+ var t = "pagenary";
17
+ var p = location.pathname;
18
+ var base = t && p.indexOf("/" + t + "/") === 0 ? "/" + t + "/" : "/";
19
+ document.write('<base href="' + base + '">');
20
+ })();
21
+ </script>
22
+ <link rel="icon" type="image/png" href="./favicon.png" />
23
+ <link rel="stylesheet" href="./styles.css" />
24
+ <meta name="x-build" content="2026-06-15T19:17:20.632Z" />
11
25
  </head>
12
26
  <body>
13
27
  <a class="skip-link" href="#app">Skip to content</a>
@@ -52,6 +66,6 @@
52
66
  <ul id="commandList" class="cmd-list" role="listbox"></ul>
53
67
  </div>
54
68
  </div>
55
- <script type="module" src="/app.js"></script>
69
+ <script type="module" src="./app.js"></script>
56
70
  </body>
57
71
  </html>
package/site/manifest.js CHANGED
@@ -3,7 +3,7 @@ export const MANIFEST = [
3
3
  "id": "welcome",
4
4
  "title": "Welcome",
5
5
  "summary": "What Pagenary is and how this dogfooded portal is built.",
6
- "module": "/sections/welcome.js"
6
+ "module": "./sections/welcome.js"
7
7
  },
8
8
  {
9
9
  "id": "getting-started",
@@ -14,7 +14,7 @@ export const MANIFEST = [
14
14
  "id": "quickstart",
15
15
  "title": "Quickstart",
16
16
  "summary": "Install, build the default bundle, and serve it locally.",
17
- "module": "/sections/quickstart.js"
17
+ "module": "./sections/quickstart.js"
18
18
  }
19
19
  ]
20
20
  },
@@ -27,19 +27,19 @@ export const MANIFEST = [
27
27
  "id": "developer-guide",
28
28
  "title": "Developer Guide",
29
29
  "summary": "Project layout, scripts, and the content authoring workflow.",
30
- "module": "/sections/developer-guide.js"
30
+ "module": "./sections/developer-guide.js"
31
31
  },
32
32
  {
33
33
  "id": "tenant-config",
34
34
  "title": "Tenant Configuration",
35
35
  "summary": "Every config.json option: branding, theming, SEO, and export.",
36
- "module": "/sections/tenant-config.js"
36
+ "module": "./sections/tenant-config.js"
37
37
  },
38
38
  {
39
39
  "id": "extending",
40
40
  "title": "Extending",
41
41
  "summary": "Add section templates, content types, and build behaviors.",
42
- "module": "/sections/extending.js"
42
+ "module": "./sections/extending.js"
43
43
  }
44
44
  ]
45
45
  },
@@ -52,25 +52,25 @@ export const MANIFEST = [
52
52
  "id": "architecture",
53
53
  "title": "Architecture",
54
54
  "summary": "The static SPA pattern, build pipeline, and tenant content model.",
55
- "module": "/sections/architecture.js"
55
+ "module": "./sections/architecture.js"
56
56
  },
57
57
  {
58
58
  "id": "api",
59
59
  "title": "API Reference",
60
60
  "summary": "Module-level documentation for the publisher internals.",
61
- "module": "/sections/api.js"
61
+ "module": "./sections/api.js"
62
62
  },
63
63
  {
64
64
  "id": "deployment",
65
65
  "title": "Deployment",
66
66
  "summary": "Hosting the static output and multi-tenant domain routing.",
67
- "module": "/sections/deployment.js"
67
+ "module": "./sections/deployment.js"
68
68
  },
69
69
  {
70
70
  "id": "seo-strategy",
71
71
  "title": "SEO Strategy",
72
72
  "summary": "Metadata, hash-routing considerations, and discoverability.",
73
- "module": "/sections/seo-strategy.js"
73
+ "module": "./sections/seo-strategy.js"
74
74
  }
75
75
  ]
76
76
  }
package/site/robots.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  # Pagenary Docs
2
- # Generated: 2026-06-15T18:50:34.704Z
2
+ # Generated: 2026-06-15T19:17:21.186Z
3
3
 
4
4
  User-agent: *
5
5
  Allow: /
package/src/index.html CHANGED
@@ -5,8 +5,22 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1" />
6
6
  <title>Docs Toolkit</title>
7
7
  <meta name="description" content="Reusable documentation toolkit for multi-tenant services." />
8
- <link rel="icon" type="image/png" href="/favicon.png" />
9
- <link rel="stylesheet" href="/styles.css" />
8
+ <script>
9
+ // Resolve all asset/module URLs against the tenant root in both deploy
10
+ // modes: domain-per-tenant at root (production, with SPA fallback) and a
11
+ // subpath mount such as /<tenant>/ (the dev preview server). The tenant id
12
+ // is injected at build time. On a domain root the path never starts with
13
+ // "/<tenant>/", so the base falls back to "/". For the un-replaced default
14
+ // build the placeholder starts with "_", which also yields "/".
15
+ (function () {
16
+ var t = "__PAGENARY_TENANT__";
17
+ var p = location.pathname;
18
+ var base = t && p.indexOf("/" + t + "/") === 0 ? "/" + t + "/" : "/";
19
+ document.write('<base href="' + base + '">');
20
+ })();
21
+ </script>
22
+ <link rel="icon" type="image/png" href="./favicon.png" />
23
+ <link rel="stylesheet" href="./styles.css" />
10
24
  </head>
11
25
  <body>
12
26
  <a class="skip-link" href="#app">Skip to content</a>
@@ -51,6 +65,6 @@
51
65
  <ul id="commandList" class="cmd-list" role="listbox"></ul>
52
66
  </div>
53
67
  </div>
54
- <script type="module" src="/app.js"></script>
68
+ <script type="module" src="./app.js"></script>
55
69
  </body>
56
70
  </html>