@liquidmetal-ai/raindrop 0.13.0 → 0.15.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 (250) hide show
  1. package/README.md +327 -89
  2. package/bundle/build-CBEGQPJT.js +62 -0
  3. package/bundle/{chunk-IEF2XC25.js → chunk-2PH3PHH3.js} +5 -3
  4. package/bundle/{chunk-4HZ22KOV.js → chunk-3CMR7ES5.js} +4 -4
  5. package/bundle/{chunk-JSBM2JYW.js → chunk-3EYKCHIK.js} +1 -1
  6. package/bundle/chunk-5XHDP4VK.js +1697 -0
  7. package/bundle/{chunk-TSQK4HH6.js → chunk-674GMSXY.js} +1 -1
  8. package/bundle/{chunk-PS3WZBDF.js → chunk-6L4V66WZ.js} +1105 -2728
  9. package/bundle/{chunk-5245CEUM.js → chunk-AGG7JZVH.js} +2 -2
  10. package/bundle/{chunk-3GFKUF5D.js → chunk-B3IY2XS6.js} +4 -2
  11. package/bundle/{chunk-WIDI65NO.js → chunk-CBAXTRCS.js} +1 -1
  12. package/bundle/{chunk-JLVDTXO2.js → chunk-DPV5HIG7.js} +4 -4
  13. package/bundle/{chunk-36GNZK4A.js → chunk-EVXLXWP7.js} +1 -1
  14. package/bundle/{chunk-4YVU5KEQ.js → chunk-HN3AAKRY.js} +4 -2
  15. package/bundle/{chunk-NVNEQXHN.js → chunk-IGLE4Y3B.js} +7 -5
  16. package/bundle/{chunk-FGSYWVBA.js → chunk-IQ6HFRA6.js} +1 -1
  17. package/bundle/{chunk-O3QZDJ75.js → chunk-JQONDSHY.js} +2 -2
  18. package/bundle/{chunk-W4IPOFZC.js → chunk-KADMFJLN.js} +8 -6
  19. package/bundle/chunk-KG5BLUGU.js +246 -0
  20. package/bundle/{chunk-V5LHJTYS.js → chunk-KLOYSTZY.js} +13 -2
  21. package/bundle/{chunk-ETC5VU7H.js → chunk-KXHVSLAI.js} +1 -1
  22. package/bundle/{chunk-Y4WFGNPM.js → chunk-L6FRQULN.js} +1 -1
  23. package/bundle/{chunk-3QCVYSRU.js → chunk-LT3BFQ4O.js} +1 -1
  24. package/bundle/{chunk-KQZJHBNG.js → chunk-MBLKVNI5.js} +1 -1
  25. package/bundle/{chunk-6AIUQUUM.js → chunk-MFMVJZW6.js} +71 -15
  26. package/bundle/{chunk-25T7MEKO.js → chunk-MJBLNWG3.js} +1 -1
  27. package/bundle/{chunk-MSJ33O5Y.js → chunk-NRCQIE3Z.js} +95 -115
  28. package/bundle/{chunk-XKKPPSPC.js → chunk-OCYTN4IH.js} +2 -2
  29. package/bundle/{chunk-2GAMWFJE.js → chunk-QEF5D4VE.js} +1 -1
  30. package/bundle/{chunk-4B3QYXBA.js → chunk-T7MQCLXF.js} +5 -3
  31. package/bundle/{chunk-LDFYPOXJ.js → chunk-TFQY5TSY.js} +1 -1
  32. package/bundle/{chunk-BWK4MC7Y.js → chunk-USZXZZAR.js} +8 -6
  33. package/bundle/{chunk-ER2RCPCY.js → chunk-V54KHS5B.js} +2 -2
  34. package/bundle/{chunk-YSKASURB.js → chunk-V6J23FL2.js} +1 -1
  35. package/bundle/{chunk-UHSTDJ7X.js → chunk-VN2QYX4C.js} +1 -1
  36. package/bundle/{chunk-Z4OWKG7J.js → chunk-VOT5MMEY.js} +1 -1
  37. package/bundle/{chunk-W6GU26WO.js → chunk-WG6BDFPZ.js} +1 -1
  38. package/bundle/{chunk-AK77X5GL.js → chunk-XX74I5RK.js} +4 -2
  39. package/bundle/{chunk-6BT265R3.js → chunk-YQCRWPNI.js} +1 -1
  40. package/bundle/commands/annotation/get.js +3 -3
  41. package/bundle/commands/annotation/list.js +3 -3
  42. package/bundle/commands/annotation/put.js +3 -3
  43. package/bundle/commands/auth/apikey.js +2 -2
  44. package/bundle/commands/auth/list.js +2 -2
  45. package/bundle/commands/auth/login.js +2 -2
  46. package/bundle/commands/auth/logout.js +2 -2
  47. package/bundle/commands/auth/select.js +3 -3
  48. package/bundle/commands/bucket/create-credential.js +2 -2
  49. package/bundle/commands/bucket/delete-credential.js +2 -2
  50. package/bundle/commands/bucket/get-credential.js +2 -2
  51. package/bundle/commands/bucket/list-credentials.js +2 -2
  52. package/bundle/commands/build/actor/setup.js +124 -0
  53. package/bundle/commands/build/branch.js +10 -10
  54. package/bundle/commands/build/bucket-events/setup.js +146 -0
  55. package/bundle/commands/build/checkout.js +8 -8
  56. package/bundle/commands/build/clone.js +6 -6
  57. package/bundle/commands/build/delete.js +8 -8
  58. package/bundle/commands/build/deploy.js +10 -10
  59. package/bundle/commands/build/env/get.js +3 -3
  60. package/bundle/commands/build/env/list.js +2 -2
  61. package/bundle/commands/build/env/set.js +3 -3
  62. package/bundle/commands/build/env.js +2 -2
  63. package/bundle/commands/build/features.js +192 -0
  64. package/bundle/commands/build/find.js +4 -4
  65. package/bundle/commands/build/generate.js +52 -3
  66. package/bundle/commands/build/init-workspace.js +3 -3
  67. package/bundle/commands/build/init.js +15 -3
  68. package/bundle/commands/build/list.js +5 -5
  69. package/bundle/commands/build/queue/setup.js +133 -0
  70. package/bundle/commands/build/sandbox.js +6 -6
  71. package/bundle/commands/build/smartbucket/setup.js +165 -0
  72. package/bundle/commands/build/smartmemory/setup.js +171 -0
  73. package/bundle/commands/build/smartsql/setup.js +167 -0
  74. package/bundle/commands/build/start.js +2 -2
  75. package/bundle/commands/build/status.js +5 -5
  76. package/bundle/commands/build/stop.js +2 -2
  77. package/bundle/commands/build/stripe/dashboard.js +3 -3
  78. package/bundle/commands/build/stripe/onboard.js +3 -3
  79. package/bundle/commands/build/stripe/setup.js +3 -3
  80. package/bundle/commands/build/stripe/start.js +14 -14
  81. package/bundle/commands/build/stripe/status.js +3 -3
  82. package/bundle/commands/build/stripe/subscription/create.js +4 -4
  83. package/bundle/commands/build/stripe/subscription/get.js +4 -4
  84. package/bundle/commands/build/stripe/subscription/update.js +4 -4
  85. package/bundle/commands/build/tools/check.js +2 -2
  86. package/bundle/commands/build/tools/fmt.js +2 -2
  87. package/bundle/commands/build/unsandbox.js +6 -6
  88. package/bundle/commands/build/upload.js +5 -5
  89. package/bundle/commands/build/validate.js +85 -14
  90. package/bundle/commands/build/workos/delete.js +6 -6
  91. package/bundle/commands/build/workos/env/attach.js +3 -3
  92. package/bundle/commands/build/workos/env/attached.js +3 -3
  93. package/bundle/commands/build/workos/env/create.js +3 -3
  94. package/bundle/commands/build/workos/env/delete.js +3 -3
  95. package/bundle/commands/build/workos/env/detach.js +3 -3
  96. package/bundle/commands/build/workos/env/dev-login.js +3 -3
  97. package/bundle/commands/build/workos/env/get.js +3 -3
  98. package/bundle/commands/build/workos/env/list.js +3 -3
  99. package/bundle/commands/build/workos/env/set.js +3 -3
  100. package/bundle/commands/build/workos/invite.js +3 -3
  101. package/bundle/commands/build/workos/jwt.js +172 -0
  102. package/bundle/commands/build/workos/setup.js +3 -3
  103. package/bundle/commands/build/workos/status.js +3 -3
  104. package/bundle/commands/dns/create.js +2 -2
  105. package/bundle/commands/dns/delete.js +6 -6
  106. package/bundle/commands/dns/get.js +6 -6
  107. package/bundle/commands/dns/list.js +3 -3
  108. package/bundle/commands/dns/records/create.js +2 -2
  109. package/bundle/commands/dns/records/delete.js +3 -3
  110. package/bundle/commands/dns/records/get.js +2 -2
  111. package/bundle/commands/dns/records/list.js +2 -2
  112. package/bundle/commands/dns/records/update.js +2 -2
  113. package/bundle/commands/doctor.js +309 -0
  114. package/bundle/commands/logs/query.js +3 -3
  115. package/bundle/commands/logs/tail.js +3 -3
  116. package/bundle/commands/mcp/install-claude.js +2 -2
  117. package/bundle/commands/mcp/install-gemini.js +2 -2
  118. package/bundle/commands/mcp/install-goose.js +2 -2
  119. package/bundle/commands/mcp/status.js +2 -2
  120. package/bundle/commands/object/delete.js +5 -37
  121. package/bundle/commands/object/get.js +5 -37
  122. package/bundle/commands/object/list.js +7 -39
  123. package/bundle/commands/object/put.js +5 -37
  124. package/bundle/commands/query/chunk-search.js +14 -46
  125. package/bundle/commands/query/document.js +17 -55
  126. package/bundle/commands/query/events.js +2 -2
  127. package/bundle/commands/query/reindex.js +2 -2
  128. package/bundle/commands/query/search.js +14 -46
  129. package/bundle/commands/tail.js +2 -2
  130. package/bundle/index.js +1 -1
  131. package/dist/commands/build/actor/setup.d.ts +22 -0
  132. package/dist/commands/build/actor/setup.d.ts.map +1 -0
  133. package/dist/commands/build/actor/setup.js +116 -0
  134. package/dist/commands/build/bucket-events/setup.d.ts +22 -0
  135. package/dist/commands/build/bucket-events/setup.d.ts.map +1 -0
  136. package/dist/commands/build/bucket-events/setup.js +134 -0
  137. package/dist/commands/build/features.d.ts +19 -0
  138. package/dist/commands/build/features.d.ts.map +1 -0
  139. package/dist/commands/build/features.js +97 -0
  140. package/dist/commands/build/generate.d.ts +2 -0
  141. package/dist/commands/build/generate.d.ts.map +1 -1
  142. package/dist/commands/build/generate.js +52 -0
  143. package/dist/commands/build/init.d.ts.map +1 -1
  144. package/dist/commands/build/init.js +10 -0
  145. package/dist/commands/build/queue/setup.d.ts +21 -0
  146. package/dist/commands/build/queue/setup.d.ts.map +1 -0
  147. package/dist/commands/build/queue/setup.js +120 -0
  148. package/dist/commands/build/smartbucket/setup.d.ts +23 -0
  149. package/dist/commands/build/smartbucket/setup.d.ts.map +1 -0
  150. package/dist/commands/build/smartbucket/setup.js +167 -0
  151. package/dist/commands/build/smartmemory/setup.d.ts +23 -0
  152. package/dist/commands/build/smartmemory/setup.d.ts.map +1 -0
  153. package/dist/commands/build/smartmemory/setup.js +172 -0
  154. package/dist/commands/build/smartsql/setup.d.ts +23 -0
  155. package/dist/commands/build/smartsql/setup.d.ts.map +1 -0
  156. package/dist/commands/build/smartsql/setup.js +169 -0
  157. package/dist/commands/build/validate.d.ts +2 -0
  158. package/dist/commands/build/validate.d.ts.map +1 -1
  159. package/dist/commands/build/validate.js +80 -8
  160. package/dist/commands/build/workos/jwt.d.ts +23 -0
  161. package/dist/commands/build/workos/jwt.d.ts.map +1 -0
  162. package/dist/commands/build/workos/jwt.js +172 -0
  163. package/dist/commands/doctor.d.ts +27 -0
  164. package/dist/commands/doctor.d.ts.map +1 -0
  165. package/dist/commands/doctor.js +328 -0
  166. package/dist/commands/object/delete.d.ts +0 -2
  167. package/dist/commands/object/delete.d.ts.map +1 -1
  168. package/dist/commands/object/delete.js +3 -38
  169. package/dist/commands/object/get.d.ts +0 -2
  170. package/dist/commands/object/get.d.ts.map +1 -1
  171. package/dist/commands/object/get.js +3 -38
  172. package/dist/commands/object/list.d.ts +0 -2
  173. package/dist/commands/object/list.d.ts.map +1 -1
  174. package/dist/commands/object/list.js +5 -40
  175. package/dist/commands/object/put.d.ts +0 -2
  176. package/dist/commands/object/put.d.ts.map +1 -1
  177. package/dist/commands/object/put.js +3 -38
  178. package/dist/commands/query/chunk-search.d.ts +0 -2
  179. package/dist/commands/query/chunk-search.d.ts.map +1 -1
  180. package/dist/commands/query/chunk-search.js +12 -46
  181. package/dist/commands/query/document.d.ts +1 -3
  182. package/dist/commands/query/document.d.ts.map +1 -1
  183. package/dist/commands/query/document.js +16 -60
  184. package/dist/commands/query/search.d.ts +0 -2
  185. package/dist/commands/query/search.d.ts.map +1 -1
  186. package/dist/commands/query/search.js +12 -46
  187. package/dist/feature-catalog.d.ts +28 -0
  188. package/dist/feature-catalog.d.ts.map +1 -0
  189. package/dist/feature-catalog.js +104 -0
  190. package/dist/index.d.ts.map +1 -1
  191. package/dist/index.js +16 -2
  192. package/oclif.manifest.json +4811 -3433
  193. package/package.json +3 -3
  194. package/templates/examples/smartbucket-minimal.ts.hbs +87 -0
  195. package/templates/examples/smartmemory-minimal.ts.hbs +82 -0
  196. package/templates/examples/smartsql-minimal.ts.hbs +69 -0
  197. package/templates/handlers/actor/index.test.ts.hbs +48 -85
  198. package/templates/handlers/actor/index.ts.hbs +16 -316
  199. package/templates/handlers/bucket-event-notification/index.ts.hbs +32 -235
  200. package/templates/handlers/bucket-event-observer.ts.hbs +79 -0
  201. package/templates/handlers/http-service/index.test.ts.hbs +3 -0
  202. package/templates/handlers/http-service/index.ts.hbs +43 -15
  203. package/templates/handlers/queue-consumer-setup.ts.hbs +45 -0
  204. package/templates/handlers/task/index.test.ts.hbs +30 -112
  205. package/templates/handlers/task/index.ts.hbs +19 -58
  206. package/templates/init/RAINDROP.md.hbs +97 -1
  207. package/templates/init/eslint.config.js +43 -0
  208. package/templates/init/package.json.hbs +4 -1
  209. package/templates/init/tsconfig.json +3 -3
  210. package/bundle/chunk-23UBI7BN.js +0 -48
  211. package/bundle/chunk-2QWMBNE3.js +0 -384
  212. package/bundle/chunk-45IYWQDC.js +0 -384
  213. package/bundle/chunk-5YUO23QU.js +0 -4585
  214. package/bundle/chunk-6MIGCNUO.js +0 -75
  215. package/bundle/chunk-7ZJWA6HP.js +0 -805
  216. package/bundle/chunk-AIYVX2M7.js +0 -44
  217. package/bundle/chunk-BB5TNIEM.js +0 -48
  218. package/bundle/chunk-BUR3HFKH.js +0 -488
  219. package/bundle/chunk-BYSBS7KT.js +0 -488
  220. package/bundle/chunk-CX3RWI62.js +0 -28658
  221. package/bundle/chunk-DLH7MI57.js +0 -305
  222. package/bundle/chunk-E3WJIYJZ.js +0 -12148
  223. package/bundle/chunk-EX7NOPRF.js +0 -12148
  224. package/bundle/chunk-F76JQS2J.js +0 -231
  225. package/bundle/chunk-FBOXMVKD.js +0 -28679
  226. package/bundle/chunk-FTPZ6SQW.js +0 -238909
  227. package/bundle/chunk-H3CFZ7ZH.js +0 -74
  228. package/bundle/chunk-HXOILVWA.js +0 -384
  229. package/bundle/chunk-IMP7O5AC.js +0 -22452
  230. package/bundle/chunk-IPYOAKRE.js +0 -231
  231. package/bundle/chunk-J7HN6XF2.js +0 -4461
  232. package/bundle/chunk-JOLOAALA.js +0 -231
  233. package/bundle/chunk-JZ2G4Q35.js +0 -4585
  234. package/bundle/chunk-KVAWPWF7.js +0 -231
  235. package/bundle/chunk-MEUAAIXV.js +0 -28657
  236. package/bundle/chunk-QBWFE57Z.js +0 -384
  237. package/bundle/chunk-SP3LOXPC.js +0 -46
  238. package/bundle/chunk-T7C564PR.js +0 -28678
  239. package/bundle/chunk-UFH545WJ.js +0 -22452
  240. package/bundle/chunk-UHVMPWM5.js +0 -315
  241. package/bundle/chunk-VB7ZTSZV.js +0 -1089
  242. package/bundle/chunk-VBIJDFMJ.js +0 -384
  243. package/bundle/chunk-VR7RLTE3.js +0 -231
  244. package/bundle/chunk-WFZUJLEC.js +0 -231
  245. package/bundle/chunk-YDGJTLVZ.js +0 -133
  246. package/bundle/chunk-YPNQ7UFK.js +0 -502
  247. package/bundle/chunk-YXFDRMSN.js +0 -384
  248. package/dist/lib/dns-utils.d.ts +0 -7
  249. package/dist/lib/dns-utils.d.ts.map +0 -1
  250. package/dist/lib/dns-utils.js +0 -44
