@olonjs/cli 3.0.139 → 3.0.141
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/assets/src_tenant_alpha.sh +339 -98
- package/assets/templates/alpha/src_tenant.sh +339 -98
- package/package.json +1 -1
|
@@ -1649,6 +1649,149 @@ cat << 'END_OF_FILE_CONTENT' > "index.html"
|
|
|
1649
1649
|
</html>
|
|
1650
1650
|
|
|
1651
1651
|
|
|
1652
|
+
END_OF_FILE_CONTENT
|
|
1653
|
+
echo "Creating middleware.ts..."
|
|
1654
|
+
cat << 'END_OF_FILE_CONTENT' > "middleware.ts"
|
|
1655
|
+
export const config = {
|
|
1656
|
+
matcher: ['/admin', '/admin/:path*'],
|
|
1657
|
+
};
|
|
1658
|
+
|
|
1659
|
+
const COOKIE_NAME = '__olonjs_admin_session';
|
|
1660
|
+
const COOKIE_MAX_AGE = 3600;
|
|
1661
|
+
const JWT_MAX_AGE_SECONDS = 300;
|
|
1662
|
+
|
|
1663
|
+
function base64urlToBase64(str: string): string {
|
|
1664
|
+
return str.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (str.length % 4)) % 4);
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
function base64ToArrayBuffer(b64: string): ArrayBuffer {
|
|
1668
|
+
const binary = atob(b64);
|
|
1669
|
+
const bytes = new Uint8Array(binary.length);
|
|
1670
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1671
|
+
return bytes.buffer;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
function pemToArrayBuffer(pem: string): ArrayBuffer {
|
|
1675
|
+
// Handle both actual newlines and literal \n sequences (common in Vercel env vars)
|
|
1676
|
+
const b64 = pem
|
|
1677
|
+
.replace(/-----BEGIN PUBLIC KEY-----/g, '')
|
|
1678
|
+
.replace(/-----END PUBLIC KEY-----/g, '')
|
|
1679
|
+
.replace(/\\n/g, '')
|
|
1680
|
+
.replace(/\s+/g, '');
|
|
1681
|
+
return base64ToArrayBuffer(b64);
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
async function importPublicKey(pem: string): Promise<CryptoKey> {
|
|
1685
|
+
return crypto.subtle.importKey(
|
|
1686
|
+
'spki',
|
|
1687
|
+
pemToArrayBuffer(pem),
|
|
1688
|
+
{ name: 'ECDSA', namedCurve: 'P-256' },
|
|
1689
|
+
false,
|
|
1690
|
+
['verify'],
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
interface JwtPayload {
|
|
1695
|
+
sub?: string;
|
|
1696
|
+
iat?: number;
|
|
1697
|
+
exp?: number;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
async function verifyAdminJwt(
|
|
1701
|
+
token: string,
|
|
1702
|
+
publicKey: CryptoKey,
|
|
1703
|
+
options: { checkExp: boolean } = { checkExp: true },
|
|
1704
|
+
): Promise<boolean> {
|
|
1705
|
+
try {
|
|
1706
|
+
const parts = token.split('.');
|
|
1707
|
+
if (parts.length !== 3) return false;
|
|
1708
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
1709
|
+
|
|
1710
|
+
const payload = JSON.parse(atob(base64urlToBase64(payloadB64))) as JwtPayload;
|
|
1711
|
+
if (payload.sub !== 'admin-access') return false;
|
|
1712
|
+
|
|
1713
|
+
if (options.checkExp) {
|
|
1714
|
+
const now = Math.floor(Date.now() / 1000);
|
|
1715
|
+
if (typeof payload.exp !== 'number' || payload.exp < now) return false;
|
|
1716
|
+
if (typeof payload.iat !== 'number' || now - payload.iat > JWT_MAX_AGE_SECONDS) return false;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
const message = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
|
|
1720
|
+
const signature = base64ToArrayBuffer(base64urlToBase64(signatureB64));
|
|
1721
|
+
return crypto.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, publicKey, signature, message);
|
|
1722
|
+
} catch {
|
|
1723
|
+
return false;
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
function parseCookies(header: string | null): Record<string, string> {
|
|
1728
|
+
if (!header) return {};
|
|
1729
|
+
return Object.fromEntries(
|
|
1730
|
+
header.split(';').map((c) => {
|
|
1731
|
+
const [k, ...v] = c.trim().split('=');
|
|
1732
|
+
return [k.trim(), decodeURIComponent(v.join('='))];
|
|
1733
|
+
}),
|
|
1734
|
+
);
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
function deny(hint: string): Response {
|
|
1738
|
+
console.error(`[admin-middleware] 401 reason: ${hint}`);
|
|
1739
|
+
return new Response('Unauthorized', { status: 401 });
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
export default async function middleware(request: Request): Promise<Response | undefined> {
|
|
1743
|
+
if (!process.env.VERCEL_ENV) return undefined;
|
|
1744
|
+
|
|
1745
|
+
const publicKeyPem = process.env.ADMIN_PUBLIC_KEY;
|
|
1746
|
+
if (!publicKeyPem) return deny('missing_public_key');
|
|
1747
|
+
|
|
1748
|
+
let publicKey: CryptoKey;
|
|
1749
|
+
try {
|
|
1750
|
+
publicKey = await importPublicKey(publicKeyPem);
|
|
1751
|
+
} catch (e) {
|
|
1752
|
+
return deny(`key_import_failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
const url = new URL(request.url);
|
|
1756
|
+
const cookies = parseCookies(request.headers.get('Cookie'));
|
|
1757
|
+
|
|
1758
|
+
// 1. Session cookie — signature check only; session lifetime governed by cookie Max-Age.
|
|
1759
|
+
// The JWT stored in the cookie was valid at issue time; exp is intentionally skipped
|
|
1760
|
+
// to allow 1h sessions without requiring the private key in the Edge Runtime.
|
|
1761
|
+
// parseCookies already decodes values — no extra decodeURIComponent needed here
|
|
1762
|
+
const sessionToken = cookies[COOKIE_NAME];
|
|
1763
|
+
if (sessionToken) {
|
|
1764
|
+
const cookieValid = await verifyAdminJwt(sessionToken, publicKey, { checkExp: false });
|
|
1765
|
+
console.error(`[admin-middleware] cookie check: present=${!!sessionToken} valid=${cookieValid}`);
|
|
1766
|
+
if (cookieValid) return undefined;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
// 2. Bearer token in Authorization header — full validation including exp
|
|
1770
|
+
const authHeader = request.headers.get('Authorization') ?? '';
|
|
1771
|
+
const bearerToken = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : null;
|
|
1772
|
+
if (bearerToken && (await verifyAdminJwt(bearerToken, publicKey))) {
|
|
1773
|
+
return undefined;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// 3. Token as query param — full validation; set session cookie and redirect to clean URL
|
|
1777
|
+
const queryToken = url.searchParams.get('token');
|
|
1778
|
+
if (queryToken && (await verifyAdminJwt(queryToken, publicKey))) {
|
|
1779
|
+
const cleanUrl = new URL(url.toString());
|
|
1780
|
+
cleanUrl.searchParams.delete('token');
|
|
1781
|
+
return new Response(null, {
|
|
1782
|
+
status: 302,
|
|
1783
|
+
headers: {
|
|
1784
|
+
Location: cleanUrl.toString(),
|
|
1785
|
+
// SameSite=Lax required: navigation originates from a cross-site platform (app.olon.it)
|
|
1786
|
+
// SameSite=Strict would block the cookie in the redirect follow-up request
|
|
1787
|
+
'Set-Cookie': `${COOKIE_NAME}=${encodeURIComponent(queryToken)}; Path=/admin; HttpOnly; Secure; SameSite=Lax; Max-Age=${COOKIE_MAX_AGE}`,
|
|
1788
|
+
},
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
return deny('token_invalid');
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1652
1795
|
END_OF_FILE_CONTENT
|
|
1653
1796
|
echo "Creating package.json..."
|
|
1654
1797
|
cat << 'END_OF_FILE_CONTENT' > "package.json"
|
|
@@ -1661,9 +1804,9 @@ cat << 'END_OF_FILE_CONTENT' > "package.json"
|
|
|
1661
1804
|
"dev": "vite",
|
|
1662
1805
|
"dev:clean": "vite --force",
|
|
1663
1806
|
"verify:webmcp": "node scripts/webmcp-feature-check.mjs",
|
|
1664
|
-
"prebuild": "node scripts/sync-pages-to-public.mjs && node scripts/generate-llms-txt.mjs",
|
|
1807
|
+
"prebuild": "node scripts/sync-pages-to-public.mjs && node scripts/generate-llms-txt.mjs && node scripts/bake.mjs && node scripts/sitemap.mjs && node scripts/robots.mjs",
|
|
1665
1808
|
"build": "tsc && vite build",
|
|
1666
|
-
"dist": "bash ./src2Code.sh --template alpha src .cursor vercel.json components.json index.html tsconfig.json package.json tsconfig.node.json vite.config.ts scripts ",
|
|
1809
|
+
"dist": "bash ./src2Code.sh --template alpha src .cursor vercel.json components.json index.html tsconfig.json package.json tsconfig.node.json vite.config.ts scripts middleware.ts",
|
|
1667
1810
|
"preview": "vite preview",
|
|
1668
1811
|
"bake:email": "tsx scripts/bake-email.tsx",
|
|
1669
1812
|
"bakemail": "npm run bake:email --",
|
|
@@ -1674,7 +1817,7 @@ cat << 'END_OF_FILE_CONTENT' > "package.json"
|
|
|
1674
1817
|
"@tiptap/extension-link": "^2.11.5",
|
|
1675
1818
|
"@tiptap/react": "^2.11.5",
|
|
1676
1819
|
"@tiptap/starter-kit": "^2.11.5",
|
|
1677
|
-
"@olonjs/core": "^1.1.
|
|
1820
|
+
"@olonjs/core": "^1.1.5",
|
|
1678
1821
|
"class-variance-authority": "^0.7.1",
|
|
1679
1822
|
"clsx": "^2.1.1",
|
|
1680
1823
|
"lucide-react": "^0.474.0",
|
|
@@ -2239,6 +2382,149 @@ const outPath = path.join(rootDir, 'public', 'llms.txt');
|
|
|
2239
2382
|
fs.writeFileSync(outPath, llmsTxt, 'utf-8');
|
|
2240
2383
|
console.log('[generate-llms-txt] Written -> public/llms.txt');
|
|
2241
2384
|
|
|
2385
|
+
END_OF_FILE_CONTENT
|
|
2386
|
+
echo "Creating scripts/robots.mjs..."
|
|
2387
|
+
cat << 'END_OF_FILE_CONTENT' > "scripts/robots.mjs"
|
|
2388
|
+
import fs from 'fs';
|
|
2389
|
+
import path from 'path';
|
|
2390
|
+
import { fileURLToPath } from 'url';
|
|
2391
|
+
|
|
2392
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
2393
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
2394
|
+
|
|
2395
|
+
const baseUrl = process.env.VERCEL_PROJECT_PRODUCTION_URL
|
|
2396
|
+
? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
|
|
2397
|
+
: 'http://localhost:5173';
|
|
2398
|
+
|
|
2399
|
+
const robotsTxt = `User-agent: *
|
|
2400
|
+
Allow: /
|
|
2401
|
+
Disallow: /api/
|
|
2402
|
+
|
|
2403
|
+
User-agent: GPTBot
|
|
2404
|
+
User-agent: ChatGPT-User
|
|
2405
|
+
User-agent: ClaudeBot
|
|
2406
|
+
User-agent: Claude-Web
|
|
2407
|
+
User-agent: PerplexityBot
|
|
2408
|
+
User-agent: OAI-SearchBot
|
|
2409
|
+
Allow: /
|
|
2410
|
+
Allow: /*.json
|
|
2411
|
+
Allow: /schemas/
|
|
2412
|
+
Allow: /llms.txt
|
|
2413
|
+
Allow: /mcp-manifest.json
|
|
2414
|
+
Disallow: /api/
|
|
2415
|
+
|
|
2416
|
+
Sitemap: ${baseUrl}/sitemap.xml
|
|
2417
|
+
`;
|
|
2418
|
+
|
|
2419
|
+
const outPath = path.join(rootDir, 'public', 'robots.txt');
|
|
2420
|
+
fs.writeFileSync(outPath, robotsTxt, 'utf-8');
|
|
2421
|
+
console.log('[robots] Written -> public/robots.txt');
|
|
2422
|
+
|
|
2423
|
+
END_OF_FILE_CONTENT
|
|
2424
|
+
echo "Creating scripts/sitemap.mjs..."
|
|
2425
|
+
cat << 'END_OF_FILE_CONTENT' > "scripts/sitemap.mjs"
|
|
2426
|
+
import fs from 'fs';
|
|
2427
|
+
import path from 'path';
|
|
2428
|
+
import { fileURLToPath } from 'url';
|
|
2429
|
+
|
|
2430
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
2431
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
2432
|
+
|
|
2433
|
+
const baseUrl = process.env.VERCEL_PROJECT_PRODUCTION_URL
|
|
2434
|
+
? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
|
|
2435
|
+
: 'http://localhost:5173';
|
|
2436
|
+
|
|
2437
|
+
function listJsonFilesRecursive(dir) {
|
|
2438
|
+
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
2439
|
+
const files = [];
|
|
2440
|
+
for (const item of items) {
|
|
2441
|
+
const fullPath = path.join(dir, item.name);
|
|
2442
|
+
if (item.isDirectory()) {
|
|
2443
|
+
files.push(...listJsonFilesRecursive(fullPath));
|
|
2444
|
+
continue;
|
|
2445
|
+
}
|
|
2446
|
+
if (item.isFile() && item.name.toLowerCase().endsWith('.json')) files.push(fullPath);
|
|
2447
|
+
}
|
|
2448
|
+
return files;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
function toW3CDate(date) {
|
|
2452
|
+
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
function urlEntry({ loc, lastmod, changefreq, priority, comment }) {
|
|
2456
|
+
const lines = [];
|
|
2457
|
+
if (comment) lines.push(` <!-- ${comment} -->`);
|
|
2458
|
+
lines.push(` <url>`);
|
|
2459
|
+
lines.push(` <loc>${loc}</loc>`);
|
|
2460
|
+
lines.push(` <lastmod>${lastmod}</lastmod>`);
|
|
2461
|
+
lines.push(` <changefreq>${changefreq}</changefreq>`);
|
|
2462
|
+
lines.push(` <priority>${priority}</priority>`);
|
|
2463
|
+
lines.push(` </url>`);
|
|
2464
|
+
return lines.join('\n');
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
function sectionComment(label) {
|
|
2468
|
+
const bar = '='.repeat(42);
|
|
2469
|
+
return [
|
|
2470
|
+
` <!-- ${bar} -->`,
|
|
2471
|
+
` <!-- ${label.padEnd(42)} -->`,
|
|
2472
|
+
` <!-- ${bar} -->`,
|
|
2473
|
+
].join('\n');
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
const pagesDir = path.join(rootDir, 'src', 'data', 'pages');
|
|
2477
|
+
const buildTime = toW3CDate(new Date());
|
|
2478
|
+
|
|
2479
|
+
const pageFiles = listJsonFilesRecursive(pagesDir);
|
|
2480
|
+
const pages = pageFiles.map((fullPath) => {
|
|
2481
|
+
const slug = path
|
|
2482
|
+
.relative(pagesDir, fullPath)
|
|
2483
|
+
.replace(/\\/g, '/')
|
|
2484
|
+
.replace(/\.json$/i, '');
|
|
2485
|
+
const lastmod = toW3CDate(fs.statSync(fullPath).mtime);
|
|
2486
|
+
return { slug, lastmod };
|
|
2487
|
+
});
|
|
2488
|
+
|
|
2489
|
+
const entries = [];
|
|
2490
|
+
|
|
2491
|
+
entries.push(sectionComment('GLOBAL AGENT DISCOVERY NODES'));
|
|
2492
|
+
entries.push(
|
|
2493
|
+
urlEntry({ loc: `${baseUrl}/llms.txt`, lastmod: buildTime, changefreq: 'weekly', priority: '1.0' }),
|
|
2494
|
+
);
|
|
2495
|
+
entries.push(
|
|
2496
|
+
urlEntry({ loc: `${baseUrl}/mcp-manifest.json`, lastmod: buildTime, changefreq: 'weekly', priority: '1.0' }),
|
|
2497
|
+
);
|
|
2498
|
+
|
|
2499
|
+
for (const { slug, lastmod } of pages) {
|
|
2500
|
+
const humanPath = slug === 'home' ? '/' : `/${slug}`;
|
|
2501
|
+
const label = `PAGE: ${slug.toUpperCase()}`;
|
|
2502
|
+
|
|
2503
|
+
entries.push(sectionComment(label));
|
|
2504
|
+
entries.push(
|
|
2505
|
+
urlEntry({ loc: `${baseUrl}${humanPath}`, lastmod, changefreq: 'daily', priority: '0.9', comment: 'Human UI' }),
|
|
2506
|
+
);
|
|
2507
|
+
entries.push(
|
|
2508
|
+
urlEntry({ loc: `${baseUrl}/${slug}.json`, lastmod, changefreq: 'daily', priority: '0.9', comment: 'Machine Payload' }),
|
|
2509
|
+
);
|
|
2510
|
+
entries.push(
|
|
2511
|
+
urlEntry({ loc: `${baseUrl}/schemas/${slug}.schema.json`, lastmod: buildTime, changefreq: 'weekly', priority: '0.8', comment: 'Machine Contract (Schema)' }),
|
|
2512
|
+
);
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
const xml = [
|
|
2516
|
+
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
2517
|
+
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`,
|
|
2518
|
+
``,
|
|
2519
|
+
entries.join('\n'),
|
|
2520
|
+
``,
|
|
2521
|
+
`</urlset>`,
|
|
2522
|
+
].join('\n');
|
|
2523
|
+
|
|
2524
|
+
const outPath = path.join(rootDir, 'public', 'sitemap.xml');
|
|
2525
|
+
fs.writeFileSync(outPath, xml, 'utf-8');
|
|
2526
|
+
console.log('[sitemap] Written -> public/sitemap.xml');
|
|
2527
|
+
|
|
2242
2528
|
END_OF_FILE_CONTENT
|
|
2243
2529
|
echo "Creating scripts/sync-pages-to-public.mjs..."
|
|
2244
2530
|
cat << 'END_OF_FILE_CONTENT' > "scripts/sync-pages-to-public.mjs"
|
|
@@ -2582,20 +2868,18 @@ cat << 'END_OF_FILE_CONTENT' > "src/App.tsx"
|
|
|
2582
2868
|
* Data from getHydratedData (file-backed or draft); assets from public/assets/images.
|
|
2583
2869
|
* Supports Hybrid Persistence: Local Filesystem (Dev) or Cloud Bridge (Prod).
|
|
2584
2870
|
*/
|
|
2585
|
-
import { useCallback, useEffect, useMemo, useRef, useState
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
import {
|
|
2589
|
-
import type { JsonPagesConfig, LibraryImageEntry, ProjectState } from '@olonjs/core/runtime';
|
|
2590
|
-
import { normalizeBasePath, withBasePath } from '@olonjs/core/runtime';
|
|
2871
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2872
|
+
import { JsonPagesEngine } from '@olonjs/core';
|
|
2873
|
+
import type { JsonPagesConfig, LibraryImageEntry, ProjectState } from '@olonjs/core';
|
|
2874
|
+
import { normalizeBasePath, withBasePath } from '@olonjs/core';
|
|
2591
2875
|
import { ComponentRegistry } from '@/lib/ComponentRegistry';
|
|
2592
2876
|
import { SECTION_SCHEMAS, SECTION_SUBMISSION_SCHEMAS } from '@/lib/schemas';
|
|
2593
2877
|
import { addSectionConfig } from '@/lib/addSectionConfig';
|
|
2594
2878
|
import { getHydratedData } from '@/lib/draftStorage';
|
|
2595
2879
|
import type { SiteConfig, ThemeConfig, MenuConfig, PageConfig } from '@/types';
|
|
2596
|
-
import type { DeployPhase, StepId } from '@olonjs/core
|
|
2597
|
-
import { DEPLOY_STEPS } from '@olonjs/core
|
|
2598
|
-
import { startCloudSaveStream } from '@olonjs/core
|
|
2880
|
+
import type { DeployPhase, StepId } from '@olonjs/core';
|
|
2881
|
+
import { DEPLOY_STEPS } from '@olonjs/core';
|
|
2882
|
+
import { startCloudSaveStream } from '@olonjs/core';
|
|
2599
2883
|
import siteData from '@/data/config/site.json';
|
|
2600
2884
|
import themeData from '@/data/config/theme.json';
|
|
2601
2885
|
import menuData from '@/data/config/menu.json';
|
|
@@ -2605,23 +2889,9 @@ import { EmptyTenantView } from '@/components/empty-tenant';
|
|
|
2605
2889
|
import { Skeleton } from '@/components/ui/skeleton';
|
|
2606
2890
|
import { ThemeProvider } from '@/components/ThemeProvider';
|
|
2607
2891
|
import { useOlonForms } from '@/lib/useOlonForms';
|
|
2608
|
-
import { OlonFormsContext } from '@olonjs/core
|
|
2892
|
+
import { OlonFormsContext } from '@olonjs/core';
|
|
2609
2893
|
import { iconMap } from '@/lib/IconResolver';
|
|
2610
2894
|
|
|
2611
|
-
/**
|
|
2612
|
-
* Engine selector. Visitors get OlonJSEngine (~28 KB gz); /admin paths
|
|
2613
|
-
* lazy-load the full JsonPagesEngine (~128 KB gz) which mounts the
|
|
2614
|
-
* Studio editor surface. The check runs at module load time — once per
|
|
2615
|
-
* page, before React mounts — so Vite statically splits the chunks.
|
|
2616
|
-
* See ADR-0008 + ADR-0009 + docs/plans/core-studio-split.md (Task 3.1).
|
|
2617
|
-
*/
|
|
2618
|
-
const isAdminPath =
|
|
2619
|
-
typeof window !== 'undefined' && window.location.pathname.startsWith('/admin');
|
|
2620
|
-
|
|
2621
|
-
const LazyJsonPagesEngine = lazy(() =>
|
|
2622
|
-
import('@olonjs/core').then((m) => ({ default: m.JsonPagesEngine })),
|
|
2623
|
-
);
|
|
2624
|
-
|
|
2625
2895
|
import tenantCss from './index.css?inline';
|
|
2626
2896
|
|
|
2627
2897
|
// Cloud Configuration (Injected by Vercel/Netlify Env Vars)
|
|
@@ -3683,12 +3953,8 @@ function App() {
|
|
|
3683
3953
|
{shouldRenderEngine ? (
|
|
3684
3954
|
isTenantEmpty ? (
|
|
3685
3955
|
<EmptyTenantView />
|
|
3686
|
-
) : isAdminPath ? (
|
|
3687
|
-
<Suspense fallback={null}>
|
|
3688
|
-
<LazyJsonPagesEngine config={config} />
|
|
3689
|
-
</Suspense>
|
|
3690
3956
|
) : (
|
|
3691
|
-
<
|
|
3957
|
+
<JsonPagesEngine config={config} />
|
|
3692
3958
|
)
|
|
3693
3959
|
) : null}
|
|
3694
3960
|
{isCloudMode && (contentMode === 'error' || contentFallback?.reasonCode === 'CLOUD_REFRESH_FAILED') ? (
|
|
@@ -3864,7 +4130,7 @@ END_OF_FILE_CONTENT
|
|
|
3864
4130
|
echo "Creating src/components/empty-tenant/schema.ts..."
|
|
3865
4131
|
cat << 'END_OF_FILE_CONTENT' > "src/components/empty-tenant/schema.ts"
|
|
3866
4132
|
import { z } from 'zod';
|
|
3867
|
-
import { BaseSectionData } from '@olonjs/core
|
|
4133
|
+
import { BaseSectionData } from '@olonjs/core';
|
|
3868
4134
|
|
|
3869
4135
|
export const EmptyTenantSchema = BaseSectionData.extend({
|
|
3870
4136
|
title: z.string().optional().describe('ui:text'),
|
|
@@ -3887,7 +4153,7 @@ mkdir -p "src/components/form-demo"
|
|
|
3887
4153
|
echo "Creating src/components/form-demo/View.tsx..."
|
|
3888
4154
|
cat << 'END_OF_FILE_CONTENT' > "src/components/form-demo/View.tsx"
|
|
3889
4155
|
import { Icon } from '@/lib/IconResolver';
|
|
3890
|
-
import { useFormState } from '@olonjs/core
|
|
4156
|
+
import { useFormState } from '@olonjs/core';
|
|
3891
4157
|
import type { FormDemoData } from './types';
|
|
3892
4158
|
|
|
3893
4159
|
type FormDemoViewProps = {
|
|
@@ -4051,7 +4317,7 @@ END_OF_FILE_CONTENT
|
|
|
4051
4317
|
echo "Creating src/components/form-demo/schema.ts..."
|
|
4052
4318
|
cat << 'END_OF_FILE_CONTENT' > "src/components/form-demo/schema.ts"
|
|
4053
4319
|
import { z } from 'zod';
|
|
4054
|
-
import { BaseSectionData, WithFormRecipient } from '@olonjs/core
|
|
4320
|
+
import { BaseSectionData, WithFormRecipient } from '@olonjs/core';
|
|
4055
4321
|
|
|
4056
4322
|
export const FormDemoSchema = BaseSectionData.merge(WithFormRecipient).extend({
|
|
4057
4323
|
icon: z.string().optional().describe('ui:icon-picker'),
|
|
@@ -4090,7 +4356,7 @@ END_OF_FILE_CONTENT
|
|
|
4090
4356
|
mkdir -p "src/components/save-drawer"
|
|
4091
4357
|
echo "Creating src/components/save-drawer/DeployConnector.tsx..."
|
|
4092
4358
|
cat << 'END_OF_FILE_CONTENT' > "src/components/save-drawer/DeployConnector.tsx"
|
|
4093
|
-
import type { StepState } from '@olonjs/core
|
|
4359
|
+
import type { StepState } from '@olonjs/core';
|
|
4094
4360
|
|
|
4095
4361
|
interface DeployConnectorProps {
|
|
4096
4362
|
fromState: StepState;
|
|
@@ -4136,7 +4402,7 @@ END_OF_FILE_CONTENT
|
|
|
4136
4402
|
echo "Creating src/components/save-drawer/DeployNode.tsx..."
|
|
4137
4403
|
cat << 'END_OF_FILE_CONTENT' > "src/components/save-drawer/DeployNode.tsx"
|
|
4138
4404
|
import type { CSSProperties } from 'react';
|
|
4139
|
-
import type { DeployStep, StepState } from '@olonjs/core
|
|
4405
|
+
import type { DeployStep, StepState } from '@olonjs/core';
|
|
4140
4406
|
|
|
4141
4407
|
interface DeployNodeProps {
|
|
4142
4408
|
step: DeployStep;
|
|
@@ -4224,8 +4490,8 @@ echo "Creating src/components/save-drawer/DopaDrawer.tsx..."
|
|
|
4224
4490
|
cat << 'END_OF_FILE_CONTENT' > "src/components/save-drawer/DopaDrawer.tsx"
|
|
4225
4491
|
import { useEffect, useMemo, useState } from 'react';
|
|
4226
4492
|
import { createPortal } from 'react-dom';
|
|
4227
|
-
import type { StepId, StepState } from '@olonjs/core
|
|
4228
|
-
import { DEPLOY_STEPS } from '@olonjs/core
|
|
4493
|
+
import type { StepId, StepState } from '@olonjs/core';
|
|
4494
|
+
import { DEPLOY_STEPS } from '@olonjs/core';
|
|
4229
4495
|
import fontsCss from '@/fonts.css?inline';
|
|
4230
4496
|
import saverStyleCss from './saverStyle.css?inline';
|
|
4231
4497
|
import { DeployNode } from './DeployNode';
|
|
@@ -5432,7 +5698,7 @@ import {
|
|
|
5432
5698
|
Code2, Quote, SquareCode,
|
|
5433
5699
|
Link2, Unlink2, ImagePlus, Eraser,
|
|
5434
5700
|
} from 'lucide-react';
|
|
5435
|
-
import { STUDIO_EVENTS, useConfig, useStudio } from '@olonjs/core
|
|
5701
|
+
import { STUDIO_EVENTS, useConfig, useStudio } from '@olonjs/core';
|
|
5436
5702
|
import type { TiptapData, TiptapSettings } from './types';
|
|
5437
5703
|
|
|
5438
5704
|
// ── UI primitives ─────────────────────────────────────────────────
|
|
@@ -5755,7 +6021,7 @@ END_OF_FILE_CONTENT
|
|
|
5755
6021
|
echo "Creating src/components/tiptap/schema.ts..."
|
|
5756
6022
|
cat << 'END_OF_FILE_CONTENT' > "src/components/tiptap/schema.ts"
|
|
5757
6023
|
import { z } from 'zod';
|
|
5758
|
-
import { BaseSectionData } from '@olonjs/core
|
|
6024
|
+
import { BaseSectionData } from '@olonjs/core';
|
|
5759
6025
|
|
|
5760
6026
|
export const TiptapSchema = BaseSectionData.extend({
|
|
5761
6027
|
content: z.string().default('').describe('ui:editorial-markdown'),
|
|
@@ -5776,7 +6042,7 @@ END_OF_FILE_CONTENT
|
|
|
5776
6042
|
mkdir -p "src/components/ui"
|
|
5777
6043
|
echo "Creating src/components/ui/OlonMark.tsx..."
|
|
5778
6044
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/OlonMark.tsx"
|
|
5779
|
-
import { cn } from '@olonjs/core
|
|
6045
|
+
import { cn } from '@olonjs/core'
|
|
5780
6046
|
|
|
5781
6047
|
interface OlonMarkProps {
|
|
5782
6048
|
size?: number
|
|
@@ -5866,7 +6132,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/accordion.tsx"
|
|
|
5866
6132
|
import * as React from "react"
|
|
5867
6133
|
import { Accordion as AccordionPrimitive } from "radix-ui"
|
|
5868
6134
|
|
|
5869
|
-
import { cn } from "@olonjs/core
|
|
6135
|
+
import { cn } from "@olonjs/core"
|
|
5870
6136
|
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
|
|
5871
6137
|
|
|
5872
6138
|
function Accordion({
|
|
@@ -5970,7 +6236,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/avatar.tsx"
|
|
|
5970
6236
|
import * as React from "react"
|
|
5971
6237
|
import { Avatar as AvatarPrimitive } from "radix-ui"
|
|
5972
6238
|
|
|
5973
|
-
import { cn } from "@olonjs/core
|
|
6239
|
+
import { cn } from "@olonjs/core"
|
|
5974
6240
|
|
|
5975
6241
|
function Avatar({
|
|
5976
6242
|
className,
|
|
@@ -6085,7 +6351,7 @@ echo "Creating src/components/ui/badge.tsx..."
|
|
|
6085
6351
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/badge.tsx"
|
|
6086
6352
|
import * as React from 'react'
|
|
6087
6353
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
6088
|
-
import { cn } from '@olonjs/core
|
|
6354
|
+
import { cn } from '@olonjs/core'
|
|
6089
6355
|
|
|
6090
6356
|
const badgeVariants = cva(
|
|
6091
6357
|
'inline-flex items-center px-2.5 py-0.5 text-xs font-medium transition-colors',
|
|
@@ -6120,7 +6386,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/breadcrumb.tsx"
|
|
|
6120
6386
|
import * as React from "react"
|
|
6121
6387
|
import { Slot } from "radix-ui"
|
|
6122
6388
|
|
|
6123
|
-
import { cn } from "@olonjs/core
|
|
6389
|
+
import { cn } from "@olonjs/core"
|
|
6124
6390
|
import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
|
|
6125
6391
|
|
|
6126
6392
|
function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
|
|
@@ -6247,7 +6513,7 @@ echo "Creating src/components/ui/button.tsx..."
|
|
|
6247
6513
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/button.tsx"
|
|
6248
6514
|
import * as React from 'react'
|
|
6249
6515
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
6250
|
-
import { cn } from '@olonjs/core
|
|
6516
|
+
import { cn } from '@olonjs/core'
|
|
6251
6517
|
|
|
6252
6518
|
const buttonVariants = cva(
|
|
6253
6519
|
'inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 shrink-0',
|
|
@@ -6308,7 +6574,7 @@ END_OF_FILE_CONTENT
|
|
|
6308
6574
|
echo "Creating src/components/ui/card.tsx..."
|
|
6309
6575
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/card.tsx"
|
|
6310
6576
|
import * as React from 'react'
|
|
6311
|
-
import { cn } from '@olonjs/core
|
|
6577
|
+
import { cn } from '@olonjs/core'
|
|
6312
6578
|
|
|
6313
6579
|
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
6314
6580
|
({ className, ...props }, ref) => (
|
|
@@ -6367,7 +6633,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/checkbox.tsx"
|
|
|
6367
6633
|
import * as React from "react"
|
|
6368
6634
|
import { Checkbox as CheckboxPrimitive } from "radix-ui"
|
|
6369
6635
|
|
|
6370
|
-
import { cn } from "@olonjs/core
|
|
6636
|
+
import { cn } from "@olonjs/core"
|
|
6371
6637
|
import { CheckIcon } from "lucide-react"
|
|
6372
6638
|
|
|
6373
6639
|
function Checkbox({
|
|
@@ -6407,7 +6673,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/dialog.tsx"
|
|
|
6407
6673
|
import * as React from "react"
|
|
6408
6674
|
import { Dialog as DialogPrimitive } from "radix-ui"
|
|
6409
6675
|
|
|
6410
|
-
import { cn } from "@olonjs/core
|
|
6676
|
+
import { cn } from "@olonjs/core"
|
|
6411
6677
|
import { Button } from "@/components/ui/button"
|
|
6412
6678
|
import { XIcon } from "lucide-react"
|
|
6413
6679
|
|
|
@@ -6579,7 +6845,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/dropdown-menu.tsx"
|
|
|
6579
6845
|
import * as React from "react"
|
|
6580
6846
|
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
|
|
6581
6847
|
|
|
6582
|
-
import { cn } from "@olonjs/core
|
|
6848
|
+
import { cn } from "@olonjs/core"
|
|
6583
6849
|
import { CheckIcon, ChevronRightIcon } from "lucide-react"
|
|
6584
6850
|
|
|
6585
6851
|
function DropdownMenu({
|
|
@@ -6854,7 +7120,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/hover-card.tsx"
|
|
|
6854
7120
|
import * as React from "react"
|
|
6855
7121
|
import { HoverCard as HoverCardPrimitive } from "radix-ui"
|
|
6856
7122
|
|
|
6857
|
-
import { cn } from "@olonjs/core
|
|
7123
|
+
import { cn } from "@olonjs/core"
|
|
6858
7124
|
|
|
6859
7125
|
function HoverCard({
|
|
6860
7126
|
...props
|
|
@@ -6900,7 +7166,7 @@ END_OF_FILE_CONTENT
|
|
|
6900
7166
|
echo "Creating src/components/ui/input.tsx..."
|
|
6901
7167
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/input.tsx"
|
|
6902
7168
|
import * as React from 'react'
|
|
6903
|
-
import { cn } from '@olonjs/core
|
|
7169
|
+
import { cn } from '@olonjs/core'
|
|
6904
7170
|
|
|
6905
7171
|
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
|
|
6906
7172
|
|
|
@@ -6931,7 +7197,7 @@ END_OF_FILE_CONTENT
|
|
|
6931
7197
|
echo "Creating src/components/ui/label.tsx..."
|
|
6932
7198
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/label.tsx"
|
|
6933
7199
|
import * as React from 'react'
|
|
6934
|
-
import { cn } from '@olonjs/core
|
|
7200
|
+
import { cn } from '@olonjs/core'
|
|
6935
7201
|
|
|
6936
7202
|
const Label = React.forwardRef<
|
|
6937
7203
|
HTMLLabelElement,
|
|
@@ -6955,7 +7221,7 @@ import * as React from "react"
|
|
|
6955
7221
|
import { cva } from "class-variance-authority"
|
|
6956
7222
|
import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui"
|
|
6957
7223
|
|
|
6958
|
-
import { cn } from "@olonjs/core
|
|
7224
|
+
import { cn } from "@olonjs/core"
|
|
6959
7225
|
import { ChevronDownIcon } from "lucide-react"
|
|
6960
7226
|
|
|
6961
7227
|
function NavigationMenu({
|
|
@@ -7124,7 +7390,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/progress.tsx"
|
|
|
7124
7390
|
import * as React from "react"
|
|
7125
7391
|
import { Progress as ProgressPrimitive } from "radix-ui"
|
|
7126
7392
|
|
|
7127
|
-
import { cn } from "@olonjs/core
|
|
7393
|
+
import { cn } from "@olonjs/core"
|
|
7128
7394
|
|
|
7129
7395
|
function Progress({
|
|
7130
7396
|
className,
|
|
@@ -7159,7 +7425,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/scroll-area.tsx"
|
|
|
7159
7425
|
import * as React from "react"
|
|
7160
7426
|
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"
|
|
7161
7427
|
|
|
7162
|
-
import { cn } from "@olonjs/core
|
|
7428
|
+
import { cn } from "@olonjs/core"
|
|
7163
7429
|
|
|
7164
7430
|
function ScrollArea({
|
|
7165
7431
|
className,
|
|
@@ -7218,7 +7484,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/select.tsx"
|
|
|
7218
7484
|
import * as React from "react"
|
|
7219
7485
|
import { Select as SelectPrimitive } from "radix-ui"
|
|
7220
7486
|
|
|
7221
|
-
import { cn } from "@olonjs/core
|
|
7487
|
+
import { cn } from "@olonjs/core"
|
|
7222
7488
|
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
|
|
7223
7489
|
|
|
7224
7490
|
function Select({
|
|
@@ -7604,7 +7870,7 @@ END_OF_FILE_CONTENT
|
|
|
7604
7870
|
echo "Creating src/components/ui/separator.tsx..."
|
|
7605
7871
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/separator.tsx"
|
|
7606
7872
|
import * as React from 'react'
|
|
7607
|
-
import { cn } from '@olonjs/core
|
|
7873
|
+
import { cn } from '@olonjs/core'
|
|
7608
7874
|
|
|
7609
7875
|
const Separator = React.forwardRef<
|
|
7610
7876
|
HTMLDivElement,
|
|
@@ -7633,7 +7899,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/sheet.tsx"
|
|
|
7633
7899
|
import * as React from "react"
|
|
7634
7900
|
import { Dialog as SheetPrimitive } from "radix-ui"
|
|
7635
7901
|
|
|
7636
|
-
import { cn } from "@olonjs/core
|
|
7902
|
+
import { cn } from "@olonjs/core"
|
|
7637
7903
|
import { Button } from "@/components/ui/button"
|
|
7638
7904
|
import { XIcon } from "lucide-react"
|
|
7639
7905
|
|
|
@@ -7781,7 +8047,7 @@ END_OF_FILE_CONTENT
|
|
|
7781
8047
|
# SKIP: src/components/ui/sheet.tsx:Zone.Identifier is binary and cannot be embedded as text.
|
|
7782
8048
|
echo "Creating src/components/ui/skeleton.tsx..."
|
|
7783
8049
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/skeleton.tsx"
|
|
7784
|
-
import { cn } from '@olonjs/core
|
|
8050
|
+
import { cn } from '@olonjs/core';
|
|
7785
8051
|
import type { HTMLAttributes } from 'react';
|
|
7786
8052
|
|
|
7787
8053
|
function Skeleton({
|
|
@@ -7805,7 +8071,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/switch.tsx"
|
|
|
7805
8071
|
import * as React from "react"
|
|
7806
8072
|
import { Switch as SwitchPrimitive } from "radix-ui"
|
|
7807
8073
|
|
|
7808
|
-
import { cn } from "@olonjs/core
|
|
8074
|
+
import { cn } from "@olonjs/core"
|
|
7809
8075
|
|
|
7810
8076
|
function Switch({
|
|
7811
8077
|
className,
|
|
@@ -7841,7 +8107,7 @@ echo "Creating src/components/ui/table.tsx..."
|
|
|
7841
8107
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/table.tsx"
|
|
7842
8108
|
import * as React from "react"
|
|
7843
8109
|
|
|
7844
|
-
import { cn } from "@olonjs/core
|
|
8110
|
+
import { cn } from "@olonjs/core"
|
|
7845
8111
|
|
|
7846
8112
|
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
7847
8113
|
return (
|
|
@@ -7965,7 +8231,7 @@ import * as React from "react"
|
|
|
7965
8231
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
7966
8232
|
import { Tabs as TabsPrimitive } from "radix-ui"
|
|
7967
8233
|
|
|
7968
|
-
import { cn } from "@olonjs/core
|
|
8234
|
+
import { cn } from "@olonjs/core"
|
|
7969
8235
|
|
|
7970
8236
|
function Tabs({
|
|
7971
8237
|
className,
|
|
@@ -8057,7 +8323,7 @@ echo "Creating src/components/ui/textarea.tsx..."
|
|
|
8057
8323
|
cat << 'END_OF_FILE_CONTENT' > "src/components/ui/textarea.tsx"
|
|
8058
8324
|
import * as React from "react"
|
|
8059
8325
|
|
|
8060
|
-
import { cn } from "@olonjs/core
|
|
8326
|
+
import { cn } from "@olonjs/core"
|
|
8061
8327
|
|
|
8062
8328
|
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
8063
8329
|
return (
|
|
@@ -8086,7 +8352,7 @@ import * as React from "react"
|
|
|
8086
8352
|
import { type VariantProps } from "class-variance-authority"
|
|
8087
8353
|
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui"
|
|
8088
8354
|
|
|
8089
|
-
import { cn } from "@olonjs/core
|
|
8355
|
+
import { cn } from "@olonjs/core"
|
|
8090
8356
|
import { toggleVariants } from "@/components/ui/toggle"
|
|
8091
8357
|
|
|
8092
8358
|
const ToggleGroupContext = React.createContext<
|
|
@@ -8181,7 +8447,7 @@ import * as React from "react"
|
|
|
8181
8447
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
8182
8448
|
import { Toggle as TogglePrimitive } from "radix-ui"
|
|
8183
8449
|
|
|
8184
|
-
import { cn } from "@olonjs/core
|
|
8450
|
+
import { cn } from "@olonjs/core"
|
|
8185
8451
|
|
|
8186
8452
|
const toggleVariants = cva(
|
|
8187
8453
|
"group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
@@ -8233,7 +8499,7 @@ cat << 'END_OF_FILE_CONTENT' > "src/components/ui/tooltip.tsx"
|
|
|
8233
8499
|
import * as React from "react"
|
|
8234
8500
|
import { Tooltip as TooltipPrimitive } from "radix-ui"
|
|
8235
8501
|
|
|
8236
|
-
import { cn } from "@olonjs/core
|
|
8502
|
+
import { cn } from "@olonjs/core"
|
|
8237
8503
|
|
|
8238
8504
|
function TooltipProvider({
|
|
8239
8505
|
delayDuration = 0,
|
|
@@ -8936,7 +9202,7 @@ echo "Creating src/entry-ssg.tsx..."
|
|
|
8936
9202
|
cat << 'END_OF_FILE_CONTENT' > "src/entry-ssg.tsx"
|
|
8937
9203
|
import { renderToString } from 'react-dom/server';
|
|
8938
9204
|
import { StaticRouter } from 'react-router-dom/server';
|
|
8939
|
-
import { ConfigProvider, PageRenderer, StudioProvider, resolveRuntimeConfig } from '@olonjs/core
|
|
9205
|
+
import { ConfigProvider, PageRenderer, StudioProvider, resolveRuntimeConfig } from '@olonjs/core';
|
|
8940
9206
|
import type { JsonPagesConfig, PageConfig, SiteConfig, ThemeConfig } from '@/types';
|
|
8941
9207
|
import { ThemeProvider } from '@/components/ThemeProvider';
|
|
8942
9208
|
import { ComponentRegistry } from '@/lib/ComponentRegistry';
|
|
@@ -10144,7 +10410,7 @@ export const Icon: React.FC<IconProps> = ({ name, size = 20, className }) => {
|
|
|
10144
10410
|
END_OF_FILE_CONTENT
|
|
10145
10411
|
echo "Creating src/lib/addSectionConfig.ts..."
|
|
10146
10412
|
cat << 'END_OF_FILE_CONTENT' > "src/lib/addSectionConfig.ts"
|
|
10147
|
-
import type { AddSectionConfig } from '@olonjs/core
|
|
10413
|
+
import type { AddSectionConfig } from '@olonjs/core';
|
|
10148
10414
|
|
|
10149
10415
|
const addableSectionTypes = ['empty-tenant', 'form-demo'] as const;
|
|
10150
10416
|
|
|
@@ -10285,7 +10551,7 @@ export {
|
|
|
10285
10551
|
BaseSectionSettingsSchema,
|
|
10286
10552
|
CtaSchema,
|
|
10287
10553
|
ImageSelectionSchema,
|
|
10288
|
-
} from '@olonjs/core
|
|
10554
|
+
} from '@olonjs/core';
|
|
10289
10555
|
|
|
10290
10556
|
END_OF_FILE_CONTENT
|
|
10291
10557
|
echo "Creating src/lib/useFormSubmit.ts..."
|
|
@@ -10380,7 +10646,7 @@ END_OF_FILE_CONTENT
|
|
|
10380
10646
|
echo "Creating src/lib/useOlonForms.ts..."
|
|
10381
10647
|
cat << 'END_OF_FILE_CONTENT' > "src/lib/useOlonForms.ts"
|
|
10382
10648
|
import { useCallback, useEffect, useState } from 'react';
|
|
10383
|
-
import type { FormState } from '@olonjs/core
|
|
10649
|
+
import type { FormState } from '@olonjs/core';
|
|
10384
10650
|
|
|
10385
10651
|
const API_BASE =
|
|
10386
10652
|
(import.meta.env.VITE_OLONJS_CLOUD_URL as string | undefined) ??
|
|
@@ -10581,12 +10847,6 @@ export type SectionComponentPropsMap = {
|
|
|
10581
10847
|
'form-demo': { data: FormDemoData; settings?: FormDemoSettings };
|
|
10582
10848
|
};
|
|
10583
10849
|
|
|
10584
|
-
// MTRP module augmentation. TypeScript treats `@olonjs/core` and
|
|
10585
|
-
// `@olonjs/core/runtime` as separate module identifiers (different
|
|
10586
|
-
// import specifiers). After ADR-0009 the tenant imports JsonPagesConfig
|
|
10587
|
-
// from `/runtime` for the visitor path, so the section registries must
|
|
10588
|
-
// be augmented for *both* identifiers, otherwise PageConfig.sections
|
|
10589
|
-
// resolves to a generic FallbackSection on the runtime side.
|
|
10590
10850
|
declare module '@olonjs/core' {
|
|
10591
10851
|
export interface SectionDataRegistry {
|
|
10592
10852
|
'empty-tenant': EmptyTenantData;
|
|
@@ -10598,26 +10858,7 @@ declare module '@olonjs/core' {
|
|
|
10598
10858
|
}
|
|
10599
10859
|
}
|
|
10600
10860
|
|
|
10601
|
-
|
|
10602
|
-
export interface SectionDataRegistry {
|
|
10603
|
-
'empty-tenant': EmptyTenantData;
|
|
10604
|
-
'form-demo': FormDemoData;
|
|
10605
|
-
}
|
|
10606
|
-
export interface SectionSettingsRegistry {
|
|
10607
|
-
'empty-tenant': EmptyTenantSettings;
|
|
10608
|
-
'form-demo': FormDemoSettings;
|
|
10609
|
-
}
|
|
10610
|
-
}
|
|
10611
|
-
|
|
10612
|
-
// ADR-0009 D7: tenant types re-export from the runtime subpath, NOT the
|
|
10613
|
-
// full @olonjs/core. This is a value re-export — even though every
|
|
10614
|
-
// consumer in this codebase only does `import type`, Vite's static
|
|
10615
|
-
// graph treats `export *` as a runtime dependency edge. Pointing it at
|
|
10616
|
-
// '@olonjs/core' would pull the full Studio bundle (AdminSidebar,
|
|
10617
|
-
// FormFactory, StudioStage, admin-skin) into the visitor main chunk.
|
|
10618
|
-
// Pointing it at '@olonjs/core/runtime' anchors the graph to the
|
|
10619
|
-
// runtime-only bundle (~28 KB gz) so the visitor entry stays clean.
|
|
10620
|
-
export * from '@olonjs/core/runtime';
|
|
10861
|
+
export * from '@olonjs/core';
|
|
10621
10862
|
|
|
10622
10863
|
END_OF_FILE_CONTENT
|
|
10623
10864
|
echo "Creating src/vite-env.d.ts..."
|