@polardbx/pxbaas 0.0.0-stage → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +107 -2
  2. package/bin/pxbaas.js +13 -0
  3. package/dist/app/preflight.d.ts +38 -0
  4. package/dist/app/preflight.d.ts.map +1 -0
  5. package/dist/app/preflight.js +79 -0
  6. package/dist/app/preflight.js.map +1 -0
  7. package/dist/app/spec-lint.d.ts +45 -0
  8. package/dist/app/spec-lint.d.ts.map +1 -0
  9. package/dist/app/spec-lint.js +407 -0
  10. package/dist/app/spec-lint.js.map +1 -0
  11. package/dist/app/templates.d.ts +143 -0
  12. package/dist/app/templates.d.ts.map +1 -0
  13. package/dist/app/templates.js +151 -0
  14. package/dist/app/templates.js.map +1 -0
  15. package/dist/cli/root.d.ts +3 -0
  16. package/dist/cli/root.d.ts.map +1 -0
  17. package/dist/cli/root.js +69 -0
  18. package/dist/cli/root.js.map +1 -0
  19. package/dist/commands/app/index.d.ts +8 -0
  20. package/dist/commands/app/index.d.ts.map +1 -0
  21. package/dist/commands/app/index.js +1476 -0
  22. package/dist/commands/app/index.js.map +1 -0
  23. package/dist/commands/auth/index.d.ts +3 -0
  24. package/dist/commands/auth/index.d.ts.map +1 -0
  25. package/dist/commands/auth/index.js +198 -0
  26. package/dist/commands/auth/index.js.map +1 -0
  27. package/dist/commands/completion/index.d.ts +3 -0
  28. package/dist/commands/completion/index.d.ts.map +1 -0
  29. package/dist/commands/completion/index.js +10 -0
  30. package/dist/commands/completion/index.js.map +1 -0
  31. package/dist/commands/data/index.d.ts +3 -0
  32. package/dist/commands/data/index.d.ts.map +1 -0
  33. package/dist/commands/data/index.js +245 -0
  34. package/dist/commands/data/index.js.map +1 -0
  35. package/dist/commands/db/index.d.ts +15 -0
  36. package/dist/commands/db/index.d.ts.map +1 -0
  37. package/dist/commands/db/index.js +389 -0
  38. package/dist/commands/db/index.js.map +1 -0
  39. package/dist/commands/doctor/index.d.ts +3 -0
  40. package/dist/commands/doctor/index.d.ts.map +1 -0
  41. package/dist/commands/doctor/index.js +305 -0
  42. package/dist/commands/doctor/index.js.map +1 -0
  43. package/dist/commands/functions/delete.d.ts +3 -0
  44. package/dist/commands/functions/delete.d.ts.map +1 -0
  45. package/dist/commands/functions/delete.js +55 -0
  46. package/dist/commands/functions/delete.js.map +1 -0
  47. package/dist/commands/functions/deploy.d.ts +3 -0
  48. package/dist/commands/functions/deploy.d.ts.map +1 -0
  49. package/dist/commands/functions/deploy.js +118 -0
  50. package/dist/commands/functions/deploy.js.map +1 -0
  51. package/dist/commands/functions/index.d.ts +3 -0
  52. package/dist/commands/functions/index.d.ts.map +1 -0
  53. package/dist/commands/functions/index.js +15 -0
  54. package/dist/commands/functions/index.js.map +1 -0
  55. package/dist/commands/functions/list.d.ts +6 -0
  56. package/dist/commands/functions/list.d.ts.map +1 -0
  57. package/dist/commands/functions/list.js +63 -0
  58. package/dist/commands/functions/list.js.map +1 -0
  59. package/dist/commands/functions/new.d.ts +3 -0
  60. package/dist/commands/functions/new.d.ts.map +1 -0
  61. package/dist/commands/functions/new.js +57 -0
  62. package/dist/commands/functions/new.js.map +1 -0
  63. package/dist/commands/gen/index.d.ts +3 -0
  64. package/dist/commands/gen/index.d.ts.map +1 -0
  65. package/dist/commands/gen/index.js +320 -0
  66. package/dist/commands/gen/index.js.map +1 -0
  67. package/dist/commands/instance/index.d.ts +8 -0
  68. package/dist/commands/instance/index.d.ts.map +1 -0
  69. package/dist/commands/instance/index.js +361 -0
  70. package/dist/commands/instance/index.js.map +1 -0
  71. package/dist/commands/login/index.d.ts +3 -0
  72. package/dist/commands/login/index.d.ts.map +1 -0
  73. package/dist/commands/login/index.js +160 -0
  74. package/dist/commands/login/index.js.map +1 -0
  75. package/dist/commands/login/login.d.ts +3 -0
  76. package/dist/commands/login/login.d.ts.map +1 -0
  77. package/dist/commands/login/login.js +185 -0
  78. package/dist/commands/login/login.js.map +1 -0
  79. package/dist/commands/logout/index.d.ts +3 -0
  80. package/dist/commands/logout/index.d.ts.map +1 -0
  81. package/dist/commands/logout/index.js +41 -0
  82. package/dist/commands/logout/index.js.map +1 -0
  83. package/dist/commands/profile/import-env.d.ts +13 -0
  84. package/dist/commands/profile/import-env.d.ts.map +1 -0
  85. package/dist/commands/profile/import-env.js +81 -0
  86. package/dist/commands/profile/import-env.js.map +1 -0
  87. package/dist/commands/profile/index.d.ts +3 -0
  88. package/dist/commands/profile/index.d.ts.map +1 -0
  89. package/dist/commands/profile/index.js +112 -0
  90. package/dist/commands/profile/index.js.map +1 -0
  91. package/dist/commands/rest/index.d.ts +3 -0
  92. package/dist/commands/rest/index.d.ts.map +1 -0
  93. package/dist/commands/rest/index.js +102 -0
  94. package/dist/commands/rest/index.js.map +1 -0
  95. package/dist/commands/skill/index.d.ts +11 -0
  96. package/dist/commands/skill/index.d.ts.map +1 -0
  97. package/dist/commands/skill/index.js +153 -0
  98. package/dist/commands/skill/index.js.map +1 -0
  99. package/dist/commands/status/index.d.ts +3 -0
  100. package/dist/commands/status/index.d.ts.map +1 -0
  101. package/dist/commands/status/index.js +59 -0
  102. package/dist/commands/status/index.js.map +1 -0
  103. package/dist/commands/storage/index.d.ts +3 -0
  104. package/dist/commands/storage/index.d.ts.map +1 -0
  105. package/dist/commands/storage/index.js +198 -0
  106. package/dist/commands/storage/index.js.map +1 -0
  107. package/dist/commands/whoami/index.d.ts +3 -0
  108. package/dist/commands/whoami/index.d.ts.map +1 -0
  109. package/dist/commands/whoami/index.js +82 -0
  110. package/dist/commands/whoami/index.js.map +1 -0
  111. package/dist/credentials/commit.d.ts +38 -0
  112. package/dist/credentials/commit.d.ts.map +1 -0
  113. package/dist/credentials/commit.js +57 -0
  114. package/dist/credentials/commit.js.map +1 -0
  115. package/dist/credentials/credential-store.d.ts +57 -0
  116. package/dist/credentials/credential-store.d.ts.map +1 -0
  117. package/dist/credentials/credential-store.js +180 -0
  118. package/dist/credentials/credential-store.js.map +1 -0
  119. package/dist/credentials/env-file.d.ts +44 -0
  120. package/dist/credentials/env-file.d.ts.map +1 -0
  121. package/dist/credentials/env-file.js +118 -0
  122. package/dist/credentials/env-file.js.map +1 -0
  123. package/dist/credentials/formatter.d.ts +39 -0
  124. package/dist/credentials/formatter.d.ts.map +1 -0
  125. package/dist/credentials/formatter.js +79 -0
  126. package/dist/credentials/formatter.js.map +1 -0
  127. package/dist/credentials/index.d.ts +13 -0
  128. package/dist/credentials/index.d.ts.map +1 -0
  129. package/dist/credentials/index.js +13 -0
  130. package/dist/credentials/index.js.map +1 -0
  131. package/dist/credentials/jwt-introspect.d.ts +32 -0
  132. package/dist/credentials/jwt-introspect.d.ts.map +1 -0
  133. package/dist/credentials/jwt-introspect.js +64 -0
  134. package/dist/credentials/jwt-introspect.js.map +1 -0
  135. package/dist/credentials/masker.d.ts +20 -0
  136. package/dist/credentials/masker.d.ts.map +1 -0
  137. package/dist/credentials/masker.js +37 -0
  138. package/dist/credentials/masker.js.map +1 -0
  139. package/dist/credentials/profile.d.ts +83 -0
  140. package/dist/credentials/profile.d.ts.map +1 -0
  141. package/dist/credentials/profile.js +184 -0
  142. package/dist/credentials/profile.js.map +1 -0
  143. package/dist/credentials/tenant-guard.d.ts +16 -0
  144. package/dist/credentials/tenant-guard.d.ts.map +1 -0
  145. package/dist/credentials/tenant-guard.js +53 -0
  146. package/dist/credentials/tenant-guard.js.map +1 -0
  147. package/dist/credentials/tty-guard.d.ts +19 -0
  148. package/dist/credentials/tty-guard.d.ts.map +1 -0
  149. package/dist/credentials/tty-guard.js +47 -0
  150. package/dist/credentials/tty-guard.js.map +1 -0
  151. package/dist/db/apply-schema.d.ts +144 -0
  152. package/dist/db/apply-schema.d.ts.map +1 -0
  153. package/dist/db/apply-schema.js +359 -0
  154. package/dist/db/apply-schema.js.map +1 -0
  155. package/dist/db/sql-file.d.ts +104 -0
  156. package/dist/db/sql-file.d.ts.map +1 -0
  157. package/dist/db/sql-file.js +584 -0
  158. package/dist/db/sql-file.js.map +1 -0
  159. package/dist/instance/provision.d.ts +89 -0
  160. package/dist/instance/provision.d.ts.map +1 -0
  161. package/dist/instance/provision.js +139 -0
  162. package/dist/instance/provision.js.map +1 -0
  163. package/dist/instance/zero-store.d.ts +47 -0
  164. package/dist/instance/zero-store.d.ts.map +1 -0
  165. package/dist/instance/zero-store.js +91 -0
  166. package/dist/instance/zero-store.js.map +1 -0
  167. package/dist/main.d.ts +3 -0
  168. package/dist/main.d.ts.map +1 -0
  169. package/dist/main.js +46 -0
  170. package/dist/main.js.map +1 -0
  171. package/dist/skill/assets.d.ts +38 -0
  172. package/dist/skill/assets.d.ts.map +1 -0
  173. package/dist/skill/assets.js +111 -0
  174. package/dist/skill/assets.js.map +1 -0
  175. package/dist/skill/hint.d.ts +39 -0
  176. package/dist/skill/hint.d.ts.map +1 -0
  177. package/dist/skill/hint.js +109 -0
  178. package/dist/skill/hint.js.map +1 -0
  179. package/dist/skill/hosts.d.ts +21 -0
  180. package/dist/skill/hosts.d.ts.map +1 -0
  181. package/dist/skill/hosts.js +38 -0
  182. package/dist/skill/hosts.js.map +1 -0
  183. package/dist/skill/installer.d.ts +88 -0
  184. package/dist/skill/installer.d.ts.map +1 -0
  185. package/dist/skill/installer.js +203 -0
  186. package/dist/skill/installer.js.map +1 -0
  187. package/dist/skill/ownership.d.ts +35 -0
  188. package/dist/skill/ownership.d.ts.map +1 -0
  189. package/dist/skill/ownership.js +52 -0
  190. package/dist/skill/ownership.js.map +1 -0
  191. package/package.json +63 -3
  192. package/skills/pxbaas-app-spec/SKILL.md +163 -0
  193. package/skills/pxbaas-app-spec/references/deploy-options.md +157 -0
  194. package/skills/pxbaas-app-spec/references/guardrails-pitfalls.md +89 -0
  195. package/skills/pxbaas-app-spec/references/runtime-contract.md +151 -0
  196. package/skills/pxbaas-app-spec/references/ssr-session.md +121 -0
  197. package/skills/pxbaas-app-spec/references/templates-examples.md +311 -0
  198. package/skills/pxbaas-cli/SKILL.md +171 -0
  199. package/skills/pxbaas-cli/references/api-reference.md +68 -0
  200. package/skills/pxbaas-cli/references/app-deploy.md +170 -0
  201. package/skills/pxbaas-cli/references/auth-and-credentials.md +100 -0
  202. package/skills/pxbaas-cli/references/data-postgrest.md +85 -0
  203. package/skills/pxbaas-cli/references/db-and-meta.md +97 -0
  204. package/skills/pxbaas-cli/references/edge-functions.md +71 -0
  205. package/skills/pxbaas-cli/references/multi-tenant-apps.md +138 -0
  206. package/skills/pxbaas-cli/references/provision.md +86 -0
  207. package/skills/pxbaas-cli/references/safety-and-two-phase.md +49 -0
  208. package/skills/pxbaas-cli/references/storage.md +61 -0
  209. package/skills/pxbaas-cli/references/troubleshooting.md +73 -0
  210. package/templates/webapp/api/index.ts +55 -0
  211. package/templates/webapp/csr-bff/README.md +81 -0
  212. package/templates/webapp/csr-bff/backend/index.ts +168 -0
  213. package/templates/webapp/csr-bff/db/rls.json +13 -0
  214. package/templates/webapp/csr-bff/db/schema.sql +49 -0
  215. package/templates/webapp/csr-bff/frontend/dist/admin.html +101 -0
  216. package/templates/webapp/csr-bff/frontend/dist/article.html +44 -0
  217. package/templates/webapp/csr-bff/frontend/dist/blog.js +206 -0
  218. package/templates/webapp/csr-bff/frontend/dist/blogger.html +53 -0
  219. package/templates/webapp/csr-bff/frontend/dist/index.html +70 -0
  220. package/templates/webapp/csr-bff/frontend/dist/login.html +56 -0
  221. package/templates/webapp/csr-bff/frontend/dist/profile.html +59 -0
  222. package/templates/webapp/csr-bff/frontend/dist/signup.html +78 -0
  223. package/templates/webapp/csr-bff/frontend/dist/style.css +27 -0
  224. package/templates/webapp/manifest.json +299 -0
  225. package/templates/webapp/mpa/about.html +29 -0
  226. package/templates/webapp/mpa/app.js +42 -0
  227. package/templates/webapp/mpa/index.html +42 -0
  228. package/templates/webapp/mpa/index.ts +60 -0
  229. package/templates/webapp/mpa/style.css +42 -0
  230. package/templates/webapp/react-vite/frontend/index.html +12 -0
  231. package/templates/webapp/react-vite/frontend/package-lock.json +1826 -0
  232. package/templates/webapp/react-vite/frontend/package.json +23 -0
  233. package/templates/webapp/react-vite/frontend/src/App.tsx +34 -0
  234. package/templates/webapp/react-vite/frontend/src/main.tsx +13 -0
  235. package/templates/webapp/react-vite/frontend/src/style.css +46 -0
  236. package/templates/webapp/react-vite/frontend/tsconfig.json +20 -0
  237. package/templates/webapp/react-vite/frontend/vite.config.ts +10 -0
  238. package/templates/webapp/react-vite-hono/backend/index.ts +21 -0
  239. package/templates/webapp/react-vite-hono/frontend/index.html +12 -0
  240. package/templates/webapp/react-vite-hono/frontend/package-lock.json +1826 -0
  241. package/templates/webapp/react-vite-hono/frontend/package.json +23 -0
  242. package/templates/webapp/react-vite-hono/frontend/src/App.tsx +47 -0
  243. package/templates/webapp/react-vite-hono/frontend/src/main.tsx +13 -0
  244. package/templates/webapp/react-vite-hono/frontend/src/style.css +66 -0
  245. package/templates/webapp/react-vite-hono/frontend/tsconfig.json +20 -0
  246. package/templates/webapp/react-vite-hono/frontend/vite.config.ts +10 -0
  247. package/templates/webapp/spa/index.ts +119 -0
  248. package/templates/webapp/ssr-auth/backend/index.ts +133 -0
  249. package/templates/webapp/ssr-auth/frontend/dist/index.html +15 -0
  250. package/templates/webapp/ssr-blog/README.md +111 -0
  251. package/templates/webapp/ssr-blog/backend/index.ts +764 -0
  252. package/templates/webapp/ssr-blog/db/rls.json +13 -0
  253. package/templates/webapp/ssr-blog/db/schema.sql +51 -0
  254. package/templates/webapp/ssr-blog/frontend/dist/index.html +39 -0
  255. package/templates/webapp/ssr-frameworks/README.md +64 -0
  256. package/templates/webapp/ssr-frameworks/backend/index.ts +241 -0
  257. package/templates/webapp/ssr-frameworks/frontend/dist/index.html +31 -0
  258. package/templates/webapp/ssr-hono/backend/index.ts +92 -0
  259. package/templates/webapp/ssr-hono/frontend/dist/index.html +12 -0
  260. package/templates/webapp/ssr-shop/README.md +80 -0
  261. package/templates/webapp/ssr-shop/backend/index.ts +491 -0
  262. package/templates/webapp/ssr-shop/db/rls.json +16 -0
  263. package/templates/webapp/ssr-shop/db/schema.sql +90 -0
  264. package/templates/webapp/ssr-shop/frontend/dist/index.html +12 -0
  265. package/templates/webapp/vanilla-static/frontend/app.js +6 -0
  266. package/templates/webapp/vanilla-static/frontend/index.html +19 -0
  267. package/templates/webapp/vanilla-static/frontend/style.css +43 -0
