@polardbx/pxbaas 0.0.0-stage → 0.1.0-beta.10
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/README.md +223 -2
- package/bin/pxbaas.js +13 -0
- package/dist/app/local-index.d.ts +70 -0
- package/dist/app/local-index.d.ts.map +1 -0
- package/dist/app/local-index.js +140 -0
- package/dist/app/local-index.js.map +1 -0
- package/dist/app/preflight.d.ts +61 -0
- package/dist/app/preflight.d.ts.map +1 -0
- package/dist/app/preflight.js +115 -0
- package/dist/app/preflight.js.map +1 -0
- package/dist/app/spec-lint.d.ts +45 -0
- package/dist/app/spec-lint.d.ts.map +1 -0
- package/dist/app/spec-lint.js +423 -0
- package/dist/app/spec-lint.js.map +1 -0
- package/dist/app/templates.d.ts +167 -0
- package/dist/app/templates.d.ts.map +1 -0
- package/dist/app/templates.js +151 -0
- package/dist/app/templates.js.map +1 -0
- package/dist/cli/help-guides.d.ts +17 -0
- package/dist/cli/help-guides.d.ts.map +1 -0
- package/dist/cli/help-guides.js +132 -0
- package/dist/cli/help-guides.js.map +1 -0
- package/dist/cli/root.d.ts +3 -0
- package/dist/cli/root.d.ts.map +1 -0
- package/dist/cli/root.js +75 -0
- package/dist/cli/root.js.map +1 -0
- package/dist/commands/app/index.d.ts +8 -0
- package/dist/commands/app/index.d.ts.map +1 -0
- package/dist/commands/app/index.js +1907 -0
- package/dist/commands/app/index.js.map +1 -0
- package/dist/commands/auth/index.d.ts +3 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +198 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/completion/index.d.ts +3 -0
- package/dist/commands/completion/index.d.ts.map +1 -0
- package/dist/commands/completion/index.js +14 -0
- package/dist/commands/completion/index.js.map +1 -0
- package/dist/commands/data/index.d.ts +55 -0
- package/dist/commands/data/index.d.ts.map +1 -0
- package/dist/commands/data/index.js +407 -0
- package/dist/commands/data/index.js.map +1 -0
- package/dist/commands/db/index.d.ts +29 -0
- package/dist/commands/db/index.d.ts.map +1 -0
- package/dist/commands/db/index.js +500 -0
- package/dist/commands/db/index.js.map +1 -0
- package/dist/commands/doctor/index.d.ts +3 -0
- package/dist/commands/doctor/index.d.ts.map +1 -0
- package/dist/commands/doctor/index.js +305 -0
- package/dist/commands/doctor/index.js.map +1 -0
- package/dist/commands/functions/delete.d.ts +3 -0
- package/dist/commands/functions/delete.d.ts.map +1 -0
- package/dist/commands/functions/delete.js +55 -0
- package/dist/commands/functions/delete.js.map +1 -0
- package/dist/commands/functions/deploy.d.ts +3 -0
- package/dist/commands/functions/deploy.d.ts.map +1 -0
- package/dist/commands/functions/deploy.js +118 -0
- package/dist/commands/functions/deploy.js.map +1 -0
- package/dist/commands/functions/index.d.ts +3 -0
- package/dist/commands/functions/index.d.ts.map +1 -0
- package/dist/commands/functions/index.js +15 -0
- package/dist/commands/functions/index.js.map +1 -0
- package/dist/commands/functions/list.d.ts +6 -0
- package/dist/commands/functions/list.d.ts.map +1 -0
- package/dist/commands/functions/list.js +63 -0
- package/dist/commands/functions/list.js.map +1 -0
- package/dist/commands/functions/new.d.ts +7 -0
- package/dist/commands/functions/new.d.ts.map +1 -0
- package/dist/commands/functions/new.js +72 -0
- package/dist/commands/functions/new.js.map +1 -0
- package/dist/commands/gen/index.d.ts +3 -0
- package/dist/commands/gen/index.d.ts.map +1 -0
- package/dist/commands/gen/index.js +323 -0
- package/dist/commands/gen/index.js.map +1 -0
- package/dist/commands/guide/index.d.ts +8 -0
- package/dist/commands/guide/index.d.ts.map +1 -0
- package/dist/commands/guide/index.js +20 -0
- package/dist/commands/guide/index.js.map +1 -0
- package/dist/commands/instance/index.d.ts +8 -0
- package/dist/commands/instance/index.d.ts.map +1 -0
- package/dist/commands/instance/index.js +481 -0
- package/dist/commands/instance/index.js.map +1 -0
- package/dist/commands/login/index.d.ts +3 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +145 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/logout/index.d.ts +3 -0
- package/dist/commands/logout/index.d.ts.map +1 -0
- package/dist/commands/logout/index.js +41 -0
- package/dist/commands/logout/index.js.map +1 -0
- package/dist/commands/profile/import-env.d.ts +18 -0
- package/dist/commands/profile/import-env.d.ts.map +1 -0
- package/dist/commands/profile/import-env.js +206 -0
- package/dist/commands/profile/import-env.js.map +1 -0
- package/dist/commands/profile/index.d.ts +3 -0
- package/dist/commands/profile/index.d.ts.map +1 -0
- package/dist/commands/profile/index.js +124 -0
- package/dist/commands/profile/index.js.map +1 -0
- package/dist/commands/rest/index.d.ts +3 -0
- package/dist/commands/rest/index.d.ts.map +1 -0
- package/dist/commands/rest/index.js +102 -0
- package/dist/commands/rest/index.js.map +1 -0
- package/dist/commands/skill/index.d.ts +11 -0
- package/dist/commands/skill/index.d.ts.map +1 -0
- package/dist/commands/skill/index.js +228 -0
- package/dist/commands/skill/index.js.map +1 -0
- package/dist/commands/status/index.d.ts +3 -0
- package/dist/commands/status/index.d.ts.map +1 -0
- package/dist/commands/status/index.js +59 -0
- package/dist/commands/status/index.js.map +1 -0
- package/dist/commands/storage/index.d.ts +3 -0
- package/dist/commands/storage/index.d.ts.map +1 -0
- package/dist/commands/storage/index.js +400 -0
- package/dist/commands/storage/index.js.map +1 -0
- package/dist/commands/tenant/index.d.ts +19 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +667 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/commands/whoami/index.d.ts +3 -0
- package/dist/commands/whoami/index.d.ts.map +1 -0
- package/dist/commands/whoami/index.js +101 -0
- package/dist/commands/whoami/index.js.map +1 -0
- package/dist/credentials/commit.d.ts +38 -0
- package/dist/credentials/commit.d.ts.map +1 -0
- package/dist/credentials/commit.js +57 -0
- package/dist/credentials/commit.js.map +1 -0
- package/dist/credentials/credential-store.d.ts +86 -0
- package/dist/credentials/credential-store.d.ts.map +1 -0
- package/dist/credentials/credential-store.js +282 -0
- package/dist/credentials/credential-store.js.map +1 -0
- package/dist/credentials/env-file.d.ts +85 -0
- package/dist/credentials/env-file.d.ts.map +1 -0
- package/dist/credentials/env-file.js +193 -0
- package/dist/credentials/env-file.js.map +1 -0
- package/dist/credentials/formatter.d.ts +39 -0
- package/dist/credentials/formatter.d.ts.map +1 -0
- package/dist/credentials/formatter.js +79 -0
- package/dist/credentials/formatter.js.map +1 -0
- package/dist/credentials/index.d.ts +13 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +13 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/credentials/jwt-introspect.d.ts +39 -0
- package/dist/credentials/jwt-introspect.d.ts.map +1 -0
- package/dist/credentials/jwt-introspect.js +64 -0
- package/dist/credentials/jwt-introspect.js.map +1 -0
- package/dist/credentials/masker.d.ts +23 -0
- package/dist/credentials/masker.d.ts.map +1 -0
- package/dist/credentials/masker.js +40 -0
- package/dist/credentials/masker.js.map +1 -0
- package/dist/credentials/profile.d.ts +95 -0
- package/dist/credentials/profile.d.ts.map +1 -0
- package/dist/credentials/profile.js +207 -0
- package/dist/credentials/profile.js.map +1 -0
- package/dist/credentials/tenant-guard.d.ts +16 -0
- package/dist/credentials/tenant-guard.d.ts.map +1 -0
- package/dist/credentials/tenant-guard.js +53 -0
- package/dist/credentials/tenant-guard.js.map +1 -0
- package/dist/credentials/tty-guard.d.ts +29 -0
- package/dist/credentials/tty-guard.d.ts.map +1 -0
- package/dist/credentials/tty-guard.js +79 -0
- package/dist/credentials/tty-guard.js.map +1 -0
- package/dist/db/apply-schema.d.ts +144 -0
- package/dist/db/apply-schema.d.ts.map +1 -0
- package/dist/db/apply-schema.js +359 -0
- package/dist/db/apply-schema.js.map +1 -0
- package/dist/db/introspect.d.ts +54 -0
- package/dist/db/introspect.d.ts.map +1 -0
- package/dist/db/introspect.js +140 -0
- package/dist/db/introspect.js.map +1 -0
- package/dist/db/sql-file.d.ts +104 -0
- package/dist/db/sql-file.d.ts.map +1 -0
- package/dist/db/sql-file.js +584 -0
- package/dist/db/sql-file.js.map +1 -0
- package/dist/instance/provision.d.ts +89 -0
- package/dist/instance/provision.d.ts.map +1 -0
- package/dist/instance/provision.js +139 -0
- package/dist/instance/provision.js.map +1 -0
- package/dist/instance/zero-store.d.ts +47 -0
- package/dist/instance/zero-store.d.ts.map +1 -0
- package/dist/instance/zero-store.js +91 -0
- package/dist/instance/zero-store.js.map +1 -0
- package/dist/instance/zero-whitelist.d.ts +39 -0
- package/dist/instance/zero-whitelist.d.ts.map +1 -0
- package/dist/instance/zero-whitelist.js +67 -0
- package/dist/instance/zero-whitelist.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +69 -0
- package/dist/main.js.map +1 -0
- package/dist/skill/agents-md.d.ts +25 -0
- package/dist/skill/agents-md.d.ts.map +1 -0
- package/dist/skill/agents-md.js +62 -0
- package/dist/skill/agents-md.js.map +1 -0
- package/dist/skill/assets.d.ts +38 -0
- package/dist/skill/assets.d.ts.map +1 -0
- package/dist/skill/assets.js +111 -0
- package/dist/skill/assets.js.map +1 -0
- package/dist/skill/hint.d.ts +39 -0
- package/dist/skill/hint.d.ts.map +1 -0
- package/dist/skill/hint.js +109 -0
- package/dist/skill/hint.js.map +1 -0
- package/dist/skill/hosts.d.ts +45 -0
- package/dist/skill/hosts.d.ts.map +1 -0
- package/dist/skill/hosts.js +96 -0
- package/dist/skill/hosts.js.map +1 -0
- package/dist/skill/installer.d.ts +100 -0
- package/dist/skill/installer.d.ts.map +1 -0
- package/dist/skill/installer.js +241 -0
- package/dist/skill/installer.js.map +1 -0
- package/dist/skill/ownership.d.ts +35 -0
- package/dist/skill/ownership.d.ts.map +1 -0
- package/dist/skill/ownership.js +52 -0
- package/dist/skill/ownership.js.map +1 -0
- package/dist/tenant/bundle.d.ts +66 -0
- package/dist/tenant/bundle.d.ts.map +1 -0
- package/dist/tenant/bundle.js +132 -0
- package/dist/tenant/bundle.js.map +1 -0
- package/dist/tenant/guide.d.ts +50 -0
- package/dist/tenant/guide.d.ts.map +1 -0
- package/dist/tenant/guide.js +152 -0
- package/dist/tenant/guide.js.map +1 -0
- package/dist/tenant/probe.d.ts +65 -0
- package/dist/tenant/probe.d.ts.map +1 -0
- package/dist/tenant/probe.js +159 -0
- package/dist/tenant/probe.js.map +1 -0
- package/dist/tenant/verify.d.ts +37 -0
- package/dist/tenant/verify.d.ts.map +1 -0
- package/dist/tenant/verify.js +132 -0
- package/dist/tenant/verify.js.map +1 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +65 -0
- package/dist/version.js.map +1 -0
- package/package.json +63 -3
- package/skills/pxbaas-app-spec/SKILL.md +165 -0
- package/skills/pxbaas-app-spec/references/deploy-options.md +158 -0
- package/skills/pxbaas-app-spec/references/guardrails-pitfalls.md +89 -0
- package/skills/pxbaas-app-spec/references/runtime-contract.md +151 -0
- package/skills/pxbaas-app-spec/references/ssr-session.md +121 -0
- package/skills/pxbaas-app-spec/references/templates-examples.md +311 -0
- package/skills/pxbaas-cli/SKILL.md +186 -0
- package/skills/pxbaas-cli/references/api-reference.md +68 -0
- package/skills/pxbaas-cli/references/app-deploy.md +186 -0
- package/skills/pxbaas-cli/references/auth-and-credentials.md +116 -0
- package/skills/pxbaas-cli/references/data-postgrest.md +101 -0
- package/skills/pxbaas-cli/references/db-and-meta.md +102 -0
- package/skills/pxbaas-cli/references/edge-functions.md +71 -0
- package/skills/pxbaas-cli/references/multi-tenant-apps.md +138 -0
- package/skills/pxbaas-cli/references/provision.md +101 -0
- package/skills/pxbaas-cli/references/safety-and-two-phase.md +78 -0
- package/skills/pxbaas-cli/references/storage.md +61 -0
- package/skills/pxbaas-cli/references/tenant-admin.md +122 -0
- package/skills/pxbaas-cli/references/troubleshooting.md +76 -0
- package/templates/webapp/api/index.ts +55 -0
- package/templates/webapp/csr-bff/README.md +81 -0
- package/templates/webapp/csr-bff/backend/index.ts +168 -0
- package/templates/webapp/csr-bff/db/rls.json +13 -0
- package/templates/webapp/csr-bff/db/schema.sql +49 -0
- package/templates/webapp/csr-bff/frontend/dist/admin.html +101 -0
- package/templates/webapp/csr-bff/frontend/dist/article.html +44 -0
- package/templates/webapp/csr-bff/frontend/dist/blog.js +206 -0
- package/templates/webapp/csr-bff/frontend/dist/blogger.html +53 -0
- package/templates/webapp/csr-bff/frontend/dist/index.html +70 -0
- package/templates/webapp/csr-bff/frontend/dist/login.html +56 -0
- package/templates/webapp/csr-bff/frontend/dist/profile.html +59 -0
- package/templates/webapp/csr-bff/frontend/dist/signup.html +78 -0
- package/templates/webapp/csr-bff/frontend/dist/style.css +27 -0
- package/templates/webapp/manifest.json +419 -0
- package/templates/webapp/mpa/about.html +29 -0
- package/templates/webapp/mpa/app.js +42 -0
- package/templates/webapp/mpa/index.html +42 -0
- package/templates/webapp/mpa/index.ts +60 -0
- package/templates/webapp/mpa/style.css +42 -0
- package/templates/webapp/react-vite/frontend/index.html +12 -0
- package/templates/webapp/react-vite/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite/frontend/package.json +23 -0
- package/templates/webapp/react-vite/frontend/src/App.tsx +34 -0
- package/templates/webapp/react-vite/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite/frontend/src/style.css +46 -0
- package/templates/webapp/react-vite/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite/frontend/vite.config.ts +10 -0
- package/templates/webapp/react-vite-hono/backend/index.ts +38 -0
- package/templates/webapp/react-vite-hono/frontend/index.html +12 -0
- package/templates/webapp/react-vite-hono/frontend/package-lock.json +1826 -0
- package/templates/webapp/react-vite-hono/frontend/package.json +23 -0
- package/templates/webapp/react-vite-hono/frontend/src/App.tsx +47 -0
- package/templates/webapp/react-vite-hono/frontend/src/main.tsx +13 -0
- package/templates/webapp/react-vite-hono/frontend/src/style.css +66 -0
- package/templates/webapp/react-vite-hono/frontend/tsconfig.json +20 -0
- package/templates/webapp/react-vite-hono/frontend/vite.config.ts +10 -0
- package/templates/webapp/spa/index.ts +119 -0
- package/templates/webapp/ssr-auth/backend/index.ts +133 -0
- package/templates/webapp/ssr-auth/frontend/dist/index.html +15 -0
- package/templates/webapp/ssr-blog/README.md +111 -0
- package/templates/webapp/ssr-blog/backend/index.ts +764 -0
- package/templates/webapp/ssr-blog/db/rls.json +13 -0
- package/templates/webapp/ssr-blog/db/schema.sql +51 -0
- package/templates/webapp/ssr-blog/frontend/dist/index.html +39 -0
- package/templates/webapp/ssr-frameworks/README.md +64 -0
- package/templates/webapp/ssr-frameworks/backend/index.ts +241 -0
- package/templates/webapp/ssr-frameworks/frontend/dist/index.html +31 -0
- package/templates/webapp/ssr-hono/backend/index.ts +111 -0
- package/templates/webapp/ssr-hono/frontend/dist/index.html +12 -0
- package/templates/webapp/ssr-shop/README.md +80 -0
- package/templates/webapp/ssr-shop/backend/index.ts +491 -0
- package/templates/webapp/ssr-shop/db/rls.json +16 -0
- package/templates/webapp/ssr-shop/db/schema.sql +90 -0
- package/templates/webapp/ssr-shop/frontend/dist/index.html +12 -0
- package/templates/webapp/vanilla-static/frontend/dist/app.js +6 -0
- package/templates/webapp/vanilla-static/frontend/dist/index.html +19 -0
- package/templates/webapp/vanilla-static/frontend/dist/style.css +43 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>MPA Blog — 注册新博主</title>
|
|
7
|
+
<link rel="stylesheet" href="./style.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<nav><a href="./index.html">← 返回广场</a></nav>
|
|
11
|
+
<h1>注册新博主</h1>
|
|
12
|
+
<div class="card">
|
|
13
|
+
<input id="email" type="email" placeholder="邮箱" autocomplete="username">
|
|
14
|
+
<input id="password" type="password" placeholder="密码(≥6 位)" autocomplete="new-password">
|
|
15
|
+
<input id="password2" type="password" placeholder="确认密码" autocomplete="new-password">
|
|
16
|
+
<div class="row">
|
|
17
|
+
<button id="signup">注册</button>
|
|
18
|
+
<span class="muted">已有账号?<a href="./login.html">去登录</a></span>
|
|
19
|
+
</div>
|
|
20
|
+
<div id="msg" class="muted"></div>
|
|
21
|
+
</div>
|
|
22
|
+
<script src="./blog.js"></script>
|
|
23
|
+
<script>
|
|
24
|
+
var msg = document.getElementById('msg');
|
|
25
|
+
var btn = document.getElementById('signup');
|
|
26
|
+
var emailEl = document.getElementById('email');
|
|
27
|
+
var pwEl = document.getElementById('password');
|
|
28
|
+
var pw2El = document.getElementById('password2');
|
|
29
|
+
|
|
30
|
+
function finish(j) {
|
|
31
|
+
BLOG.setToken(j.access_token);
|
|
32
|
+
BLOG.setMeta((j.user && j.user.user_metadata) || {});
|
|
33
|
+
location.href = './profile.html';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function doSignup() {
|
|
37
|
+
if (btn.disabled) return;
|
|
38
|
+
var email = emailEl.value.trim();
|
|
39
|
+
var pw = pwEl.value;
|
|
40
|
+
var pw2 = pw2El.value;
|
|
41
|
+
msg.className = 'muted';
|
|
42
|
+
if (!email || pw.length < 6) { msg.className = 'error'; msg.textContent = '邮箱必填、密码至少 6 位'; return; }
|
|
43
|
+
if (pw !== pw2) { msg.className = 'error'; msg.textContent = '两次密码不一致'; return; }
|
|
44
|
+
msg.textContent = '注册中…';
|
|
45
|
+
btn.disabled = true;
|
|
46
|
+
BLOG.signup(email, pw).then(function (r) {
|
|
47
|
+
return r.json().catch(function () { return {}; }).then(function (j) {
|
|
48
|
+
if ((!r.ok && r.status !== 201)) {
|
|
49
|
+
msg.className = 'error'; msg.textContent = BLOG.authError(j, r.status); btn.disabled = false; return;
|
|
50
|
+
}
|
|
51
|
+
// 免邮箱验证时 signup 直接返回 access_token;否则回退到登录。
|
|
52
|
+
if (j.access_token) { finish(j); return; }
|
|
53
|
+
msg.textContent = '注册成功,正在登录…';
|
|
54
|
+
return BLOG.login(email, pw).then(function (r2) {
|
|
55
|
+
return r2.json().catch(function () { return {}; }).then(function (j2) {
|
|
56
|
+
if (!r2.ok || !j2.access_token) {
|
|
57
|
+
msg.className = 'error';
|
|
58
|
+
msg.textContent = '注册成功但自动登录失败:' + BLOG.authError(j2, r2.status) + ',请前往登录页重试。';
|
|
59
|
+
btn.disabled = false; return;
|
|
60
|
+
}
|
|
61
|
+
finish(j2);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}).catch(function (e) { msg.className = 'error'; msg.textContent = String(e); btn.disabled = false; });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
BLOG.init().then(function () { return BLOG.me(); }).then(function (m) {
|
|
69
|
+
if (m && m.user) { location.replace('./admin.html'); return; }
|
|
70
|
+
btn.onclick = doSignup;
|
|
71
|
+
[emailEl, pwEl, pw2El].forEach(function (el) {
|
|
72
|
+
el.addEventListener('keydown', function (ev) { if (ev.key === 'Enter') { ev.preventDefault(); doSignup(); } });
|
|
73
|
+
});
|
|
74
|
+
emailEl.focus();
|
|
75
|
+
});
|
|
76
|
+
</script>
|
|
77
|
+
</body>
|
|
78
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
* { box-sizing: border-box; }
|
|
2
|
+
body { margin: 0 auto; max-width: 780px; padding: 24px; font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; background: #0f1115; color: #e6e6e6; }
|
|
3
|
+
h1 { font-size: 24px; }
|
|
4
|
+
h2 { font-size: 20px; }
|
|
5
|
+
a { color: #7fb9ff; text-decoration: none; }
|
|
6
|
+
a:hover { text-decoration: underline; }
|
|
7
|
+
nav { margin: 12px 0 20px; display: flex; gap: 16px; align-items: center; }
|
|
8
|
+
nav .spacer { flex: 1; }
|
|
9
|
+
.muted { color: #9aa0a6; font-size: 13px; }
|
|
10
|
+
.card { background: #1a1d24; border: 1px solid #2a2e37; border-radius: 10px; padding: 16px; margin: 12px 0; }
|
|
11
|
+
.row { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
|
|
12
|
+
.badge { font-size: 12px; padding: 2px 8px; border-radius: 999px; border: 1px solid #2a2e37; }
|
|
13
|
+
.badge.draft { color: #e6c07b; }
|
|
14
|
+
.badge.published { color: #98c379; }
|
|
15
|
+
p.content { white-space: pre-wrap; line-height: 1.7; margin: 8px 0; }
|
|
16
|
+
input, textarea, select { width: 100%; background: #0f1115; color: #e6e6e6; border: 1px solid #2a2e37; border-radius: 8px; padding: 10px; font: inherit; margin: 6px 0; }
|
|
17
|
+
button { background: #2f6fed; color: #fff; border: 0; border-radius: 8px; padding: 9px 16px; font: inherit; cursor: pointer; }
|
|
18
|
+
button:disabled { opacity: .6; cursor: not-allowed; }
|
|
19
|
+
button.danger { background: #b3261e; padding: 6px 12px; font-size: 13px; }
|
|
20
|
+
button.ghost { background: #2a2e37; padding: 6px 12px; font-size: 13px; }
|
|
21
|
+
.banner { background: #3a2f14; border: 1px solid #7a6122; color: #ffd97a; border-radius: 10px; padding: 10px 14px; margin: 12px 0; font-size: 14px; }
|
|
22
|
+
.error { color: #ff8a80; font-size: 14px; margin: 8px 0; }
|
|
23
|
+
.card.blogger h2 { font-size: 18px; margin: 0; }
|
|
24
|
+
a.more { white-space: nowrap; font-size: 14px; }
|
|
25
|
+
ul.postlist { list-style: none; padding: 0; margin: 0; }
|
|
26
|
+
ul.postlist li { padding: 6px 0; border-top: 1px solid #2a2e37; }
|
|
27
|
+
ul.postlist li:first-child { border-top: 0; }
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"templates": [
|
|
4
|
+
{
|
|
5
|
+
"id": "spa",
|
|
6
|
+
"meta": {
|
|
7
|
+
"delivery": "legacy",
|
|
8
|
+
"render": "csr",
|
|
9
|
+
"frontend": "inline",
|
|
10
|
+
"backend": "none",
|
|
11
|
+
"session": "none",
|
|
12
|
+
"hasDb": false,
|
|
13
|
+
"coldStart": "light",
|
|
14
|
+
"purpose": "legacy-demo"
|
|
15
|
+
},
|
|
16
|
+
"description": "Self-contained single-page webapp: inline HTML/CSS/JS + a built-in JSON API via ?action=. Best for shareable demos.",
|
|
17
|
+
"entrypoint": "index.ts"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "api",
|
|
21
|
+
"meta": {
|
|
22
|
+
"delivery": "legacy",
|
|
23
|
+
"render": "headless",
|
|
24
|
+
"frontend": "none",
|
|
25
|
+
"backend": "none",
|
|
26
|
+
"session": "none",
|
|
27
|
+
"hasDb": false,
|
|
28
|
+
"coldStart": "light",
|
|
29
|
+
"purpose": "legacy-demo"
|
|
30
|
+
},
|
|
31
|
+
"description": "Headless JSON backend (Deno.serve) with ?action= routing and CORS. Best for webhooks / API-only demos.",
|
|
32
|
+
"entrypoint": "index.ts"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "mpa",
|
|
36
|
+
"meta": {
|
|
37
|
+
"delivery": "legacy",
|
|
38
|
+
"render": "static",
|
|
39
|
+
"frontend": "html",
|
|
40
|
+
"backend": "none",
|
|
41
|
+
"session": "none",
|
|
42
|
+
"hasDb": false,
|
|
43
|
+
"coldStart": "light",
|
|
44
|
+
"purpose": "legacy-demo"
|
|
45
|
+
},
|
|
46
|
+
"description": "Multi-page static webapp: real index.html/about.html/style.css/app.js served by path via the proxy static branch, plus a worker JSON API via ?action=. Best for traditional multi-page sites.",
|
|
47
|
+
"entrypoint": "index.ts",
|
|
48
|
+
"mode": "mpa",
|
|
49
|
+
"files": [
|
|
50
|
+
"index.ts",
|
|
51
|
+
"index.html",
|
|
52
|
+
"about.html",
|
|
53
|
+
"style.css",
|
|
54
|
+
"app.js"
|
|
55
|
+
],
|
|
56
|
+
"pages": [
|
|
57
|
+
"index.html",
|
|
58
|
+
"about.html"
|
|
59
|
+
],
|
|
60
|
+
"assets": [
|
|
61
|
+
"style.css",
|
|
62
|
+
"app.js"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "vanilla-static",
|
|
67
|
+
"meta": {
|
|
68
|
+
"delivery": "webapp",
|
|
69
|
+
"render": "static",
|
|
70
|
+
"frontend": "vanilla",
|
|
71
|
+
"backend": "none",
|
|
72
|
+
"session": "none",
|
|
73
|
+
"hasDb": false,
|
|
74
|
+
"coldStart": "light",
|
|
75
|
+
"purpose": "validation"
|
|
76
|
+
},
|
|
77
|
+
"description": "Minimal text-only static app for validating the /apps mount and release lifecycle. Editable files live in frontend/dist, which is also the artifact directory deploy uploads.",
|
|
78
|
+
"entrypoint": "frontend/dist/index.html",
|
|
79
|
+
"mode": "webapp",
|
|
80
|
+
"files": [
|
|
81
|
+
"frontend/dist/index.html",
|
|
82
|
+
"frontend/dist/style.css",
|
|
83
|
+
"frontend/dist/app.js"
|
|
84
|
+
],
|
|
85
|
+
"frontend": {
|
|
86
|
+
"root": "frontend/dist",
|
|
87
|
+
"routing": "files",
|
|
88
|
+
"index": "index.html",
|
|
89
|
+
"fallback": null
|
|
90
|
+
},
|
|
91
|
+
"backend": null
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "react-vite",
|
|
95
|
+
"meta": {
|
|
96
|
+
"delivery": "webapp",
|
|
97
|
+
"render": "csr",
|
|
98
|
+
"frontend": "react",
|
|
99
|
+
"backend": "none",
|
|
100
|
+
"session": "none",
|
|
101
|
+
"hasDb": false,
|
|
102
|
+
"coldStart": "light",
|
|
103
|
+
"purpose": "starter"
|
|
104
|
+
},
|
|
105
|
+
"description": "React + Vite static app with HashRouter, relative base, plain CSS, and exact dependency versions.",
|
|
106
|
+
"entrypoint": "frontend/src/App.tsx",
|
|
107
|
+
"mode": "webapp",
|
|
108
|
+
"files": [
|
|
109
|
+
"frontend/package.json",
|
|
110
|
+
"frontend/package-lock.json",
|
|
111
|
+
"frontend/index.html",
|
|
112
|
+
"frontend/tsconfig.json",
|
|
113
|
+
"frontend/vite.config.ts",
|
|
114
|
+
"frontend/src/main.tsx",
|
|
115
|
+
"frontend/src/App.tsx",
|
|
116
|
+
"frontend/src/style.css"
|
|
117
|
+
],
|
|
118
|
+
"frontend": {
|
|
119
|
+
"root": "frontend/dist",
|
|
120
|
+
"routing": "files",
|
|
121
|
+
"index": "index.html",
|
|
122
|
+
"fallback": null
|
|
123
|
+
},
|
|
124
|
+
"backend": null
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "react-vite-hono",
|
|
128
|
+
"meta": {
|
|
129
|
+
"delivery": "webapp",
|
|
130
|
+
"render": "csr",
|
|
131
|
+
"frontend": "react",
|
|
132
|
+
"backend": "hono",
|
|
133
|
+
"session": "none",
|
|
134
|
+
"hasDb": false,
|
|
135
|
+
"coldStart": "light",
|
|
136
|
+
"purpose": "starter"
|
|
137
|
+
},
|
|
138
|
+
"description": "React + Vite + HashRouter frontend with a Deno-served, platform-versioned Hono backend.",
|
|
139
|
+
"entrypoint": "backend/index.ts",
|
|
140
|
+
"mode": "webapp",
|
|
141
|
+
"files": [
|
|
142
|
+
"frontend/package.json",
|
|
143
|
+
"frontend/package-lock.json",
|
|
144
|
+
"frontend/index.html",
|
|
145
|
+
"frontend/tsconfig.json",
|
|
146
|
+
"frontend/vite.config.ts",
|
|
147
|
+
"frontend/src/main.tsx",
|
|
148
|
+
"frontend/src/App.tsx",
|
|
149
|
+
"frontend/src/style.css",
|
|
150
|
+
"backend/index.ts"
|
|
151
|
+
],
|
|
152
|
+
"frontend": {
|
|
153
|
+
"root": "frontend/dist",
|
|
154
|
+
"routing": "files",
|
|
155
|
+
"index": "index.html",
|
|
156
|
+
"fallback": null
|
|
157
|
+
},
|
|
158
|
+
"backend": {
|
|
159
|
+
"entrypoint": "backend/index.ts",
|
|
160
|
+
"framework": "hono",
|
|
161
|
+
"pathMode": "strip-app-api-prefix",
|
|
162
|
+
"verifyJwt": false,
|
|
163
|
+
"secrets": [],
|
|
164
|
+
"egressPolicy": "deny"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "ssr-hono",
|
|
169
|
+
"meta": {
|
|
170
|
+
"delivery": "webapp",
|
|
171
|
+
"render": "ssr",
|
|
172
|
+
"frontend": "static-shell",
|
|
173
|
+
"backend": "hono",
|
|
174
|
+
"session": "none",
|
|
175
|
+
"hasDb": false,
|
|
176
|
+
"coldStart": "moderate",
|
|
177
|
+
"purpose": "starter"
|
|
178
|
+
},
|
|
179
|
+
"description": "SSR-shell webapp: Hono worker server-renders the page shell at /page (static-miss fallthrough, fallback=worker); browser hydrates and fetches data client-side. Single-file self-contained worker per D16.",
|
|
180
|
+
"entrypoint": "backend/index.ts",
|
|
181
|
+
"mode": "webapp",
|
|
182
|
+
"files": [
|
|
183
|
+
"backend/index.ts",
|
|
184
|
+
"frontend/dist/index.html"
|
|
185
|
+
],
|
|
186
|
+
"frontend": {
|
|
187
|
+
"root": "frontend/dist",
|
|
188
|
+
"routing": "files",
|
|
189
|
+
"index": "index.html",
|
|
190
|
+
"fallback": "worker"
|
|
191
|
+
},
|
|
192
|
+
"backend": {
|
|
193
|
+
"entrypoint": "backend/index.ts",
|
|
194
|
+
"framework": "hono",
|
|
195
|
+
"pathMode": "strip-app-api-prefix",
|
|
196
|
+
"verifyJwt": false,
|
|
197
|
+
"secrets": [],
|
|
198
|
+
"egressPolicy": "deny"
|
|
199
|
+
},
|
|
200
|
+
"ssrProbePath": "/page"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"id": "ssr-auth",
|
|
204
|
+
"meta": {
|
|
205
|
+
"delivery": "webapp",
|
|
206
|
+
"render": "ssr",
|
|
207
|
+
"frontend": "static-shell",
|
|
208
|
+
"backend": "deno",
|
|
209
|
+
"session": "proxy-injected",
|
|
210
|
+
"hasDb": false,
|
|
211
|
+
"coldStart": "light",
|
|
212
|
+
"purpose": "reference"
|
|
213
|
+
},
|
|
214
|
+
"description": "SSR webapp with proxy-injected session (方案 C): the worker server-renders authenticated pages from trusted X-App-User-* headers; it never reads cookies, never sets Set-Cookie, and never puts tokens in URLs. Requires capabilities.sessionMode=proxy-injected-header.",
|
|
215
|
+
"entrypoint": "backend/index.ts",
|
|
216
|
+
"mode": "webapp",
|
|
217
|
+
"files": [
|
|
218
|
+
"backend/index.ts",
|
|
219
|
+
"frontend/dist/index.html"
|
|
220
|
+
],
|
|
221
|
+
"frontend": {
|
|
222
|
+
"root": "frontend/dist",
|
|
223
|
+
"routing": "files",
|
|
224
|
+
"index": "index.html",
|
|
225
|
+
"fallback": null
|
|
226
|
+
},
|
|
227
|
+
"backend": {
|
|
228
|
+
"entrypoint": "backend/index.ts",
|
|
229
|
+
"framework": "deno",
|
|
230
|
+
"pathMode": "strip-app-api-prefix",
|
|
231
|
+
"verifyJwt": false,
|
|
232
|
+
"secrets": [],
|
|
233
|
+
"egressPolicy": "deny",
|
|
234
|
+
"session": "proxy-injected"
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"id": "ssr-blog",
|
|
239
|
+
"meta": {
|
|
240
|
+
"delivery": "webapp",
|
|
241
|
+
"render": "ssr",
|
|
242
|
+
"frontend": "static-shell",
|
|
243
|
+
"backend": "deno",
|
|
244
|
+
"session": "proxy-injected",
|
|
245
|
+
"hasDb": true,
|
|
246
|
+
"coldStart": "light",
|
|
247
|
+
"purpose": "reference"
|
|
248
|
+
},
|
|
249
|
+
"description": "Full-site SSR blog (zero npm deps) with proxy-injected session: the worker renders every page server-side from the instance internal base and reads identity ONLY from X-App-User-* headers. Requires capabilities.sessionMode=proxy-injected-header.",
|
|
250
|
+
"entrypoint": "backend/index.ts",
|
|
251
|
+
"mode": "webapp",
|
|
252
|
+
"files": [
|
|
253
|
+
"README.md",
|
|
254
|
+
"backend/index.ts",
|
|
255
|
+
"db/schema.sql",
|
|
256
|
+
"db/rls.json",
|
|
257
|
+
"frontend/dist/index.html"
|
|
258
|
+
],
|
|
259
|
+
"frontend": {
|
|
260
|
+
"root": "frontend/dist",
|
|
261
|
+
"routing": "files",
|
|
262
|
+
"index": "index.html",
|
|
263
|
+
"fallback": "worker"
|
|
264
|
+
},
|
|
265
|
+
"backend": {
|
|
266
|
+
"entrypoint": "backend/index.ts",
|
|
267
|
+
"framework": "deno",
|
|
268
|
+
"pathMode": "strip-app-api-prefix",
|
|
269
|
+
"verifyJwt": false,
|
|
270
|
+
"secrets": [],
|
|
271
|
+
"egressPolicy": "deny",
|
|
272
|
+
"session": "proxy-injected"
|
|
273
|
+
},
|
|
274
|
+
"ssrProbePath": "/posts",
|
|
275
|
+
"nextSteps": [
|
|
276
|
+
"Initialize the database BEFORE deploy: run `pxbaas app db-init <name> --dir <appsDir>`. It reads db/schema.sql (DDL + seed) and db/rls.json (RLS registry), shows the full plan, and applies it only after you authorize (--dry-run to preview, --yes for non-interactive). Works in single-tenant (/pg/query) AND multi-tenant (/api/tenant-ddl with your per-tenant service_role key); the CLI never auto-runs DDL.",
|
|
277
|
+
"Requires capabilities.sessionMode=proxy-injected-header.",
|
|
278
|
+
"Data-plane base and anon key come from the platform-in SUPABASE_INTERNAL_URL / SUPABASE_ANON_KEY (edge-runtime MR #30497903); no plaintext key editing is needed."
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"id": "csr-bff",
|
|
283
|
+
"meta": {
|
|
284
|
+
"delivery": "webapp",
|
|
285
|
+
"render": "csr",
|
|
286
|
+
"frontend": "html",
|
|
287
|
+
"backend": "deno",
|
|
288
|
+
"session": "proxy-injected",
|
|
289
|
+
"hasDb": true,
|
|
290
|
+
"coldStart": "light",
|
|
291
|
+
"purpose": "reference"
|
|
292
|
+
},
|
|
293
|
+
"description": "Front/back separated CSR blog: real static pages served by path plus a same-origin Deno BFF worker that proxies /api/* to the instance internal REST/Auth. Identity comes from proxy-injected X-App-User-Token (client Authorization is stripped on /apps).",
|
|
294
|
+
"entrypoint": "backend/index.ts",
|
|
295
|
+
"mode": "webapp",
|
|
296
|
+
"files": [
|
|
297
|
+
"README.md",
|
|
298
|
+
"backend/index.ts",
|
|
299
|
+
"db/schema.sql",
|
|
300
|
+
"db/rls.json",
|
|
301
|
+
"frontend/dist/admin.html",
|
|
302
|
+
"frontend/dist/article.html",
|
|
303
|
+
"frontend/dist/blog.js",
|
|
304
|
+
"frontend/dist/blogger.html",
|
|
305
|
+
"frontend/dist/index.html",
|
|
306
|
+
"frontend/dist/login.html",
|
|
307
|
+
"frontend/dist/profile.html",
|
|
308
|
+
"frontend/dist/signup.html",
|
|
309
|
+
"frontend/dist/style.css"
|
|
310
|
+
],
|
|
311
|
+
"frontend": {
|
|
312
|
+
"root": "frontend/dist",
|
|
313
|
+
"routing": "files",
|
|
314
|
+
"index": "index.html",
|
|
315
|
+
"fallback": null
|
|
316
|
+
},
|
|
317
|
+
"backend": {
|
|
318
|
+
"entrypoint": "backend/index.ts",
|
|
319
|
+
"framework": "deno",
|
|
320
|
+
"pathMode": "strip-app-api-prefix",
|
|
321
|
+
"verifyJwt": false,
|
|
322
|
+
"secrets": [],
|
|
323
|
+
"egressPolicy": "deny",
|
|
324
|
+
"session": "proxy-injected"
|
|
325
|
+
},
|
|
326
|
+
"nextSteps": [
|
|
327
|
+
"Initialize the database BEFORE deploy: run `pxbaas app db-init <name> --dir <appsDir>`. It reads db/schema.sql (DDL + seed) and db/rls.json (RLS registry), shows the full plan, and applies it only after you authorize (--dry-run to preview, --yes for non-interactive). Works in single-tenant (/pg/query) AND multi-tenant (/api/tenant-ddl with your per-tenant service_role key); the CLI never auto-runs DDL.",
|
|
328
|
+
"Requires capabilities.sessionMode=proxy-injected-header.",
|
|
329
|
+
"The BFF forwards to the platform-injected SUPABASE_INTERNAL_URL with SUPABASE_ANON_KEY (edge-runtime MR #30497903); no plaintext key editing is needed."
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"id": "ssr-shop",
|
|
334
|
+
"meta": {
|
|
335
|
+
"delivery": "webapp",
|
|
336
|
+
"render": "ssr",
|
|
337
|
+
"frontend": "react",
|
|
338
|
+
"backend": "hono",
|
|
339
|
+
"session": "browser-side",
|
|
340
|
+
"hasDb": true,
|
|
341
|
+
"coldStart": "moderate",
|
|
342
|
+
"purpose": "reference"
|
|
343
|
+
},
|
|
344
|
+
"description": "React 18 + Hono SSR shop: catalog/detail/search are fully server-rendered from MySQL; cart/checkout/orders hydrate in the browser. Browser-side session (localStorage + Authorization direct to /rest,/auth); order gating enforced by RLS.",
|
|
345
|
+
"entrypoint": "backend/index.ts",
|
|
346
|
+
"mode": "webapp",
|
|
347
|
+
"files": [
|
|
348
|
+
"README.md",
|
|
349
|
+
"backend/index.ts",
|
|
350
|
+
"db/schema.sql",
|
|
351
|
+
"db/rls.json",
|
|
352
|
+
"frontend/dist/index.html"
|
|
353
|
+
],
|
|
354
|
+
"frontend": {
|
|
355
|
+
"root": "frontend/dist",
|
|
356
|
+
"routing": "files",
|
|
357
|
+
"index": "index.html",
|
|
358
|
+
"fallback": "worker"
|
|
359
|
+
},
|
|
360
|
+
"backend": {
|
|
361
|
+
"entrypoint": "backend/index.ts",
|
|
362
|
+
"framework": "hono",
|
|
363
|
+
"pathMode": "strip-app-api-prefix",
|
|
364
|
+
"verifyJwt": false,
|
|
365
|
+
"secrets": [],
|
|
366
|
+
"egressPolicy": "deny",
|
|
367
|
+
"session": "browser-side"
|
|
368
|
+
},
|
|
369
|
+
"ssrProbePath": "/shop",
|
|
370
|
+
"nextSteps": [
|
|
371
|
+
"Initialize the database BEFORE deploy: run `pxbaas app db-init <name> --dir <appsDir>`. It reads db/schema.sql (DDL + seed) and db/rls.json (RLS: products public-read; orders and order_items owner-gated by buyer_email = jwt.email), shows the full plan, and applies it only after you authorize (--dry-run to preview, --yes for non-interactive). Works in single-tenant (/pg/query) AND multi-tenant (/api/tenant-ddl with your per-tenant service_role key); the CLI never auto-runs DDL.",
|
|
372
|
+
"Create the admin account (admin@shop.demo) via GoTrue signup if the admin whitelist is needed.",
|
|
373
|
+
"Data-plane base and anon key come from the platform-injected SUPABASE_INTERNAL_URL / SUPABASE_ANON_KEY (edge-runtime MR #30497903); no plaintext key editing is needed. Requires the instance to report react/react-dom in capabilities.ssrLibs."
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"id": "ssr-frameworks",
|
|
378
|
+
"meta": {
|
|
379
|
+
"delivery": "webapp",
|
|
380
|
+
"render": "ssr",
|
|
381
|
+
"frontend": "static-shell",
|
|
382
|
+
"backend": "hono",
|
|
383
|
+
"session": "none",
|
|
384
|
+
"hasDb": false,
|
|
385
|
+
"coldStart": "heavy",
|
|
386
|
+
"purpose": "showcase"
|
|
387
|
+
},
|
|
388
|
+
"description": "Four-framework SSR showcase (React / Vue / Preact / Solid on Hono) rendering the same UI spec server-side, plus /compare. No data plane and no credentials; heaviest cold start of the set (~60s), so warm the tenant sandbox before publish.",
|
|
389
|
+
"entrypoint": "backend/index.ts",
|
|
390
|
+
"mode": "webapp",
|
|
391
|
+
"files": [
|
|
392
|
+
"README.md",
|
|
393
|
+
"backend/index.ts",
|
|
394
|
+
"frontend/dist/index.html"
|
|
395
|
+
],
|
|
396
|
+
"frontend": {
|
|
397
|
+
"root": "frontend/dist",
|
|
398
|
+
"routing": "files",
|
|
399
|
+
"index": "index.html",
|
|
400
|
+
"fallback": "worker"
|
|
401
|
+
},
|
|
402
|
+
"backend": {
|
|
403
|
+
"entrypoint": "backend/index.ts",
|
|
404
|
+
"framework": "hono",
|
|
405
|
+
"pathMode": "strip-app-api-prefix",
|
|
406
|
+
"verifyJwt": false,
|
|
407
|
+
"secrets": [],
|
|
408
|
+
"egressPolicy": "deny",
|
|
409
|
+
"session": "none"
|
|
410
|
+
},
|
|
411
|
+
"ssrProbePath": "/react",
|
|
412
|
+
"nextSteps": [
|
|
413
|
+
"No data plane and no credentials are required.",
|
|
414
|
+
"Heaviest cold start of the set (~60s with four SSR renderers): warm the tenant sandbox before publish and retry APP_SSR_PROBE_FAILED 3-5 times.",
|
|
415
|
+
"Requires the instance to report react/react-dom, vue/@vue/server-renderer, preact/preact-render-to-string and solid-js in capabilities.ssrLibs, else deploy is blocked by no-remote-import / ssr-lib-not-allowed."
|
|
416
|
+
]
|
|
417
|
+
}
|
|
418
|
+
]
|
|
419
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>{{APP_NAME}} — About</title>
|
|
7
|
+
<link rel="stylesheet" href="style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<h1>About {{APP_NAME}}</h1>
|
|
11
|
+
<nav class="nav">
|
|
12
|
+
<a href="index.html">Home</a> · <a href="about.html">About</a>
|
|
13
|
+
</nav>
|
|
14
|
+
|
|
15
|
+
<div class="card">
|
|
16
|
+
<p>
|
|
17
|
+
This is a second static page (<code>about.html</code>). Navigating here from
|
|
18
|
+
the home page uses a plain relative link — no client-side router, no
|
|
19
|
+
single-file bundle. Each page is a real file served by path.
|
|
20
|
+
</p>
|
|
21
|
+
<p class="muted">
|
|
22
|
+
Add more pages by dropping new <code>.html</code> files into the app
|
|
23
|
+
directory and listing them under <code>pages</code> in <code>app.json</code>.
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<script src="app.js"></script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// {{APP_NAME}} — shared client script (MPA). Runs in the BROWSER on every page.
|
|
2
|
+
//
|
|
3
|
+
// Guardrails:
|
|
4
|
+
// - Asset links in the HTML are relative; here the API call uses a COMPUTED base
|
|
5
|
+
// (the function directory) + "?action=..." so the request returns through
|
|
6
|
+
// Kong -> proxy -> sandbox on the same /functions/v1/{{SLUG}}/ path and never
|
|
7
|
+
// escapes the prefix.
|
|
8
|
+
// - Defensive element lookups: the same script is included on every page, and
|
|
9
|
+
// not every page has every widget.
|
|
10
|
+
(function () {
|
|
11
|
+
// Directory of the current page, e.g. /functions/v1/{{SLUG}}/
|
|
12
|
+
var base = location.pathname.endsWith("/")
|
|
13
|
+
? location.pathname
|
|
14
|
+
: location.pathname.replace(/\/[^/]*$/, "/");
|
|
15
|
+
|
|
16
|
+
var urlEl = document.getElementById("url");
|
|
17
|
+
if (urlEl) urlEl.textContent = location.origin + base;
|
|
18
|
+
|
|
19
|
+
var n = 0;
|
|
20
|
+
var countEl = document.getElementById("count");
|
|
21
|
+
var incBtn = document.getElementById("inc");
|
|
22
|
+
if (incBtn) {
|
|
23
|
+
incBtn.addEventListener("click", function () {
|
|
24
|
+
n++;
|
|
25
|
+
if (countEl) countEl.textContent = String(n);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var pingBtn = document.getElementById("ping");
|
|
30
|
+
var apiEl = document.getElementById("api");
|
|
31
|
+
if (pingBtn) {
|
|
32
|
+
pingBtn.addEventListener("click", async function () {
|
|
33
|
+
if (apiEl) apiEl.textContent = "loading…";
|
|
34
|
+
try {
|
|
35
|
+
var r = await fetch(base + "?action=time", { headers: { Accept: "application/json" } });
|
|
36
|
+
if (apiEl) apiEl.textContent = JSON.stringify(await r.json(), null, 2);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
if (apiEl) apiEl.textContent = "error: " + e;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
})();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>{{APP_NAME}}</title>
|
|
7
|
+
<!-- RELATIVE asset link: resolves to /functions/v1/{{SLUG}}/style.css -->
|
|
8
|
+
<link rel="stylesheet" href="style.css" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<h1>{{APP_NAME}}</h1>
|
|
12
|
+
<nav class="nav">
|
|
13
|
+
<a href="index.html">Home</a> · <a href="about.html">About</a>
|
|
14
|
+
</nav>
|
|
15
|
+
|
|
16
|
+
<p class="muted">
|
|
17
|
+
A multi-page webapp: <code>index.html</code>, <code>about.html</code>,
|
|
18
|
+
<code>style.css</code> and <code>app.js</code> are served as real static files
|
|
19
|
+
by the BaaS proxy, reverse-proxied via Kong <code>/functions/v1/</code>.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<div class="card">
|
|
23
|
+
<div class="muted">Share URL (opens directly in a browser)</div>
|
|
24
|
+
<code id="url">loading…</code>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div class="card">
|
|
28
|
+
<div>① Client-side counter (from <code>app.js</code>)</div>
|
|
29
|
+
<div class="big" id="count">0</div>
|
|
30
|
+
<button id="inc">+1</button>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="card">
|
|
34
|
+
<div>② Call the worker API (computed base + <code>?action=time</code>)</div>
|
|
35
|
+
<button id="ping">GET ?action=time</button>
|
|
36
|
+
<pre id="api" class="muted">Click to fetch server time</pre>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<!-- RELATIVE script src: resolves to /functions/v1/{{SLUG}}/app.js -->
|
|
40
|
+
<script src="app.js"></script>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|