lakebed-native-cli 0.1.0

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 (265) hide show
  1. package/dist/cli/apple/branding.d.ts +9 -0
  2. package/dist/cli/apple/branding.d.ts.map +1 -0
  3. package/dist/cli/apple/branding.js +40 -0
  4. package/dist/cli/apple/branding.js.map +1 -0
  5. package/dist/cli/apple/build-cloud.d.ts +6 -0
  6. package/dist/cli/apple/build-cloud.d.ts.map +1 -0
  7. package/dist/cli/apple/build-cloud.js +34 -0
  8. package/dist/cli/apple/build-cloud.js.map +1 -0
  9. package/dist/cli/apple/build-local.d.ts +16 -0
  10. package/dist/cli/apple/build-local.d.ts.map +1 -0
  11. package/dist/cli/apple/build-local.js +97 -0
  12. package/dist/cli/apple/build-local.js.map +1 -0
  13. package/dist/cli/apple/choose-path.d.ts +23 -0
  14. package/dist/cli/apple/choose-path.d.ts.map +1 -0
  15. package/dist/cli/apple/choose-path.js +78 -0
  16. package/dist/cli/apple/choose-path.js.map +1 -0
  17. package/dist/cli/apple/device-pack.d.ts +36 -0
  18. package/dist/cli/apple/device-pack.d.ts.map +1 -0
  19. package/dist/cli/apple/device-pack.js +210 -0
  20. package/dist/cli/apple/device-pack.js.map +1 -0
  21. package/dist/cli/apple/devices.d.ts +6 -0
  22. package/dist/cli/apple/devices.d.ts.map +1 -0
  23. package/dist/cli/apple/devices.js +49 -0
  24. package/dist/cli/apple/devices.js.map +1 -0
  25. package/dist/cli/apple/eas-delegate.d.ts +25 -0
  26. package/dist/cli/apple/eas-delegate.d.ts.map +1 -0
  27. package/dist/cli/apple/eas-delegate.js +63 -0
  28. package/dist/cli/apple/eas-delegate.js.map +1 -0
  29. package/dist/cli/apple/index.d.ts +9 -0
  30. package/dist/cli/apple/index.d.ts.map +1 -0
  31. package/dist/cli/apple/index.js +12 -0
  32. package/dist/cli/apple/index.js.map +1 -0
  33. package/dist/cli/apple/route-device-build.d.ts +16 -0
  34. package/dist/cli/apple/route-device-build.d.ts.map +1 -0
  35. package/dist/cli/apple/route-device-build.js +54 -0
  36. package/dist/cli/apple/route-device-build.js.map +1 -0
  37. package/dist/cli/apple/setup.d.ts +5 -0
  38. package/dist/cli/apple/setup.d.ts.map +1 -0
  39. package/dist/cli/apple/setup.js +69 -0
  40. package/dist/cli/apple/setup.js.map +1 -0
  41. package/dist/cli/apple/shell-ipa.d.ts +7 -0
  42. package/dist/cli/apple/shell-ipa.d.ts.map +1 -0
  43. package/dist/cli/apple/shell-ipa.js +73 -0
  44. package/dist/cli/apple/shell-ipa.js.map +1 -0
  45. package/dist/cli/apple/sign-ios.d.ts +24 -0
  46. package/dist/cli/apple/sign-ios.d.ts.map +1 -0
  47. package/dist/cli/apple/sign-ios.js +148 -0
  48. package/dist/cli/apple/sign-ios.js.map +1 -0
  49. package/dist/cli/apple/status.d.ts +64 -0
  50. package/dist/cli/apple/status.d.ts.map +1 -0
  51. package/dist/cli/apple/status.js +249 -0
  52. package/dist/cli/apple/status.js.map +1 -0
  53. package/dist/cli/bin.d.ts +3 -0
  54. package/dist/cli/bin.d.ts.map +1 -0
  55. package/dist/cli/bin.js +7 -0
  56. package/dist/cli/bin.js.map +1 -0
  57. package/dist/cli/bundler.d.ts +16 -0
  58. package/dist/cli/bundler.d.ts.map +1 -0
  59. package/dist/cli/bundler.js +109 -0
  60. package/dist/cli/bundler.js.map +1 -0
  61. package/dist/cli/capsule-eas.d.ts +27 -0
  62. package/dist/cli/capsule-eas.d.ts.map +1 -0
  63. package/dist/cli/capsule-eas.js +131 -0
  64. package/dist/cli/capsule-eas.js.map +1 -0
  65. package/dist/cli/cloud/index.d.ts +14 -0
  66. package/dist/cli/cloud/index.d.ts.map +1 -0
  67. package/dist/cli/cloud/index.js +118 -0
  68. package/dist/cli/cloud/index.js.map +1 -0
  69. package/dist/cli/cloud-client.d.ts +38 -0
  70. package/dist/cli/cloud-client.d.ts.map +1 -0
  71. package/dist/cli/cloud-client.js +71 -0
  72. package/dist/cli/cloud-client.js.map +1 -0
  73. package/dist/cli/commands/auth.d.ts +2 -0
  74. package/dist/cli/commands/auth.d.ts.map +1 -0
  75. package/dist/cli/commands/auth.js +18 -0
  76. package/dist/cli/commands/auth.js.map +1 -0
  77. package/dist/cli/commands/build-native.d.ts +18 -0
  78. package/dist/cli/commands/build-native.d.ts.map +1 -0
  79. package/dist/cli/commands/build-native.js +156 -0
  80. package/dist/cli/commands/build-native.js.map +1 -0
  81. package/dist/cli/commands/build.d.ts +6 -0
  82. package/dist/cli/commands/build.d.ts.map +1 -0
  83. package/dist/cli/commands/build.js +57 -0
  84. package/dist/cli/commands/build.js.map +1 -0
  85. package/dist/cli/commands/claim.d.ts +2 -0
  86. package/dist/cli/commands/claim.d.ts.map +1 -0
  87. package/dist/cli/commands/claim.js +2 -0
  88. package/dist/cli/commands/claim.js.map +1 -0
  89. package/dist/cli/commands/db.d.ts +7 -0
  90. package/dist/cli/commands/db.d.ts.map +1 -0
  91. package/dist/cli/commands/db.js +18 -0
  92. package/dist/cli/commands/db.js.map +1 -0
  93. package/dist/cli/commands/deploy.d.ts +10 -0
  94. package/dist/cli/commands/deploy.d.ts.map +1 -0
  95. package/dist/cli/commands/deploy.js +101 -0
  96. package/dist/cli/commands/deploy.js.map +1 -0
  97. package/dist/cli/commands/dev.d.ts +5 -0
  98. package/dist/cli/commands/dev.d.ts.map +1 -0
  99. package/dist/cli/commands/dev.js +46 -0
  100. package/dist/cli/commands/dev.js.map +1 -0
  101. package/dist/cli/commands/devices.d.ts +4 -0
  102. package/dist/cli/commands/devices.d.ts.map +1 -0
  103. package/dist/cli/commands/devices.js +27 -0
  104. package/dist/cli/commands/devices.js.map +1 -0
  105. package/dist/cli/commands/domains.d.ts +5 -0
  106. package/dist/cli/commands/domains.d.ts.map +1 -0
  107. package/dist/cli/commands/domains.js +36 -0
  108. package/dist/cli/commands/domains.js.map +1 -0
  109. package/dist/cli/commands/inspect.d.ts +7 -0
  110. package/dist/cli/commands/inspect.d.ts.map +1 -0
  111. package/dist/cli/commands/inspect.js +15 -0
  112. package/dist/cli/commands/inspect.js.map +1 -0
  113. package/dist/cli/commands/logs.d.ts +7 -0
  114. package/dist/cli/commands/logs.d.ts.map +1 -0
  115. package/dist/cli/commands/logs.js +15 -0
  116. package/dist/cli/commands/logs.js.map +1 -0
  117. package/dist/cli/commands/new.d.ts +6 -0
  118. package/dist/cli/commands/new.d.ts.map +1 -0
  119. package/dist/cli/commands/new.js +17 -0
  120. package/dist/cli/commands/new.js.map +1 -0
  121. package/dist/cli/commands/open.d.ts +5 -0
  122. package/dist/cli/commands/open.d.ts.map +1 -0
  123. package/dist/cli/commands/open.js +14 -0
  124. package/dist/cli/commands/open.js.map +1 -0
  125. package/dist/cli/commands/pack.d.ts +32 -0
  126. package/dist/cli/commands/pack.d.ts.map +1 -0
  127. package/dist/cli/commands/pack.js +273 -0
  128. package/dist/cli/commands/pack.js.map +1 -0
  129. package/dist/cli/commands/screenshot.d.ts +5 -0
  130. package/dist/cli/commands/screenshot.d.ts.map +1 -0
  131. package/dist/cli/commands/screenshot.js +8 -0
  132. package/dist/cli/commands/screenshot.js.map +1 -0
  133. package/dist/cli/commands/shell-fetch.d.ts +5 -0
  134. package/dist/cli/commands/shell-fetch.d.ts.map +1 -0
  135. package/dist/cli/commands/shell-fetch.js +123 -0
  136. package/dist/cli/commands/shell-fetch.js.map +1 -0
  137. package/dist/cli/commands/shell.d.ts +2 -0
  138. package/dist/cli/commands/shell.d.ts.map +1 -0
  139. package/dist/cli/commands/shell.js +2 -0
  140. package/dist/cli/commands/shell.js.map +1 -0
  141. package/dist/cli/commands/submit.d.ts +2 -0
  142. package/dist/cli/commands/submit.d.ts.map +1 -0
  143. package/dist/cli/commands/submit.js +2 -0
  144. package/dist/cli/commands/submit.js.map +1 -0
  145. package/dist/cli/commands/tree.d.ts +5 -0
  146. package/dist/cli/commands/tree.d.ts.map +1 -0
  147. package/dist/cli/commands/tree.js +23 -0
  148. package/dist/cli/commands/tree.js.map +1 -0
  149. package/dist/cli/deploy-metadata.d.ts +10 -0
  150. package/dist/cli/deploy-metadata.d.ts.map +1 -0
  151. package/dist/cli/deploy-metadata.js +50 -0
  152. package/dist/cli/deploy-metadata.js.map +1 -0
  153. package/dist/cli/deploy-runtime.d.ts +4 -0
  154. package/dist/cli/deploy-runtime.d.ts.map +1 -0
  155. package/dist/cli/deploy-runtime.js +14 -0
  156. package/dist/cli/deploy-runtime.js.map +1 -0
  157. package/dist/cli/dev-config.d.ts +2 -0
  158. package/dist/cli/dev-config.d.ts.map +1 -0
  159. package/dist/cli/dev-config.js +36 -0
  160. package/dist/cli/dev-config.js.map +1 -0
  161. package/dist/cli/hosted-client.d.ts +39 -0
  162. package/dist/cli/hosted-client.d.ts.map +1 -0
  163. package/dist/cli/hosted-client.js +275 -0
  164. package/dist/cli/hosted-client.js.map +1 -0
  165. package/dist/cli/hosted-v1-store.d.ts +73 -0
  166. package/dist/cli/hosted-v1-store.d.ts.map +1 -0
  167. package/dist/cli/hosted-v1-store.js +96 -0
  168. package/dist/cli/hosted-v1-store.js.map +1 -0
  169. package/dist/cli/hosted.d.ts +13 -0
  170. package/dist/cli/hosted.d.ts.map +1 -0
  171. package/dist/cli/hosted.js +337 -0
  172. package/dist/cli/hosted.js.map +1 -0
  173. package/dist/cli/index.d.ts +2 -0
  174. package/dist/cli/index.d.ts.map +1 -0
  175. package/dist/cli/index.js +261 -0
  176. package/dist/cli/index.js.map +1 -0
  177. package/dist/cli/kit-paths.d.ts +8 -0
  178. package/dist/cli/kit-paths.d.ts.map +1 -0
  179. package/dist/cli/kit-paths.js +67 -0
  180. package/dist/cli/kit-paths.js.map +1 -0
  181. package/dist/cli/loader.d.ts +2 -0
  182. package/dist/cli/loader.d.ts.map +1 -0
  183. package/dist/cli/loader.js +5 -0
  184. package/dist/cli/loader.js.map +1 -0
  185. package/dist/cli/native-deploy-payload.d.ts +17 -0
  186. package/dist/cli/native-deploy-payload.d.ts.map +1 -0
  187. package/dist/cli/native-deploy-payload.js +29 -0
  188. package/dist/cli/native-deploy-payload.js.map +1 -0
  189. package/dist/cli/platform-detect.d.ts +11 -0
  190. package/dist/cli/platform-detect.d.ts.map +1 -0
  191. package/dist/cli/platform-detect.js +54 -0
  192. package/dist/cli/platform-detect.js.map +1 -0
  193. package/dist/cli/site.d.ts +6 -0
  194. package/dist/cli/site.d.ts.map +1 -0
  195. package/dist/cli/site.js +9 -0
  196. package/dist/cli/site.js.map +1 -0
  197. package/dist/cli/util.d.ts +12 -0
  198. package/dist/cli/util.d.ts.map +1 -0
  199. package/dist/cli/util.js +118 -0
  200. package/dist/cli/util.js.map +1 -0
  201. package/dist/cli/web-deploy-envelope.d.ts +15 -0
  202. package/dist/cli/web-deploy-envelope.d.ts.map +1 -0
  203. package/dist/cli/web-deploy-envelope.js +156 -0
  204. package/dist/cli/web-deploy-envelope.js.map +1 -0
  205. package/metro.lakebed-native.cjs +94 -0
  206. package/package.json +38 -0
  207. package/templates/camera-note/.env.lakebed.native.server +1 -0
  208. package/templates/camera-note/.lakebed-native/dev.json +6 -0
  209. package/templates/camera-note/.lakebed-native/metro/.expo/README.md +8 -0
  210. package/templates/camera-note/.lakebed-native/metro/.expo/devices.json +3 -0
  211. package/templates/camera-note/.lakebed-native/metro/index.js +2 -0
  212. package/templates/camera-note/.lakebed-native/metro/metro.config.js +4 -0
  213. package/templates/camera-note/.lakebed-native/metro/package.json +4 -0
  214. package/templates/camera-note/AGENTS.md +1 -0
  215. package/templates/camera-note/README.md +1 -0
  216. package/templates/camera-note/app/index.tsx +64 -0
  217. package/templates/camera-note/server/index.ts +23 -0
  218. package/templates/error-fixture/.env.lakebed.native.server +1 -0
  219. package/templates/error-fixture/.lakebed-native/dev.json +6 -0
  220. package/templates/error-fixture/.lakebed-native/metro/.expo/README.md +8 -0
  221. package/templates/error-fixture/.lakebed-native/metro/.expo/devices.json +3 -0
  222. package/templates/error-fixture/.lakebed-native/metro/index.js +2 -0
  223. package/templates/error-fixture/.lakebed-native/metro/metro.config.js +4 -0
  224. package/templates/error-fixture/.lakebed-native/metro/package.json +4 -0
  225. package/templates/error-fixture/AGENTS.md +1 -0
  226. package/templates/error-fixture/README.md +1 -0
  227. package/templates/error-fixture/app/index.tsx +31 -0
  228. package/templates/error-fixture/server/index.ts +19 -0
  229. package/templates/form/.env.lakebed.native.server +1 -0
  230. package/templates/form/.lakebed-native/dev.json +6 -0
  231. package/templates/form/.lakebed-native/metro/.expo/README.md +8 -0
  232. package/templates/form/.lakebed-native/metro/.expo/devices.json +3 -0
  233. package/templates/form/.lakebed-native/metro/index.js +2 -0
  234. package/templates/form/.lakebed-native/metro/metro.config.js +4 -0
  235. package/templates/form/.lakebed-native/metro/package.json +4 -0
  236. package/templates/form/AGENTS.md +1 -0
  237. package/templates/form/README.md +1 -0
  238. package/templates/form/app/index.tsx +56 -0
  239. package/templates/form/server/index.ts +27 -0
  240. package/templates/guestbook/.env.lakebed.native.server +1 -0
  241. package/templates/guestbook/AGENTS.md +1 -0
  242. package/templates/guestbook/README.md +3 -0
  243. package/templates/guestbook/app/index.tsx +45 -0
  244. package/templates/guestbook/server/index.ts +31 -0
  245. package/templates/location-checkin/.env.lakebed.native.server +1 -0
  246. package/templates/location-checkin/.lakebed-native/dev.json +6 -0
  247. package/templates/location-checkin/.lakebed-native/metro/.expo/README.md +8 -0
  248. package/templates/location-checkin/.lakebed-native/metro/.expo/devices.json +3 -0
  249. package/templates/location-checkin/.lakebed-native/metro/index.js +2 -0
  250. package/templates/location-checkin/.lakebed-native/metro/metro.config.js +4 -0
  251. package/templates/location-checkin/.lakebed-native/metro/package.json +4 -0
  252. package/templates/location-checkin/AGENTS.md +1 -0
  253. package/templates/location-checkin/README.md +1 -0
  254. package/templates/location-checkin/app/index.tsx +52 -0
  255. package/templates/location-checkin/server/index.ts +34 -0
  256. package/templates/tabs/.env.lakebed.native.server +1 -0
  257. package/templates/tabs/AGENTS.md +1 -0
  258. package/templates/tabs/README.md +1 -0
  259. package/templates/tabs/app/index.tsx +39 -0
  260. package/templates/tabs/server/index.ts +9 -0
  261. package/templates/todo/.env.lakebed.native.server +1 -0
  262. package/templates/todo/AGENTS.md +27 -0
  263. package/templates/todo/README.md +18 -0
  264. package/templates/todo/app/index.tsx +112 -0
  265. package/templates/todo/server/index.ts +51 -0