@@ -0,0 +1,407 @@
1
+ /** Static compliance checks for legacy edge-function apps and manifest-v2 webapps. */
2
+ import { scanRootAbsoluteRefs } from "./preflight.js";
3
+ const SPEC = "pxbaas-app-spec";
4
+ const BINARY_ASSET_RE = /\.(png|jpe?g|gif|webp|ico|bmp|tiff?|woff2?|ttf|otf|eot|pdf|zip|gz|tgz|mp4|webm|mp3|wav|avif|wasm)$/i;
5
+ const NODE_PATTERNS = [
6
+ { re: /\brequire\s*\(/, hint: "require()" },
7
+ { re: /(?:from\s+|import\s*)["']node:/, hint: "node: import" },
8
+ {
9
+ re: /\bfrom\s+["'](?:fs|path|http|https|os|crypto|child_process|express|koa|fastify|axios)["']/,
10
+ hint: "Node/builtin import",
11
+ },
12
+ {
13
+ re: /\bprocess\.(?:env|exit|argv|stdin|stdout|stderr)\b/,
14
+ hint: "process.*",
15
+ },
16
+ { re: /\b__dirname\b|\b__filename\b/, hint: "__dirname/__filename" },
17
+ ];
18
+ /**
19
+ * Platform-injected public env keys readable by App candidate workers.
20
+ * Mirrors edge-runtime `mysql/builtin-functions/main/app-env.ts`
21
+ * APP_PUBLIC_ENV_KEYS (MR #30497903). Role contract: SUPABASE_INTERNAL_URL is the
22
+ * only legal data-plane fetch base, SUPABASE_ANON_KEY the data-plane credential,
23
+ * SUPABASE_URL a render-only public origin (never fetch through it).
24
+ */
25
+ const APP_PUBLIC_ENV_KEYS = new Set([
26
+ "SUPABASE_URL",
27
+ "SUPABASE_ANON_KEY",
28
+ "SUPABASE_INTERNAL_URL",
29
+ ]);
30
+ /**
31
+ * Strip line and block comments while preserving string and template literals,
32
+ * so keyword rules (Deno.env, Set-Cookie, Node APIs, ...) do not false-positive
33
+ * on explanatory comments. Regex literals are not lexed: a slash only begins a
34
+ * comment when followed by another slash or an asterisk.
35
+ */
36
+ function stripComments(src) {
37
+ let out = "";
38
+ let i = 0;
39
+ const n = src.length;
40
+ let state = "code";
41
+ while (i < n) {
42
+ const c = src[i];
43
+ const c2 = src[i + 1];
44
+ if (state === "code") {
45
+ if (c === "/" && c2 === "/") {
46
+ state = "line";
47
+ i += 2;
48
+ continue;
49
+ }
50
+ if (c === "/" && c2 === "*") {
51
+ state = "block";
52
+ i += 2;
53
+ continue;
54
+ }
55
+ if (c === "'") {
56
+ state = "sq";
57
+ out += c;
58
+ i++;
59
+ continue;
60
+ }
61
+ if (c === '"') {
62
+ state = "dq";
63
+ out += c;
64
+ i++;
65
+ continue;
66
+ }
67
+ if (c === "`") {
68
+ state = "tpl";
69
+ out += c;
70
+ i++;
71
+ continue;
72
+ }
73
+ out += c;
74
+ i++;
75
+ continue;
76
+ }
77
+ if (state === "line") {
78
+ if (c === "\n") {
79
+ state = "code";
80
+ out += c;
81
+ }
82
+ i++;
83
+ continue;
84
+ }
85
+ if (state === "block") {
86
+ if (c === "*" && c2 === "/") {
87
+ state = "code";
88
+ i += 2;
89
+ continue;
90
+ }
91
+ if (c === "\n")
92
+ out += c;
93
+ i++;
94
+ continue;
95
+ }
96
+ // string / template states: copy verbatim, honour backslash escapes
97
+ if (c === "\\") {
98
+ out += c + (c2 ?? "");
99
+ i += 2;
100
+ continue;
101
+ }
102
+ if ((state === "sq" && c === "'") ||
103
+ (state === "dq" && c === '"') ||
104
+ (state === "tpl" && c === "`")) {
105
+ state = "code";
106
+ }
107
+ out += c;
108
+ i++;
109
+ continue;
110
+ }
111
+ return out;
112
+ }
113
+ function finding(rule, message, ref) {
114
+ return {
115
+ rule,
116
+ severity: "blocker",
117
+ message,
118
+ specRef: `${SPEC}/references/${ref}`,
119
+ };
120
+ }
121
+ function lintBackend(source, options, blockers, warnings) {
122
+ const code = stripComments(source);
123
+ if (!/Deno\.serve\s*\(/.test(code)) {
124
+ blockers.push(finding("deno-serve", "Missing top-level Deno.serve(...). The webapp backend must use the Deno HTTP server contract.", "runtime-contract.md"));
125
+ }
126
+ for (const { re, hint } of NODE_PATTERNS) {
127
+ if (re.test(code)) {
128
+ blockers.push(finding("no-node-api", `Node.js API detected (${hint}). The backend runtime is Deno.`, "runtime-contract.md"));
129
+ break;
130
+ }
131
+ }
132
+ // Custom Secrets are unsupported in the first webapp release.
133
+ if ((options.secrets?.length ?? 0) > 0) {
134
+ blockers.push(finding("custom-secrets-not-supported", "Custom Secrets are not supported by the first webapp release. Remove the backend.secrets entries from app.json.", "guardrails-pitfalls.md"));
135
+ }
136
+ // Deno.env: only the platform public three-key whitelist is readable. Any
137
+ // other key, or dynamic/toObject access that could expose the whole env, is a
138
+ // blocker. Matched on comment-stripped code so documented examples do not trip it.
139
+ const envOffenders = new Set();
140
+ let sawUnverifiableEnv = false;
141
+ for (const match of code.matchAll(/Deno\.env\.(get|toObject|set|delete)\s*\(([^)]*)\)/g)) {
142
+ const method = match[1];
143
+ const argRaw = match[2].trim();
144
+ if (method === "toObject") {
145
+ sawUnverifiableEnv = true;
146
+ continue;
147
+ }
148
+ const literal = argRaw.match(/^["']([^"']+)["']/);
149
+ if (literal) {
150
+ if (!APP_PUBLIC_ENV_KEYS.has(literal[1]))
151
+ envOffenders.add(literal[1]);
152
+ }
153
+ else {
154
+ sawUnverifiableEnv = true;
155
+ }
156
+ }
157
+ if (envOffenders.size > 0 || sawUnverifiableEnv) {
158
+ const detail = envOffenders.size > 0
159
+ ? [...envOffenders].slice(0, 3).join(", ")
160
+ : "dynamic key or Deno.env.toObject()";
161
+ blockers.push(finding("deno-env-not-allowed", `Only the platform public env keys are readable (${[...APP_PUBLIC_ENV_KEYS].join(", ")}). Offending Deno.env access: ${detail}.`, "guardrails-pitfalls.md"));
162
+ }
163
+ if ((options.egressPolicy ?? "deny") !== "deny") {
164
+ blockers.push(finding("egress-deny", 'The first webapp release requires backend.egressPolicy="deny".', "runtime-contract.md"));
165
+ }
166
+ const importSpecifiers = [
167
+ ...code.matchAll(/(?:from\s*|import\s*(?:\(\s*)?)["']([^"']+)["']/g),
168
+ ].map((match) => match[1]);
169
+ const remoteImports = importSpecifiers.filter((value) => /^(?:https?:|jsr:|npm:)/.test(value));
170
+ const ssrLibs = options.ssrLibs ?? [];
171
+ const isAllowedSsrImport = (value) => ssrLibs.some((e) => value === `npm:${e}` || value.startsWith(`npm:${e}/`));
172
+ const honoExpected = options.backendFramework === "hono" && options.honoVersion
173
+ ? `npm:hono@${options.honoVersion}`
174
+ : null;
175
+ // Hono (D7): the hono-version rule governs ONLY the Hono import itself.
176
+ if (options.backendFramework === "hono") {
177
+ if (!honoExpected || !importSpecifiers.includes(honoExpected)) {
178
+ blockers.push(finding("hono-version", honoExpected
179
+ ? `Hono must use the exact platform import ${honoExpected}.`
180
+ : "Hono is not available because the instance did not report an exact offline-ready version.", "runtime-contract.md"));
181
+ }
182
+ }
183
+ // Off-list remote imports: anything except the exact Hono import and the
184
+ // capability-curated SSR renderers (npm:<name>@<version>[/subpath]).
185
+ const offList = remoteImports.filter((value) => {
186
+ if (honoExpected && value === honoExpected)
187
+ return false;
188
+ if (options.backendFramework === "hono" && /^npm:hono@/.test(value))
189
+ return false; // wrong-version Hono is reported by hono-version above
190
+ if (value.startsWith("npm:") && isAllowedSsrImport(value))
191
+ return false;
192
+ return true;
193
+ });
194
+ const npmOffList = offList.filter((value) => value.startsWith("npm:"));
195
+ const otherOffList = offList.filter((value) => !value.startsWith("npm:"));
196
+ if (npmOffList.length > 0) {
197
+ blockers.push(ssrLibs.length > 0
198
+ ? finding("ssr-lib-not-allowed", `npm import(s) not in this instance's capability ssrLibs: ${npmOffList.slice(0, 3).join(", ")}. Allowed SSR renderers: ${ssrLibs.map((e) => `npm:${e}`).join(", ")} (a /subpath such as /server or /web is allowed).`, "runtime-contract.md")
199
+ : finding("no-remote-import", `Remote/npm/jsr import(s) are not allowed: ${npmOffList.slice(0, 3).join(", ")}. ` +
200
+ "This instance reported an EMPTY capabilities.ssrLibs allow-list, so every npm: import is blocked. " +
201
+ "ssrLibs is a declaration baked from SSR_LIBS_LIST (/etc/supabase/ssr-libs); an empty value usually means " +
202
+ "the AIO image was built without it even though the sandbox caches the renderers. Fix the instance " +
203
+ "(bake SSR_LIBS_LIST or set APP_SSR_LIBS, then restart edge-proxy/studio) rather than working around it " +
204
+ "with --skip-spec-check; Hono itself is gated by hono-version/honoOfflineReady, not by ssrLibs.", "runtime-contract.md"));
205
+ }
206
+ if (otherOffList.length > 0) {
207
+ blockers.push(finding("no-remote-import", `Remote http/https/jsr import(s) are not allowed: ${otherOffList.slice(0, 3).join(", ")}.`, "runtime-contract.md"));
208
+ }
209
+ const hasCors = /Access-Control-Allow-Origin/i.test(code);
210
+ const hasOptions = /OPTIONS/.test(code);
211
+ if (!hasCors || !hasOptions) {
212
+ warnings.push({
213
+ rule: "cors-options",
214
+ severity: "warning",
215
+ message: `Missing ${!hasCors ? "CORS headers" : ""}${!hasCors && !hasOptions ? " and " : ""}${!hasOptions ? "OPTIONS handling" : ""}. Browser calls to the backend may fail.`,
216
+ specRef: `${SPEC}/references/guardrails-pitfalls.md`,
217
+ });
218
+ }
219
+ }
220
+ function lintWebappFrontend(options, blockers) {
221
+ const files = options.frontendFiles ?? [];
222
+ const normalized = files.map((file) => file.replace(/\\/g, "/"));
223
+ const forbiddenEnv = normalized.filter((file) => /(^|\/)\.env(?:\.|$)/.test(file));
224
+ const sourceMaps = normalized.filter((file) => /\.map$/i.test(file));
225
+ const nodeModules = normalized.filter((file) => /(^|\/)node_modules\//.test(file));
226
+ const sourceDirs = normalized.filter((file) => /(^|\/)src\//.test(file));
227
+ const serviceWorkers = normalized.filter((file) => /(^|\/)(?:service-worker|sw)\.(?:js|mjs|ts)$/i.test(file));
228
+ if (forbiddenEnv.length > 0)
229
+ blockers.push(finding("no-env-files", `Frontend artifacts must not include .env files: ${forbiddenEnv.slice(0, 5).join(", ")}.`, "guardrails-pitfalls.md"));
230
+ if (sourceMaps.length > 0)
231
+ blockers.push(finding("no-source-maps", `Frontend artifacts must not include source maps: ${sourceMaps.slice(0, 5).join(", ")}.`, "guardrails-pitfalls.md"));
232
+ if (nodeModules.length > 0)
233
+ blockers.push(finding("no-node-modules", "Upload the built frontend output, not node_modules.", "guardrails-pitfalls.md"));
234
+ if (sourceDirs.length > 0)
235
+ blockers.push(finding("no-frontend-source", "Upload the prebuilt frontend directory, not a source directory.", "templates-examples.md"));
236
+ if (serviceWorkers.length > 0)
237
+ blockers.push(finding("no-service-worker", `Service Worker files are not supported: ${serviceWorkers.slice(0, 5).join(", ")}.`, "guardrails-pitfalls.md"));
238
+ const frontendSource = (options.frontendSources ?? [])
239
+ .map((file) => file.source)
240
+ .join("\n");
241
+ const projectSource = (options.frontendProjectSources ?? []).join("\n");
242
+ if (/navigator\.serviceWorker|serviceWorker\.register\s*\(/.test(`${frontendSource}\n${projectSource}`)) {
243
+ blockers.push(finding("no-service-worker", "Service Worker registration is not supported by the first webapp release.", "guardrails-pitfalls.md"));
244
+ }
245
+ if (options.frontendConfigSource !== undefined &&
246
+ !/\bbase\s*:\s*["']\.\/["']/.test(options.frontendConfigSource)) {
247
+ blockers.push(finding("vite-relative-base", 'Vite must set base: "./" so assets remain under the App mount.', "templates-examples.md"));
248
+ }
249
+ if (options.frontendConfigSource !== undefined &&
250
+ /\bsourcemap\s*:\s*(?:true|["'](?:inline|hidden)["'])/.test(options.frontendConfigSource)) {
251
+ blockers.push(finding("no-source-maps", "Vite source maps must be disabled for uploaded frontend artifacts.", "guardrails-pitfalls.md"));
252
+ }
253
+ if (options.requireHashRouter && !/\bHashRouter\b/.test(projectSource)) {
254
+ blockers.push(finding("react-hash-router", "React webapps must use HashRouter; history fallback is not supported.", "templates-examples.md"));
255
+ }
256
+ }
257
+ /** SSR (W5): authoring guards for fallback=worker apps (DX-2 marker, D16 self-contained). */
258
+ function lintSsr(backendSource, options, blockers, warnings) {
259
+ const code = stripComments(backendSource);
260
+ const probe = options.ssrProbePath;
261
+ if (typeof probe !== "string" || !probe.startsWith("/") || probe.includes("..")) {
262
+ blockers.push(finding("ssr-probe-declared", 'manifest.ssrProbePath is required (safe logical path, e.g. "/page") when frontend.fallback="worker".', "runtime-contract.md"));
263
+ }
264
+ if (/from\s+["']\.\//.test(code) || /import\s*\(\s*["']\.\//.test(code)) {
265
+ blockers.push(finding("ssr-self-contained", "SSR worker must be single-file self-contained: relative module imports fail at boot on the current runtime (D16). Inline helpers or import platform-pinned packages only.", "runtime-contract.md"));
266
+ }
267
+ // The marker may be written with escaped quotes inside a double-quoted JS
268
+ // string (e.g. "<div ... data-ssr=\"v1\">"), so match an optional backslash
269
+ // before each quote rather than a naive substring.
270
+ if (!/data-ssr=\\?["']v1\\?["']/.test(code)) {
271
+ blockers.push(finding("ssr-marker-present", 'SSR page output must include the hydration root marker <div id="__ssr" data-ssr="v1"> so the publish probe can verify rendering (DX-2).', "runtime-contract.md"));
272
+ }
273
+ if (/\bwindow\b|\bdocument\b/.test(code)) {
274
+ warnings.push({
275
+ ...finding("ssr-no-browser-globals", "SSR worker references window/document: server render must not touch browser globals at import or render time.", "runtime-contract.md"),
276
+ severity: "warning",
277
+ });
278
+ }
279
+ }
280
+ /** Lint source and artifact metadata while preserving legacy spa/api/mpa behavior. */
281
+ export function lintAppSource(source, options = {}) {
282
+ const blockers = [];
283
+ const warnings = [];
284
+ const mode = options.mode ?? "spa";
285
+ const verifyJwt = options.verifyJwt ?? false;
286
+ const isWebapp = mode === "webapp";
287
+ const backendSource = options.backendSource ?? source;
288
+ // Backend lint runs for legacy apps and for webapps with a declared framework.
289
+ // A webapp backend missing `framework` is rejected earlier by manifest
290
+ // validation (requireWebappManifestValue, R2-09), so it never reaches a state
291
+ // where these checks would be silently skipped.
292
+ if (!isWebapp || options.backendFramework)
293
+ lintBackend(backendSource, options, blockers, warnings);
294
+ if (isWebapp)
295
+ lintWebappFrontend(options, blockers);
296
+ const scannedSources = isWebapp
297
+ ? [
298
+ ...(options.frontendSources ?? []).map((file) => file.source),
299
+ ...(options.frontendProjectSources ?? []),
300
+ // R2-08: also scan SSR backend output for root-absolute refs (href="/x",
301
+ // fetch("/x"), url(/x)) that would escape the /apps/{mount} prefix. Comments
302
+ // are stripped first so documented examples do not false-positive; server-side
303
+ // fetches use the injected internal base (base + "/rest/..."), not root-absolute
304
+ // literals, so legitimate SSR data access is unaffected.
305
+ ...(options.backendSource ? [stripComments(options.backendSource)] : []),
306
+ ]
307
+ : [source, ...(options.auxiliarySources ?? [])];
308
+ const rootAbs = scanRootAbsoluteRefs(scannedSources.join("\n"));
309
+ if (rootAbs.length > 0) {
310
+ blockers.push(finding("no-root-absolute", `Root-absolute reference(s) found: ${rootAbs.slice(0, 3).join(", ")}. Use mount-relative URLs.`, "guardrails-pitfalls.md"));
311
+ }
312
+ if (mode === "mpa") {
313
+ const existing = new Set(options.existingFiles ?? []);
314
+ const missing = (options.declaredFiles ?? []).filter((file) => !existing.has(file));
315
+ if (missing.length > 0)
316
+ blockers.push(finding("mpa-assets-exist", `app.json declares missing page(s)/asset(s): ${missing.join(", ")}.`, "templates-examples.md"));
317
+ }
318
+ if (isWebapp && options.ssrFallback)
319
+ lintSsr(backendSource, options, blockers, warnings);
320
+ if (isWebapp)
321
+ lintSession(backendSource, options, blockers, warnings);
322
+ if (mode === "mpa" || isWebapp) {
323
+ const files = isWebapp
324
+ ? (options.frontendFiles ?? [])
325
+ : (options.existingFiles ?? []);
326
+ const binary = files.filter((file) => BINARY_ASSET_RE.test(file));
327
+ if (binary.length > 0)
328
+ blockers.push(finding("no-binary-assets", `Binary assets are not supported by the text-only release: ${binary.slice(0, 5).join(", ")}. Put binary assets in Storage instead.`, "guardrails-pitfalls.md"));
329
+ }
330
+ if (!isWebapp) {
331
+ const servesHtml = /text\/html/i.test(source);
332
+ const hasEscape = /\besc\s*\(|escapeHtml|encodeHTML|replace\(\s*\/&\/g/.test(source);
333
+ if (servesHtml && !hasEscape)
334
+ warnings.push({
335
+ rule: "escape-reflected",
336
+ severity: "warning",
337
+ message: "Serves text/html but no HTML-escaping helper was found.",
338
+ specRef: `${SPEC}/references/guardrails-pitfalls.md`,
339
+ });
340
+ if (/<script[^>]+src=["']https?:\/\//i.test(source) ||
341
+ /<link[^>]+href=["']https?:\/\//i.test(source))
342
+ warnings.push({
343
+ rule: "no-external-cdn",
344
+ severity: "warning",
345
+ message: "External CDN core assets were detected; bundle or inline them.",
346
+ specRef: `${SPEC}/references/guardrails-pitfalls.md`,
347
+ });
348
+ if (!verifyJwt &&
349
+ /service_role|serviceRoleKey|SERVICE_ROLE|dbPassword|DASHBOARD_PASSWORD|secret\s*[:=]/i.test(source))
350
+ warnings.push({
351
+ rule: "no-secrets-public",
352
+ severity: "warning",
353
+ message: "A public function appears to reference a secret.",
354
+ specRef: `${SPEC}/references/guardrails-pitfalls.md`,
355
+ });
356
+ }
357
+ return { passed: blockers.length === 0, blockers, warnings };
358
+ }
359
+ /** 方案 C: session-contract authoring guards for webapp backends. */
360
+ function lintSession(backendSource, options, blockers, warnings) {
361
+ const session = options.backendSession ?? "none";
362
+ const src = stripComments(backendSource ?? "");
363
+ if (session === "proxy-injected") {
364
+ // Worker must NOT read the client cookie: /apps strips it, so any cookie the
365
+ // worker sees is a proxy-jar artifact. Identity comes from injected headers.
366
+ if (/headers?\s*(?:\.get\s*\(\s*["']cookie["']|\[\s*["']cookie["']\s*\])/i.test(src))
367
+ blockers.push(finding("session-no-cookie-read", 'backend.session="proxy-injected" must not read the Cookie header; use the injected X-App-User-* headers.', "ssr-session.md"));
368
+ if (/set-cookie/i.test(src))
369
+ blockers.push(finding("session-no-set-cookie", 'backend.session="proxy-injected" must not issue Set-Cookie; the proxy owns the session cookie.', "ssr-session.md"));
370
+ if (/[?&](sid|session_token|access_token)=/i.test(src))
371
+ blockers.push(finding("session-no-url-token", "Do not carry the user token in URLs (?sid=/&token=); the proxy injects X-App-User-Token.", "ssr-session.md"));
372
+ const headers = (options.sessionHeaders ?? []).map((h) => h.toLowerCase());
373
+ const used = headers.filter((h) => src.toLowerCase().includes(h));
374
+ if (used.length === 0)
375
+ warnings.push({
376
+ rule: "session-use-injected-header",
377
+ severity: "warning",
378
+ message: 'backend.session="proxy-injected" but no capabilities.sessionHeaders reference found; read X-App-User-Token/X-App-User-Id.',
379
+ specRef: `${SPEC}/references/ssr-session.md`,
380
+ });
381
+ // Any X-App-User-* header not in the capability whitelist is a forgery risk / typo.
382
+ const referenced = [
383
+ ...new Set((src.toLowerCase().match(/x-app-user-[a-z-]+/g) ?? [])),
384
+ ];
385
+ const unknown = referenced.filter((h) => !headers.includes(h));
386
+ if (unknown.length > 0)
387
+ blockers.push(finding("session-header-name-whitelist", `Unknown injected session header(s): ${unknown.join(", ")}. Use only capabilities.sessionHeaders.`, "ssr-session.md"));
388
+ if (/JWT_SECRET/i.test(src))
389
+ warnings.push({
390
+ rule: "session-env-secret",
391
+ severity: "warning",
392
+ message: "proxy-injected sessions are verified by the proxy; the worker needs no JWT signing secret.",
393
+ specRef: `${SPEC}/references/ssr-session.md`,
394
+ });
395
+ }
396
+ if (session === "browser-side") {
397
+ if (/headers?\s*(?:\.get\s*\(\s*["'](cookie|authorization)["']|\[\s*["'](cookie|authorization)["']\s*\])/i
398
+ .test(src))
399
+ warnings.push({
400
+ rule: "session-browser-side-no-worker-auth",
401
+ severity: "warning",
402
+ message: 'backend.session="browser-side": authentication belongs in the browser (localStorage + Authorization to /auth,/rest), not the worker.',
403
+ specRef: `${SPEC}/references/ssr-session.md`,
404
+ });
405
+ }
406
+ }
407
+ //# sourceMappingURL=spec-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-lint.js","sourceRoot":"","sources":["../../src/app/spec-lint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Webapp template resolution & scaffolding for `pxbaas app`.
3
+ *
4
+ * Templates ship as package files under `apps/baas/templates/webapp/` (route A,
5
+ * same as the bundled skill). We resolve the package root by walking up from this
6
+ * module until we find `templates/webapp/manifest.json`. The standalone single-file
7
+ * binary does not carry these assets; scaffolding then fails with a clear error.
8
+ */
9
+ export type AppMode = "spa" | "api" | "mpa" | "webapp";
10
+ export type BackendFramework = "deno" | "hono";
11
+ export interface AppFrontend {
12
+ root: string;
13
+ routing: "files";
14
+ index: string;
15
+ /** null = static-only; "worker" = static-miss falls through to the worker (SSR). */
16
+ fallback: null | "worker";
17
+ }
18
+ export interface AppBackend {
19
+ entrypoint: string;
20
+ framework: BackendFramework;
21
+ pathMode: "strip-app-api-prefix";
22
+ verifyJwt: boolean;
23
+ secrets: string[];
24
+ egressPolicy: "deny";
25
+ /** 方案 C: session delivery. none | proxy-injected | browser-side. */
26
+ session?: "none" | "proxy-injected" | "browser-side";
27
+ /**
28
+ * Optional backend health probe path for `pxbaas app verify` (a mount-relative
29
+ * logical path such as "/api/health"). When absent, verify checks only the
30
+ * mount homepage and does NOT probe a fixed backend route.
31
+ */
32
+ healthPath?: string;
33
+ }
34
+ export interface WebappTemplate {
35
+ id: string;
36
+ description: string;
37
+ entrypoint: string;
38
+ /** Deploy mode written into app.json; defaults to the template id (spa/api). */
39
+ mode?: AppMode;
40
+ /** Multi-file templates list every file to scaffold; paths may be nested. */
41
+ files?: string[];
42
+ /** mpa: the static HTML pages served by path. */
43
+ pages?: string[];
44
+ /** mpa: the static assets (css/js/images) served by path. */
45
+ assets?: string[];
46
+ /** webapp: prebuilt frontend artifact contract. */
47
+ frontend?: AppFrontend;
48
+ /** webapp: optional Deno/Hono backend contract. */
49
+ backend?: AppBackend | null;
50
+ /** webapp SSR (DX-2): publish-probe logical path; required when frontend.fallback==="worker". */
51
+ ssrProbePath?: string;
52
+ /**
53
+ * Machine-readable post-scaffold TODOs surfaced by `app new --json` (R2-11):
54
+ * e.g. database initialization for templates that ship db/schema.sql. The CLI
55
+ * never auto-runs DDL; these are reminders requiring explicit user action.
56
+ */
57
+ nextSteps?: string[];
58
+ }
59
+ export interface AppManifest {
60
+ schemaVersion?: 1 | 2;
61
+ name: string;
62
+ slug: string;
63
+ template: string;
64
+ entrypoint: string;
65
+ verifyJwt: boolean;
66
+ createdAt: string;
67
+ /** Legacy spa/api/mpa modes and the v2 webapp mode are both supported. */
68
+ mode?: AppMode;
69
+ /** mpa: static HTML pages that must exist and be served by path. */
70
+ pages?: string[];
71
+ /** mpa: static assets that must exist and be served by path. */
72
+ assets?: string[];
73
+ /** webapp: frontend staging layout. */
74
+ frontend?: AppFrontend;
75
+ /** webapp: backend runtime contract; null for static-only apps. */
76
+ backend?: AppBackend | null;
77
+ /** Optional SSR publish-probe path (DX-2): logical path returning the SSR page. */
78
+ ssrProbePath?: string;
79
+ /** Local deployment state used by lifecycle commands; ignored by the runtime. */
80
+ deployment?: {
81
+ mountId: string;
82
+ candidateFunctionSlug?: string;
83
+ generation: number;
84
+ };
85
+ }
86
+ /** Replaced with the exact capability version only in the uploaded candidate. */
87
+ export declare const HONO_VERSION_PLACEHOLDER = "{{HONO_VERSION}}";
88
+ export declare class TemplatesNotFoundError extends Error {
89
+ constructor(message: string);
90
+ }
91
+ /** Walk up to find the package root holding templates/webapp/manifest.json. */
92
+ export declare function resolveTemplatesRoot(startDir?: string): string | null;
93
+ export declare function resolveTemplatesDir(startDir?: string): string;
94
+ export declare function listTemplates(startDir?: string): Promise<WebappTemplate[]>;
95
+ /**
96
+ * Synchronous template-id list for CLI help text (command registration is sync).
97
+ * Returns [] when the bundled templates are unavailable (standalone binary), so
98
+ * callers can fall back to a generic hint instead of throwing at startup.
99
+ */
100
+ export declare function listTemplateIdsSync(startDir?: string): string[];
101
+ /** Read a template's entrypoint and substitute {{APP_NAME}} / {{SLUG}}. */
102
+ export declare function renderTemplate(templateId: string, vars: {
103
+ appName: string;
104
+ slug: string;
105
+ }, startDir?: string): Promise<{
106
+ entrypoint: string;
107
+ source: string;
108
+ }>;
109
+ /**
110
+ * Resolve a template definition and render every file it declares.
111
+ *
112
+ * Single-file templates (spa/api) render just the entrypoint; multi-file
113
+ * templates (mpa) render each entry in `files` (falling back to the entrypoint).
114
+ * Returns the template definition plus the rendered `{ name, source }` list.
115
+ */
116
+ export declare function renderTemplateFiles(templateId: string, vars: {
117
+ appName: string;
118
+ slug: string;
119
+ }, startDir?: string): Promise<{
120
+ template: WebappTemplate;
121
+ files: Array<{
122
+ name: string;
123
+ source: string;
124
+ }>;
125
+ }>;
126
+ /**
127
+ * Scaffold a new app under `<dir>/<name>/`: writes the rendered entrypoint and an
128
+ * `app.json` manifest. Refuses to overwrite an existing entrypoint unless forced.
129
+ */
130
+ export declare function scaffoldApp(opts: {
131
+ name: string;
132
+ slug: string;
133
+ template: string;
134
+ dir: string;
135
+ force?: boolean;
136
+ startDir?: string;
137
+ }): Promise<{
138
+ appDir: string;
139
+ files: string[];
140
+ manifest: AppManifest;
141
+ nextSteps: string[];
142
+ }>;
143
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/app/templates.ts"],"names":[],"mappings":"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"}