@@ -0,0 +1,169 @@
1
+ import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import * as fs from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ import { BaseCommand } from '../../../base-command.js';
6
+ import { renderTemplateFromFile, TEMPLATES_DIR } from '../../../codegen.js';
7
+ export default class SmartSqlSetup extends BaseCommand {
8
+ static args = {};
9
+ static description = 'Add SmartSQL (PostgreSQL with natural language queries) to your Raindrop app';
10
+ static examples = [
11
+ `<%= config.bin %> <%= command.id %>
12
+ Add SmartSQL with default name "my-database"
13
+
14
+ <%= config.bin %> <%= command.id %> --name orders-db
15
+ Add SmartSQL with custom name "orders-db"
16
+ `,
17
+ ];
18
+ static flags = {
19
+ ...BaseCommand.HIDDEN_FLAGS,
20
+ name: Flags.string({
21
+ description: 'Name for the SmartSQL binding',
22
+ default: 'my-database',
23
+ }),
24
+ 'dry-run': Flags.boolean({
25
+ description: 'Preview changes without applying them',
26
+ default: false,
27
+ }),
28
+ };
29
+ async run() {
30
+ // Check if binding already exists in manifest, use that name if found
31
+ const existingBinding = await this.findExistingBinding('smartsql');
32
+ const manifestName = existingBinding || this.flags.name;
33
+ const bindingName = manifestName.toUpperCase().replace(/-/g, '_');
34
+ const dryRun = this.flags['dry-run'];
35
+ // Find the first handler (service/actor/observer/task) to determine import path
36
+ const handlerName = await this.findFirstHandler();
37
+ // If no handler found, warn user and provide guidance
38
+ if (!handlerName) {
39
+ this.log(chalk.yellow.bold('⚠ No service, actor, observer, or task found in manifest'));
40
+ this.log('');
41
+ this.log('SmartSQL examples require a handler to generate type-safe code.');
42
+ this.log('Please add a handler to your manifest first:');
43
+ this.log('');
44
+ this.log(chalk.cyan(' service "api" {'));
45
+ this.log(chalk.cyan(' visibility = "public"'));
46
+ this.log(chalk.cyan(' }'));
47
+ this.log('');
48
+ this.log('Then run:');
49
+ this.log(chalk.bold(' raindrop build generate'));
50
+ this.log(chalk.bold(' raindrop build smartsql setup'));
51
+ return;
52
+ }
53
+ if (dryRun) {
54
+ this.log(chalk.blue.bold('DRY RUN - Preview of changes (no files will be modified)'));
55
+ this.log('');
56
+ this.log(chalk.blue('Would create:') + ' ' + chalk.bold('src/examples/smartsql-minimal.ts'));
57
+ this.log(chalk.dim(' - 55 lines of example code'));
58
+ this.log(chalk.dim(' - SQL queries, natural language queries, metadata management'));
59
+ this.log('');
60
+ this.log(chalk.blue('Would update:') + ' ' + chalk.bold('raindrop.manifest'));
61
+ this.log(chalk.dim(` + smartsql "${manifestName}" {}`));
62
+ this.log('');
63
+ this.log(chalk.blue('Environment binding:') + ' ' + chalk.bold(`this.env.${bindingName}`));
64
+ this.log('');
65
+ this.log(chalk.yellow('Run without --dry-run to apply these changes'));
66
+ return;
67
+ }
68
+ try {
69
+ // Step 1: Create examples directory if it doesn't exist
70
+ const examplesDir = path.join(process.cwd(), 'src', 'examples');
71
+ await fs.mkdir(examplesDir, { recursive: true });
72
+ // Step 2: Generate example file
73
+ const exampleContent = await this.generateExampleFile(bindingName, handlerName);
74
+ const examplePath = path.join(examplesDir, 'smartsql-minimal.ts');
75
+ await fs.writeFile(examplePath, exampleContent);
76
+ this.log(chalk.green('✓') + ' Created ' + chalk.bold('src/examples/smartsql-minimal.ts'));
77
+ // Step 3: Update manifest
78
+ await this.updateManifest(manifestName);
79
+ this.log(chalk.green('✓') + ' Updated ' + chalk.bold('raindrop.manifest'));
80
+ // Step 4: Show next steps
81
+ this.log('');
82
+ this.log(chalk.bold.cyan('Next Steps:'));
83
+ this.log('');
84
+ this.log('1. Run ' + chalk.bold('raindrop build generate') + ' to update types');
85
+ this.log('2. Check out ' + chalk.bold('src/examples/smartsql-minimal.ts') + ' for example code');
86
+ this.log('3. Use ' + chalk.bold(`this.env.${bindingName}`) + ' in your handlers to query your database');
87
+ this.log('');
88
+ this.log(chalk.dim('Example usage:'));
89
+ this.log(chalk.dim(` const result = await this.env.${bindingName}.executeQuery({`));
90
+ this.log(chalk.dim(` sqlQuery: 'SELECT * FROM users',`));
91
+ this.log(chalk.dim(` format: 'json'`));
92
+ this.log(chalk.dim(` });`));
93
+ this.log('');
94
+ }
95
+ catch (error) {
96
+ this.error(`Failed to set up SmartSQL: ${error instanceof Error ? error.message : 'Unknown error'}`);
97
+ }
98
+ }
99
+ async generateExampleFile(bindingName, handlerName) {
100
+ const templatePath = path.join(TEMPLATES_DIR, 'examples', 'smartsql-minimal.ts.hbs');
101
+ return renderTemplateFromFile(templatePath, { bindingName, handlerName });
102
+ }
103
+ async findExistingBinding(bindingType) {
104
+ const manifestPath = path.join(process.cwd(), 'raindrop.manifest');
105
+ try {
106
+ const content = await fs.readFile(manifestPath, 'utf-8');
107
+ const regex = new RegExp(`^\\s*${bindingType}\\s+"([^"]+)"`, 'm');
108
+ const match = content.match(regex);
109
+ return match?.[1] || null;
110
+ }
111
+ catch (_error) {
112
+ return null;
113
+ }
114
+ }
115
+ async findFirstHandler() {
116
+ const manifestPath = path.join(process.cwd(), 'raindrop.manifest');
117
+ try {
118
+ const content = await fs.readFile(manifestPath, 'utf-8');
119
+ // Look for first uncommented service, actor, observer, or task
120
+ const serviceMatch = content.match(/^\s*service\s+"([^"]+)"/m);
121
+ if (serviceMatch?.[1])
122
+ return serviceMatch[1];
123
+ const actorMatch = content.match(/^\s*actor\s+"([^"]+)"/m);
124
+ if (actorMatch?.[1])
125
+ return actorMatch[1];
126
+ const observerMatch = content.match(/^\s*observer\s+"([^"]+)"/m);
127
+ if (observerMatch?.[1])
128
+ return observerMatch[1];
129
+ const taskMatch = content.match(/^\s*task\s+"([^"]+)"/m);
130
+ if (taskMatch?.[1])
131
+ return taskMatch[1];
132
+ // Return null if no handler found
133
+ return null;
134
+ }
135
+ catch (_error) {
136
+ // Return null if can't read manifest
137
+ return null;
138
+ }
139
+ }
140
+ async updateManifest(manifestName) {
141
+ const manifestPath = path.join(process.cwd(), 'raindrop.manifest');
142
+ try {
143
+ let content = await fs.readFile(manifestPath, 'utf-8');
144
+ // Check if SmartSQL binding already exists
145
+ if (content.includes(`smartsql "${manifestName}"`)) {
146
+ this.log(chalk.yellow('⚠') + ' SmartSQL binding already exists in manifest');
147
+ return;
148
+ }
149
+ // Find the application block and add the smartsql binding
150
+ // Insert it after the opening brace of the application block
151
+ const appMatch = content.match(/application\s+"[^"]+"\s+\{/);
152
+ if (appMatch) {
153
+ const insertPos = appMatch.index + appMatch[0].length;
154
+ const binding = `\n smartsql "${manifestName}" {}\n`;
155
+ content = content.slice(0, insertPos) + binding + content.slice(insertPos);
156
+ await fs.writeFile(manifestPath, content);
157
+ }
158
+ else {
159
+ throw new Error('Could not find application block in raindrop.manifest');
160
+ }
161
+ }
162
+ catch (error) {
163
+ if (error.code === 'ENOENT') {
164
+ throw new Error('raindrop.manifest not found. Are you in a Raindrop project directory?');
165
+ }
166
+ throw error;
167
+ }
168
+ }
169
+ }
@@ -8,7 +8,9 @@ export default class Build extends BaseCommand<typeof Build> {
8
8
  manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
9
  config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ quick: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  };