@@ -0,0 +1,94 @@
1
+ const path = require("path");
2
+ const fs = require("fs");
3
+
4
+ function resolvePackage(projectRoot, workspaceRoot, packageName) {
5
+ const local = path.join(projectRoot, "node_modules", packageName);
6
+ if (fs.existsSync(local)) return local;
7
+ const root = path.join(workspaceRoot, "node_modules", packageName);
8
+ if (fs.existsSync(root)) return root;
9
+ return local;
10
+ }
11
+
12
+ /** Metro resolver for Lakebed Native monorepo — maps packages and .js → .ts/.tsx */
13
+ function createLakebedNativeMetroConfig(projectRoot, workspaceRoot) {
14
+ const root = workspaceRoot ?? path.resolve(projectRoot, "..", "..", "..");
15
+ const workspace = fs.existsSync(path.join(root, "packages", "shared"))
16
+ ? root
17
+ : path.resolve(projectRoot, "..");
18
+ const { getDefaultConfig } = require("expo/metro-config");
19
+ const config = getDefaultConfig(projectRoot);
20
+
21
+ const reactRoot = resolvePackage(projectRoot, workspace, "react");
22
+ const rnRoot = resolvePackage(projectRoot, workspace, "react-native");
23
+
24
+ config.watchFolders = [workspace];
25
+ config.resolver.nodeModulesPaths = [
26
+ path.resolve(projectRoot, "node_modules"),
27
+ path.resolve(workspace, "node_modules"),
28
+ ];
29
+ const extraNodeModules = {
30
+ react: reactRoot,
31
+ "react-native": rnRoot,
32
+ "react/jsx-runtime": path.join(reactRoot, "jsx-runtime.js"),
33
+ "react/jsx-dev-runtime": path.join(reactRoot, "jsx-dev-runtime.js"),
34
+ "@lakebed-native/shared": path.resolve(workspace, "packages/shared/dist"),
35
+ "lakebed-native/client": path.resolve(workspace, "packages/client/src/client"),
36
+ "lakebed-native/ui": path.resolve(workspace, "packages/ui/src/ui"),
37
+ "lakebed-native/capabilities": path.resolve(
38
+ workspace,
39
+ "packages/capabilities/src/capabilities"
40
+ ),
41
+ };
42
+ const optionalExpoModules = [
43
+ "expo-crypto", "expo-secure-store", "expo-web-browser", "expo-linking",
44
+ ];
45
+ for (const mod of optionalExpoModules) {
46
+ const resolved = resolvePackage(projectRoot, workspace, mod);
47
+ if (fs.existsSync(resolved)) extraNodeModules[mod] = resolved;
48
+ }
49
+ config.resolver.extraNodeModules = extraNodeModules;
50
+
51
+ const defaultResolve = config.resolver.resolveRequest;
52
+ config.resolver.resolveRequest = (context, moduleName, platform) => {
53
+ if (moduleName === "react" || moduleName === "react-native") {
54
+ const root = moduleName === "react" ? reactRoot : rnRoot;
55
+ const entry = path.join(root, moduleName === "react" ? "index.js" : "index.js");
56
+ if (fs.existsSync(entry)) {
57
+ return { type: "sourceFile", filePath: entry };
58
+ }
59
+ }
60
+
61
+ // TypeScript ESM uses .js extensions; Metro needs .ts/.tsx
62
+ if (moduleName.startsWith(".") && moduleName.endsWith(".js")) {
63
+ const origin = path.dirname(context.originModulePath);
64
+ const withoutJs = path.join(origin, moduleName.slice(0, -3));
65
+ const resolved = resolveFile(withoutJs);
66
+ if (resolved) return { type: "sourceFile", filePath: resolved };
67
+ }
68
+
69
+ if (defaultResolve) {
70
+ return defaultResolve(context, moduleName, platform);
71
+ }
72
+ return context.resolveRequest(context, moduleName, platform);
73
+ };
74
+
75
+ return config;
76
+ }
77
+
78
+ function resolveFile(basePath) {
79
+ const candidates = [
80
+ basePath,
81
+ `${basePath}.tsx`,
82
+ `${basePath}.ts`,
83
+ `${basePath}.jsx`,
84
+ `${basePath}.js`,
85
+ path.join(basePath, "index.tsx"),
86
+ path.join(basePath, "index.ts"),
87
+ ];
88
+ for (const candidate of candidates) {
89
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
90
+ }
91
+ return null;
92
+ }
93
+
94
+ module.exports = { createLakebedNativeMetroConfig };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "lakebed-native-cli",
3
+ "version": "0.1.0",
4
+ "description": "Lakebed Native CLI — dev, deploy, pack, and device builds",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mawlicious/lakebed-native.git",
9
+ "directory": "packages/cli"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "templates",
17
+ "metro.lakebed-native.cjs"
18
+ ],
19
+ "type": "module",
20
+ "bin": {
21
+ "lakebed-native": "./dist/cli/bin.js"
22
+ },
23
+ "main": "./dist/cli/index.js",
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.json && node scripts/copy-kit-assets.mjs",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@lakebed-native/shared": "0.1.0",
30
+ "commander": "^13.1.0",
31
+ "esbuild": "^0.25.4",
32
+ "lakebed": "npm:@lakebed-native/server@0.1.0",
33
+ "ws": "^8.18.2"
34
+ },
35
+ "devDependencies": {
36
+ "@types/ws": "^8.18.1"
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ CAPSULE_NAME=camera-note
@@ -0,0 +1,6 @@
1
+ {
2
+ "serverUrl": "http://localhost:3000",
3
+ "bundleUrl": "http://localhost:3100/index.bundle?platform=ios&dev=true&minify=false",
4
+ "capsuleEntry": "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/camera-note/app/index.tsx",
5
+ "openUrl": "lakebed-native://capsule?server=http%3A%2F%2Flocalhost%3A3000&bundle=http%3A%2F%2Flocalhost%3A3100%2Findex.bundle%3Fplatform%3Dios%26dev%3Dtrue%26minify%3Dfalse"
6
+ }
@@ -0,0 +1,8 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
3
+ > What do the files contain?
4
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
5
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
6
+ > Should I commit the ".expo" folder?
7
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
8
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -0,0 +1,2 @@
1
+ import App from "../../app/index.tsx";
2
+ globalThis.__LAKEBED_CAPSULE_EXPORT__ = App;
@@ -0,0 +1,4 @@
1
+
2
+ const path = require('path');
3
+ const { createLakebedNativeMetroConfig } = require("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/metro.lakebed-native.cjs");
4
+ module.exports = createLakebedNativeMetroConfig("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/camera-note/.lakebed-native/metro", "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor");
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "capsule-metro",
3
+ "version": "1.0.0"
4
+ }
@@ -0,0 +1 @@
1
+ Use lakebed-native/ui first.
@@ -0,0 +1 @@
1
+ # Camera Note template
@@ -0,0 +1,64 @@
1
+ import React, { useState } from "react";
2
+ import { Router, Stack, Route, Screen, Text, Button, Input, List, Card, Image } from "lakebed-native/ui";
3
+ import { useQuery, useMutation } from "lakebed-native/client";
4
+ import { camera, imagePicker } from "lakebed-native/capabilities";
5
+
6
+ function CameraNotes() {
7
+ const { data: notes, refetch } = useQuery<Array<{ id: string; uri: string; caption: string }>>("listNotes");
8
+ const { mutate: saveNote } = useMutation<{ uri: string; caption: string }>("saveNote");
9
+ const [caption, setCaption] = useState("");
10
+ const [uri, setUri] = useState<string | null>(null);
11
+
12
+ const takePhoto = async () => {
13
+ const result = await camera.takePhoto();
14
+ if (result.ok) setUri(result.data.uri);
15
+ else alert(result.message);
16
+ };
17
+
18
+ const pickPhoto = async () => {
19
+ const result = await imagePicker.pick();
20
+ if (result.ok) setUri(result.data.uri);
21
+ else alert(result.message);
22
+ };
23
+
24
+ return (
25
+ <Screen title="Camera Notes" testID="camera-note-screen">
26
+ <Button title="Take Photo" onPress={takePhoto} testID="take-photo-button" />
27
+ <Button title="Pick Photo" onPress={pickPhoto} testID="pick-photo-button" />
28
+ {uri ? <Image source={{ uri }} style={{ width: "100%", height: 200 }} testID="preview-image" /> : null}
29
+ <Input value={caption} onChangeText={setCaption} placeholder="Caption" testID="caption-input" />
30
+ <Button
31
+ title="Save Note"
32
+ testID="save-note-button"
33
+ onPress={async () => {
34
+ if (!uri) return;
35
+ await saveNote({ uri, caption });
36
+ setCaption("");
37
+ setUri(null);
38
+ await refetch();
39
+ }}
40
+ />
41
+ <List
42
+ data={notes ?? []}
43
+ keyExtractor={(n) => n.id}
44
+ testID="notes-list"
45
+ renderItem={({ item }) => (
46
+ <Card testID={`note-${item.id}`}>
47
+ <Image source={{ uri: item.uri }} style={{ width: "100%", height: 120 }} />
48
+ <Text>{item.caption || "(no caption)"}</Text>
49
+ </Card>
50
+ )}
51
+ />
52
+ </Screen>
53
+ );
54
+ }
55
+
56
+ export default function App() {
57
+ return (
58
+ <Router>
59
+ <Stack>
60
+ <Route path="/" element={<CameraNotes />} />
61
+ </Stack>
62
+ </Router>
63
+ );
64
+ }
@@ -0,0 +1,23 @@
1
+ import { capsule, query, mutation, table, string, text } from "lakebed/server";
2
+
3
+ const notes = table("notes", {
4
+ uri: string(),
5
+ caption: text(),
6
+ });
7
+
8
+ export default capsule({
9
+ name: "camera-note",
10
+ tables: [notes],
11
+ queries: [query("listNotes", (ctx) => ctx.db.table("notes").orderBy("id", "desc").all())],
12
+ mutations: [
13
+ mutation("saveNote", (ctx, args: { uri?: string; caption?: string }) => {
14
+ if (!args?.uri) throw new Error("Photo URI required");
15
+ ctx.log.info("Saving note", { uri: args.uri });
16
+ return ctx.db.table("notes").insert({
17
+ uri: args.uri,
18
+ caption: args.caption?.trim() ?? "",
19
+ });
20
+ }),
21
+ ],
22
+ endpoints: [],
23
+ });
@@ -0,0 +1 @@
1
+ CAPSULE_NAME=error-fixture
@@ -0,0 +1,6 @@
1
+ {
2
+ "serverUrl": "http://localhost:3000",
3
+ "bundleUrl": "http://localhost:3100/index.bundle?platform=ios&dev=true&minify=false",
4
+ "capsuleEntry": "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/error-fixture/app/index.tsx",
5
+ "openUrl": "lakebed-native://capsule?server=http%3A%2F%2Flocalhost%3A3000&bundle=http%3A%2F%2Flocalhost%3A3100%2Findex.bundle%3Fplatform%3Dios%26dev%3Dtrue%26minify%3Dfalse"
6
+ }
@@ -0,0 +1,8 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
3
+ > What do the files contain?
4
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
5
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
6
+ > Should I commit the ".expo" folder?
7
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
8
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -0,0 +1,2 @@
1
+ import App from "../../app/index.tsx";
2
+ globalThis.__LAKEBED_CAPSULE_EXPORT__ = App;
@@ -0,0 +1,4 @@
1
+
2
+ const path = require('path');
3
+ const { createLakebedNativeMetroConfig } = require("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/metro.lakebed-native.cjs");
4
+ module.exports = createLakebedNativeMetroConfig("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/error-fixture/.lakebed-native/metro", "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor");
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "capsule-metro",
3
+ "version": "1.0.0"
4
+ }
@@ -0,0 +1 @@
1
+ Use lakebed-native/ui first.
@@ -0,0 +1 @@
1
+ # Error fixture template for logs E2E testing
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { Router, Stack, Route, Screen, Button, Text } from "lakebed-native/ui";
3
+ import { useMutation } from "lakebed-native/client";
4
+
5
+ function ErrorFixture() {
6
+ const { mutate: triggerServer } = useMutation("triggerServerError");
7
+
8
+ return (
9
+ <Screen title="Error Fixture" testID="error-fixture-screen">
10
+ <Button
11
+ title="Trigger JS Error"
12
+ testID="trigger-js-error"
13
+ onPress={() => {
14
+ throw new Error("Client-side E2E error");
15
+ }}
16
+ />
17
+ <Button
18
+ title="Trigger Server Error"
19
+ testID="trigger-server-error"
20
+ onPress={() => triggerServer({})}
21
+ />
22
+ <Text testID="error-fixture-hint">Use logs CLI after triggering errors</Text>
23
+ </Screen>
24
+ );
25
+ }
26
+
27
+ export default function App() {
28
+ return (
29
+ <Router><Stack><Route path="/" element={<ErrorFixture />} /></Stack></Router>
30
+ );
31
+ }
@@ -0,0 +1,19 @@
1
+ import { capsule, query, mutation } from "lakebed/server";
2
+
3
+ export default capsule({
4
+ name: "error-fixture",
5
+ tables: [],
6
+ queries: [
7
+ query("triggerError", () => {
8
+ throw new Error("Intentional E2E error fixture");
9
+ }),
10
+ ],
11
+ mutations: [
12
+ mutation("triggerServerError", (ctx) => {
13
+ ctx.log.error("Intentional E2E server error");
14
+ throw new Error("Intentional E2E server error");
15
+ }),
16
+ mutation("triggerClientError", () => ({ ok: true })),
17
+ ],
18
+ endpoints: [],
19
+ });
@@ -0,0 +1 @@
1
+ CAPSULE_NAME=form
@@ -0,0 +1,6 @@
1
+ {
2
+ "serverUrl": "http://localhost:3000",
3
+ "bundleUrl": "http://localhost:3100/index.bundle?platform=ios&dev=true&minify=false",
4
+ "capsuleEntry": "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/form/app/index.tsx",
5
+ "openUrl": "lakebed-native://capsule?server=http%3A%2F%2Flocalhost%3A3000&bundle=http%3A%2F%2Flocalhost%3A3100%2Findex.bundle%3Fplatform%3Dios%26dev%3Dtrue%26minify%3Dfalse"
6
+ }
@@ -0,0 +1,8 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
3
+ > What do the files contain?
4
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
5
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
6
+ > Should I commit the ".expo" folder?
7
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
8
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -0,0 +1,3 @@
1
+ {
2
+ "devices": []
3
+ }
@@ -0,0 +1,2 @@
1
+ import App from "../../app/index.tsx";
2
+ globalThis.__LAKEBED_CAPSULE_EXPORT__ = App;
@@ -0,0 +1,4 @@
1
+
2
+ const path = require('path');
3
+ const { createLakebedNativeMetroConfig } = require("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/metro.lakebed-native.cjs");
4
+ module.exports = createLakebedNativeMetroConfig("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/form/.lakebed-native/metro", "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor");
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "capsule-metro",
3
+ "version": "1.0.0"
4
+ }
@@ -0,0 +1 @@
1
+ Use lakebed-native/ui first.
@@ -0,0 +1 @@
1
+ # Form template
@@ -0,0 +1,56 @@
1
+ import React, { useState } from "react";
2
+ import { Router, Stack, Route, Screen, Form, Field, Input, TextArea, Text, List, Card } from "lakebed-native/ui";
3
+ import { useQuery, useMutation } from "lakebed-native/client";
4
+
5
+ function FormScreen() {
6
+ const { mutate: submitForm } = useMutation<{ name: string; email: string; notes: string }>("submitForm");
7
+ const { data: submissions, refetch } = useQuery<Array<{ id: string; name: string; email: string; notes: string }>>("listSubmissions");
8
+ const [name, setName] = useState("");
9
+ const [email, setEmail] = useState("");
10
+ const [notes, setNotes] = useState("");
11
+
12
+ return (
13
+ <Screen title="Contact Form" testID="form-screen">
14
+ <Form
15
+ onSubmit={async () => {
16
+ await submitForm({ name, email, notes });
17
+ setName("");
18
+ setEmail("");
19
+ setNotes("");
20
+ await refetch();
21
+ }}
22
+ >
23
+ <Field label="Name">
24
+ <Input value={name} onChangeText={setName} testID="form-name" />
25
+ </Field>
26
+ <Field label="Email">
27
+ <Input value={email} onChangeText={setEmail} testID="form-email" />
28
+ </Field>
29
+ <Field label="Notes">
30
+ <TextArea value={notes} onChangeText={setNotes} testID="form-notes" />
31
+ </Field>
32
+ </Form>
33
+ <List
34
+ data={submissions ?? []}
35
+ keyExtractor={(s) => s.id}
36
+ testID="submissions-list"
37
+ renderItem={({ item }) => (
38
+ <Card testID={`submission-${item.id}`}>
39
+ <Text>{item.name} — {item.email}</Text>
40
+ <Text>{item.notes}</Text>
41
+ </Card>
42
+ )}
43
+ />
44
+ </Screen>
45
+ );
46
+ }
47
+
48
+ export default function App() {
49
+ return (
50
+ <Router>
51
+ <Stack>
52
+ <Route path="/" element={<FormScreen />} />
53
+ </Stack>
54
+ </Router>
55
+ );
56
+ }
@@ -0,0 +1,27 @@
1
+ import { capsule, query, mutation, table, string, text } from "lakebed/server";
2
+
3
+ const submissions = table("submissions", {
4
+ name: string(),
5
+ email: string(),
6
+ notes: text(),
7
+ });
8
+
9
+ export default capsule({
10
+ name: "form",
11
+ tables: [submissions],
12
+ queries: [query("listSubmissions", (ctx) => ctx.db.table("submissions").all())],
13
+ mutations: [
14
+ mutation("submitForm", (ctx, args: { name?: string; email?: string; notes?: string }) => {
15
+ const name = args?.name?.trim();
16
+ const email = args?.email?.trim();
17
+ if (!name) throw new Error("Name is required");
18
+ if (!email) throw new Error("Email is required");
19
+ return ctx.db.table("submissions").insert({
20
+ name,
21
+ email,
22
+ notes: args?.notes?.trim() ?? "",
23
+ });
24
+ }),
25
+ ],
26
+ endpoints: [],
27
+ });
@@ -0,0 +1 @@
1
+ CAPSULE_NAME=guestbook
@@ -0,0 +1 @@
1
+ Use lakebed-native/ui first. See todo template AGENTS.md for rules.
@@ -0,0 +1,3 @@
1
+ # Guestbook
2
+
3
+ Shared feed capsule template.
@@ -0,0 +1,45 @@
1
+ import React, { useState } from "react";
2
+ import { Router, Stack, Route, Screen, Text, Button, Input, List, Card } from "lakebed-native/ui";
3
+ import { useQuery, useMutation } from "lakebed-native/client";
4
+
5
+ function Guestbook() {
6
+ const { data: entries, refetch } = useQuery<Array<{ id: string; authorName: string; message: string }>>("listEntries");
7
+ const { mutate: addEntry } = useMutation<{ message: string }>("addEntry");
8
+ const [message, setMessage] = useState("");
9
+
10
+ return (
11
+ <Screen title="Guestbook" testID="guestbook-screen">
12
+ <Input value={message} onChangeText={setMessage} placeholder="Leave a message" testID="guestbook-input" />
13
+ <Button
14
+ title="Sign Guestbook"
15
+ testID="add-entry-button"
16
+ onPress={async () => {
17
+ await addEntry({ message });
18
+ setMessage("");
19
+ await refetch();
20
+ }}
21
+ />
22
+ <List
23
+ data={entries ?? []}
24
+ keyExtractor={(e) => e.id}
25
+ testID="guestbook-list"
26
+ renderItem={({ item }) => (
27
+ <Card testID={`entry-${item.id}`}>
28
+ <Text style={{ fontWeight: "600" }}>{item.authorName}</Text>
29
+ <Text>{item.message}</Text>
30
+ </Card>
31
+ )}
32
+ />
33
+ </Screen>
34
+ );
35
+ }
36
+
37
+ export default function App() {
38
+ return (
39
+ <Router>
40
+ <Stack>
41
+ <Route path="/" title="Guestbook" element={<Guestbook />} />
42
+ </Stack>
43
+ </Router>
44
+ );
45
+ }
@@ -0,0 +1,31 @@
1
+ import { capsule, query, mutation, table, string, text } from "lakebed/server";
2
+
3
+ const entries = table("entries", {
4
+ authorId: string(),
5
+ authorName: string(),
6
+ message: text(),
7
+ });
8
+
9
+ export default capsule({
10
+ name: "guestbook",
11
+ tables: [entries],
12
+ queries: [
13
+ query("listEntries", (ctx) =>
14
+ ctx.db.table("entries").orderBy("id", "desc").limit(50).all()
15
+ ),
16
+ ],
17
+ mutations: [
18
+ mutation("addEntry", (ctx, args: { message?: string }) => {
19
+ const message = args?.message?.trim() ?? "";
20
+ if (!message) throw new Error("Message is required");
21
+ if (message.length > 280) throw new Error("Message must be 280 characters or less");
22
+ const user = ctx.auth.user;
23
+ return ctx.db.table("entries").insert({
24
+ authorId: user?.id ?? "guest",
25
+ authorName: user?.name ?? "Guest",
26
+ message,
27
+ });
28
+ }),
29
+ ],
30
+ endpoints: [],
31
+ });
@@ -0,0 +1 @@
1
+ CAPSULE_NAME=location-checkin
@@ -0,0 +1,6 @@
1
+ {
2
+ "serverUrl": "http://localhost:3000",
3
+ "bundleUrl": "http://localhost:3100/index.bundle?platform=ios&dev=true&minify=false",
4
+ "capsuleEntry": "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/location-checkin/app/index.tsx",
5
+ "openUrl": "lakebed-native://capsule?server=http%3A%2F%2Flocalhost%3A3000&bundle=http%3A%2F%2Flocalhost%3A3100%2Findex.bundle%3Fplatform%3Dios%26dev%3Dtrue%26minify%3Dfalse"
6
+ }
@@ -0,0 +1,8 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
3
+ > What do the files contain?
4
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
5
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
6
+ > Should I commit the ".expo" folder?
7
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
8
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -0,0 +1,2 @@
1
+ import App from "../../app/index.tsx";
2
+ globalThis.__LAKEBED_CAPSULE_EXPORT__ = App;
@@ -0,0 +1,4 @@
1
+
2
+ const path = require('path');
3
+ const { createLakebedNativeMetroConfig } = require("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/metro.lakebed-native.cjs");
4
+ module.exports = createLakebedNativeMetroConfig("/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor/templates/location-checkin/.lakebed-native/metro", "/Users/yahiaelramal/MAS_Projects/lakebed-native-cursor");
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "capsule-metro",
3
+ "version": "1.0.0"
4
+ }
@@ -0,0 +1 @@
1
+ Use lakebed-native/ui first.