12
13
  run(): Promise<void>;
14
+ private checkDependencies;
13
15
  }
14
16
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/build/validate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAgBpD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW,CAAC,OAAO,KAAK,CAAC;IAC1D,OAAgB,IAAI,KAAM;IAE1B,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,QAAQ,WAA2C;IAEnE,OAAgB,KAAK;;;;;MAgBnB;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBlC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/build/validate.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAqCpD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW,CAAC,OAAO,KAAK,CAAC;IAC1D,OAAgB,IAAI,KAAM;IAE1B,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;;;MAoBnB;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAmDnB,iBAAiB;CA2BhC"}
@@ -1,23 +1,45 @@
1
1
  import { Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
2
3
  import { spawn } from 'node:child_process';
4
+ import * as fs from 'node:fs/promises';
3
5
  import path from 'node:path';
4
6
  import { BaseCommand } from '../../base-command.js';
5
7
  import { buildHandlers } from '../../build.js';
6
8
  async function runTypeCheck(root) {
7
9
  return new Promise((resolve) => {
10
+ let output = '';
8
11
  const tsc = spawn('npx', ['tsc', '--noEmit'], {
9
12
  cwd: root,
10
- stdio: 'inherit', // Inherit stdio to show compiler output in real-time
13
+ stdio: 'pipe', // Capture output to analyze errors
14
+ });
15
+ tsc.stdout?.on('data', (data) => {
16
+ output += data.toString();
17
+ });
18
+ tsc.stderr?.on('data', (data) => {
19
+ output += data.toString();
11
20
  });
12
21
  tsc.on('exit', (code) => {
13
- resolve(code === 0);
22
+ const hasFrameworkError = output.includes('@liquidmetal-ai/raindrop-framework');
23
+ const hasHonoError = output.includes('hono');
24
+ // Print the TypeScript errors if check failed
25
+ if (code !== 0 && output) {
26
+ console.log(output);
27
+ }
28
+ resolve({
29
+ success: code === 0,
30
+ hasFrameworkError,
31
+ hasHonoError
32
+ });
14
33
  });
15
34
  });
16
35
  }
17
36
  export default class Build extends BaseCommand {
18
37
  static args = {};
19
38
  static description = 'build and validate a LiquidMetal.AI project';
20
- static examples = ['<%= config.bin %> <%= command.id %>'];
39
+ static examples = [
40
+ '<%= config.bin %> <%= command.id %>',
41
+ '<%= config.bin %> <%= command.id %> --quick # Skip dependency checks',
42
+ ];
21
43
  static flags = {
22
44
  root: Flags.string({ char: 'r', description: 'root directory', required: false, default: process.cwd() }),
23
45
  manifest: Flags.string({
@@ -34,6 +56,10 @@ export default class Build extends BaseCommand {
34
56
  default: '.raindrop/config.json',
35
57
  }),
36
58
  output: Flags.string({ char: 'o', description: 'output directory', required: false, default: 'dist' }),
59
+ quick: Flags.boolean({
60
+ description: 'Skip dependency checks and run basic validation only',
61
+ default: false,
62
+ }),
37
63
  };
38
64
  async run() {
39
65
  const apps = await this.loadManifest();
@@ -41,17 +67,63 @@ export default class Build extends BaseCommand {
41
67
  if (version === null) {
42
68
  this.error('Failed to determine @liquidmetal-ai/raindrop-framework version; is it installed?', { exit: 1 });
43
69
  }
44
- console.log(`Using @liquidmetal-ai/raindrop-framework version ${version}`);
70
+ console.log(chalk.blue(`✓ Using @liquidmetal-ai/raindrop-framework version ${version}`));
71
+ // Check package.json dependencies if not quick mode
72
+ if (!this.flags.quick) {
73
+ await this.checkDependencies();
74
+ }
45
75
  // Run TypeScript type checking
46
76
  console.log('Running type check...');
47
- const typeCheckPassed = await runTypeCheck(this.flags.root);
48
- if (!typeCheckPassed) {
49
- this.error('Type check failed. Please fix the TypeScript errors before building.');
77
+ const typeCheckResult = await runTypeCheck(this.flags.root);
78
+ if (!typeCheckResult.success) {
79
+ console.log('');
80
+ console.log(chalk.red('Type check failed. Please fix the TypeScript errors before building.'));
81
+ if (typeCheckResult.hasFrameworkError) {
82
+ console.log('');
83
+ console.log(chalk.yellow('Framework import error detected. Try:'));
84
+ console.log(chalk.dim(' npm install'));
85
+ console.log(chalk.dim(' raindrop build generate'));
86
+ console.log(chalk.dim(' Or check your package.json for the correct framework version'));
87
+ }
88
+ if (typeCheckResult.hasHonoError) {
89
+ console.log('');
90
+ console.log(chalk.yellow('Hono import error detected. Try:'));
91
+ console.log(chalk.dim(' npm install hono'));
92
+ }
93
+ console.log('');
94
+ console.log(chalk.bold('For more help:'));
95
+ console.log(chalk.dim(' raindrop build features # Discover available features'));
96
+ console.log(chalk.dim(' raindrop build smartmemory setup # Get working examples'));
97
+ this.error('Validation failed');
50
98
  }
51
- console.log('Type check passed');
99
+ console.log(chalk.green('Type check passed'));
52
100
  const buildDir = path.isAbsolute(this.flags.output)
53
101
  ? this.flags.output
54
102
  : path.join(this.flags.root, this.flags.output);
55
103
  await buildHandlers(this, apps, buildDir, this.flags.root);
56
104
  }
105
+ async checkDependencies() {
106
+ try {
107
+ const packageJsonPath = path.join(this.flags.root, 'package.json');
108
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
109
+ const frameworkDep = packageJson.dependencies?.['@liquidmetal-ai/raindrop-framework'];
110
+ const honoDep = packageJson.dependencies?.['hono'];
111
+ if (!frameworkDep) {
112
+ console.log(chalk.yellow('⚠️ @liquidmetal-ai/raindrop-framework not found in dependencies'));
113
+ console.log(chalk.dim(' Try: npm install @liquidmetal-ai/raindrop-framework'));
114
+ console.log('');
115
+ }
116
+ if (!honoDep) {
117
+ console.log(chalk.yellow('⚠️ hono not found in dependencies'));
118
+ console.log(chalk.dim(' Try: npm install hono'));
119
+ console.log('');
120
+ }
121
+ if (frameworkDep && honoDep) {
122
+ console.log(chalk.green('✓ Core dependencies present'));
123
+ }
124
+ }
125
+ catch (_error) {
126
+ console.log(chalk.yellow('⚠️ Could not check package.json dependencies'));
127
+ }
128
+ }
57
129
  }
@@ -0,0 +1,23 @@
1
+ import { BaseCommand } from '../../../base-command.js';
2
+ export default class Jwt extends BaseCommand<typeof Jwt> {
3
+ static args: {};
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ root: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ application: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'client-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'session-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ raindropCatalogService: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ rainbowAuthToken: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ rainbowOrganizationId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ rainbowUserId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ sendVersionMetadata: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
19
+ };
20
+ run(): Promise<void>;
21
+ private fetchClientId;
22
+ }
23
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../../src/commands/build/workos/jwt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAuDvD,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,WAAW,CAAC,OAAO,GAAG,CAAC;IACtD,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAAoE;IAEtF,MAAM,CAAC,QAAQ,WAUb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;MA0BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA6DZ,aAAa;CAsC5B"}
@@ -0,0 +1,172 @@
1
+ import { Flags } from '@oclif/core';
2
+ import * as fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { BaseCommand } from '../../../base-command.js';
5
+ import { refreshToken } from '../../../lib/workos-test-server.js';
6
+ /**
7
+ * Decode JWT payload without verification
8
+ */
9
+ function decodeJWTPayload(token) {
10
+ try {
11
+ const parts = token.split('.');
12
+ if (parts.length !== 3) {
13
+ throw new Error('Invalid JWT format');
14
+ }
15
+ const payload = parts[1];
16
+ if (!payload) {
17
+ throw new Error('Invalid JWT format: missing payload');
18
+ }
19
+ const decoded = JSON.parse(Buffer.from(payload, 'base64url').toString());
20
+ return decoded;
21
+ }
22
+ catch (error) {
23
+ throw new Error(`Failed to decode JWT: ${error instanceof Error ? error.message : 'Unknown error'}`);
24
+ }
25
+ }
26
+ /**
27
+ * Check if a JWT is expired
28
+ */
29
+ function isTokenExpired(token) {
30
+ try {
31
+ const payload = decodeJWTPayload(token);
32
+ if (!payload.exp) {
33
+ // If no expiration, consider it valid
34
+ return false;
35
+ }
36
+ const now = Math.floor(Date.now() / 1000);
37
+ return payload.exp < now;
38
+ }
39
+ catch {
40
+ // If we can't decode it, consider it invalid/expired
41
+ return true;
42
+ }
43
+ }
44
+ /**
45
+ * Read session from file
46
+ */
47
+ async function readSession(sessionFile) {
48
+ try {
49
+ const data = await fs.readFile(sessionFile, 'utf8');
50
+ return JSON.parse(data);
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ export default class Jwt extends BaseCommand {
57
+ static args = {};
58
+ static description = 'Get the JWT from the dev-login session (refreshing if expired)';
59
+ static examples = [
60
+ `<%= config.bin %> <%= command.id %>
61
+ Get JWT from the default session file (.auth.json)
62
+
63
+ <%= config.bin %> <%= command.id %> --session-file /path/to/.auth.json
64
+ Get JWT from a specific session file
65
+
66
+ <%= config.bin %> <%= command.id %> --client-id client_xxx
67
+ Get JWT with explicit client ID for refresh
68
+ `,
69
+ ];
70
+ static flags = {
71
+ ...BaseCommand.HIDDEN_FLAGS,
72
+ root: Flags.string({
73
+ description: 'root directory',
74
+ required: false,
75
+ default: process.cwd(),
76
+ }),
77
+ manifest: Flags.string({
78
+ description: 'project manifest',
79
+ required: false,
80
+ default: 'raindrop.manifest',
81
+ }),
82
+ application: Flags.string({
83
+ char: 'a',
84
+ description: 'application name',
85
+ required: false,
86
+ }),
87
+ 'client-id': Flags.string({
88
+ description: 'WorkOS client ID (for token refresh)',
89
+ required: false,
90
+ env: 'WORKOS_CLIENT_ID',
91
+ }),
92
+ 'session-file': Flags.string({
93
+ description: 'path to session file',
94
+ required: false,
95
+ }),
96
+ };
97
+ async run() {
98
+ const { root, 'client-id': clientIdFlag, 'session-file': sessionFileFlag } = this.flags;
99
+ // Determine session file path
100
+ const sessionFile = sessionFileFlag || path.join(root, '.auth.json');
101
+ // Read the session
102
+ const session = await readSession(sessionFile);
103
+ if (!session) {
104
+ this.error(`No session file found at ${sessionFile}. Run 'raindrop build workos env dev-login' first.`, { exit: 1 });
105
+ }
106
+ if (!session.access_token) {
107
+ this.error('Session file exists but contains no access token.', { exit: 1 });
108
+ }
109
+ let accessToken = session.access_token;
110
+ // Check if token is expired
111
+ if (isTokenExpired(accessToken)) {
112
+ // Token is expired, try to refresh it
113
+ if (!session.refresh_token) {
114
+ this.error('Token is expired and no refresh token is available. Run `raindrop build workos env dev-login` again.', { exit: 1 });
115
+ }
116
+ // Get client ID
117
+ let clientId = clientIdFlag;
118
+ if (!clientId) {
119
+ // Try to get from environment
120
+ try {
121
+ const envInfo = await this.fetchClientId();
122
+ clientId = envInfo;
123
+ }
124
+ catch (error) {
125
+ const err = error;
126
+ this.error(`Client ID required for token refresh. Provide --client-id or ensure WorkOS environment is attached.\nError: ${err.message}`, { exit: 1 });
127
+ }
128
+ }
129
+ // Refresh the token
130
+ try {
131
+ const refreshedSession = await refreshToken({
132
+ clientId,
133
+ sessionFile,
134
+ });
135
+ accessToken = refreshedSession.access_token;
136
+ }
137
+ catch (error) {
138
+ const err = error;
139
+ this.error(`Failed to refresh token: ${err.message}. Run \`raindrop build workos env dev-login\` again.`, { exit: 1 });
140
+ }
141
+ }
142
+ // Output the JWT to stdout
143
+ console.log(accessToken);
144
+ }
145
+ async fetchClientId() {
146
+ const { valueOf } = await import('@liquidmetal-ai/drizzle/appify/build');
147
+ // Load manifest to get application name
148
+ const apps = await this.loadManifest();
149
+ const app = apps.find((a) => valueOf(a.name) === this.flags.application) || apps[0];
150
+ if (!app) {
151
+ throw new Error('No application found in manifest. Specify --client-id.');
152
+ }
153
+ const applicationName = valueOf(app.name);
154
+ // Load config to get version ID
155
+ const config = await this.loadConfig();
156
+ const versionId = config.versionId;
157
+ if (!versionId) {
158
+ throw new Error('No version ID found. Deploy your application first with: raindrop build deploy');
159
+ }
160
+ const { client: workosService, userId, organizationId } = await this.workosIntegrationService();
161
+ const response = await workosService.getEnvironmentForApplication({
162
+ userId,
163
+ organizationId,
164
+ applicationName,
165
+ versionId,
166
+ });
167
+ if (!response.environment?.clientId) {
168
+ throw new Error(`No WorkOS environment attached to ${applicationName}. Attach one with: raindrop build workos env attach <env-name>`);
169
+ }
170
+ return response.environment.clientId;
171
+ }
172
+ }
@@ -0,0 +1,27 @@
1
+ import { BaseCommand } from '../base-command.js';
2
+ export default class Doctor extends BaseCommand<typeof Doctor> {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ root: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ manifest: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ rainbowAuthService: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ raindropCatalogService: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ rainbowAuthToken: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ rainbowOrganizationId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ rainbowUserId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ sendVersionMetadata: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<void>;
18
+ private promptForAIAgent;
19
+ private collectDiagnostics;
20
+ private collectVersionInfo;
21
+ private collectProjectInfo;
22
+ private collectAuthInfo;
23
+ private maskEmail;
24
+ private collectEnvironmentInfo;
25
+ private displayDiagnostics;
26
+ }
27
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2CjD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC5D,MAAM,CAAC,WAAW,SAAoE;IAEtF,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;MAmBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAqBZ,gBAAgB;YA8ChB,kBAAkB;YA0BlB,kBAAkB;YA4BlB,kBAAkB;YA6ClB,eAAe;IAiC7B,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,kBAAkB;CAyF3B"}