@gonvex/cli 0.1.32 → 0.3.1

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 (36) hide show
  1. package/README.md +30 -15
  2. package/dist/browser.d.ts +1 -1
  3. package/dist/browser.js +1 -1
  4. package/dist/browser.js.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +274 -555
  7. package/dist/index.js.map +1 -1
  8. package/dist/manifest-types.d.ts +261 -0
  9. package/dist/manifest-types.js +3 -0
  10. package/dist/manifest-types.js.map +1 -0
  11. package/dist/module-artifact.d.ts +26 -0
  12. package/dist/module-artifact.js +1585 -0
  13. package/dist/module-artifact.js.map +1 -0
  14. package/dist/react.d.ts +2 -2
  15. package/dist/react.js +1 -1
  16. package/dist/react.js.map +1 -1
  17. package/dist/templates/vite-react/README.md +5 -2
  18. package/dist/templates/vite-react/gonvex/_build/module.js +407 -0
  19. package/dist/templates/vite-react/gonvex/_generated/api.ts +185 -3
  20. package/dist/templates/vite-react/gonvex/_generated/client.ts +1 -1
  21. package/dist/templates/vite-react/gonvex/_generated/{landlord → control-plane}/schema.ts +2 -1
  22. package/dist/templates/vite-react/gonvex/_generated/{landlord → control-plane}/tables.ts +1 -1
  23. package/dist/templates/vite-react/gonvex/_generated/manifest.json +201 -66
  24. package/dist/templates/vite-react/gonvex/_generated/module.json +120 -0
  25. package/dist/templates/vite-react/gonvex/_generated/react.ts +2 -2
  26. package/dist/templates/vite-react/gonvex/_generated/schema.ts +4 -34
  27. package/dist/templates/vite-react/gonvex/_generated/tenant/schema.ts +1 -30
  28. package/dist/templates/vite-react/gonvex/_generated/tenant/tables.ts +0 -30
  29. package/dist/templates/vite-react/gonvex/index.ts +1 -0
  30. package/dist/templates/vite-react/gonvex/messages.ts +47 -0
  31. package/dist/templates/vite-react/migrations/0001_messages.sql +9 -0
  32. package/dist/templates/vite-react/package.json +1 -0
  33. package/dist/templates/vite-react/src/App.tsx +5 -5
  34. package/package.json +4 -3
  35. package/dist/templates/vite-react/gonvex/messages.go +0 -38
  36. package/dist/templates/vite-react/gonvex/schema.go +0 -14
@@ -0,0 +1,120 @@
1
+ {
2
+ "language": "typescript",
3
+ "generation": 4,
4
+ "hash": "3032d0fd8002f04b1c8fd5599e2a33ae1b082a4001b4b80c6783f422909894ee",
5
+ "entrypoint": "gonvex/index.ts",
6
+ "functions": {
7
+ "messages.list": {
8
+ "kind": "query",
9
+ "handler": "list",
10
+ "file": "gonvex/messages.ts",
11
+ "export": "list",
12
+ "args": {
13
+ "kind": "object",
14
+ "fields": {}
15
+ },
16
+ "result": {
17
+ "kind": "array",
18
+ "items": {
19
+ "kind": "object",
20
+ "fields": {
21
+ "id": {
22
+ "kind": "id",
23
+ "entity": "messages"
24
+ },
25
+ "body": {
26
+ "kind": "string"
27
+ },
28
+ "author": {
29
+ "kind": "string"
30
+ },
31
+ "created_at": {
32
+ "kind": "string",
33
+ "format": "datetime"
34
+ }
35
+ }
36
+ }
37
+ },
38
+ "dependencies": {
39
+ "liveQueryPlan": {
40
+ "table": "messages",
41
+ "key": "id",
42
+ "columns": [
43
+ "id",
44
+ "body",
45
+ "author",
46
+ "created_at"
47
+ ],
48
+ "sort": {
49
+ "defaultColumn": "created_at",
50
+ "defaultDirection": "asc",
51
+ "allowedColumns": [
52
+ "created_at"
53
+ ]
54
+ }
55
+ }
56
+ },
57
+ "delivery": "live"
58
+ },
59
+ "messages.send": {
60
+ "kind": "reducer",
61
+ "handler": "send",
62
+ "file": "gonvex/messages.ts",
63
+ "export": "send",
64
+ "args": {
65
+ "kind": "object",
66
+ "fields": {
67
+ "body": {
68
+ "kind": "string"
69
+ }
70
+ }
71
+ },
72
+ "result": {
73
+ "kind": "object",
74
+ "fields": {
75
+ "id": {
76
+ "kind": "id",
77
+ "entity": "messages"
78
+ },
79
+ "body": {
80
+ "kind": "string"
81
+ },
82
+ "author": {
83
+ "kind": "string"
84
+ },
85
+ "created_at": {
86
+ "kind": "string",
87
+ "format": "datetime"
88
+ }
89
+ }
90
+ },
91
+ "dependencies": {
92
+ "nonOptimisticReason": "server assigns the message id"
93
+ },
94
+ "offline": {
95
+ "mode": "onlineOnly",
96
+ "reason": "server assigns the message id"
97
+ }
98
+ }
99
+ },
100
+ "visibility": {
101
+ "messages": {
102
+ "table": "messages",
103
+ "key": "id",
104
+ "sets": {},
105
+ "where": {
106
+ "operator": "public"
107
+ }
108
+ }
109
+ },
110
+ "files": {
111
+ "gonvex/index.ts": "ZXhwb3J0IHsgbGlzdCwgc2VuZCwgbWVzc2FnZXNWaXNpYmlsaXR5IH0gZnJvbSAiLi9tZXNzYWdlcy50cyI7Cg==",
112
+ "gonvex/messages.ts": "aW1wb3J0IHsgbGl2ZVF1ZXJ5LCByZWR1Y2VyLCBzY2hlbWEsIHZpc2liaWxpdHkgfSBmcm9tICJAZ29udmV4L21vZHVsZS1zZGsiOwoKZXhwb3J0IGNvbnN0IG1lc3NhZ2VzVmlzaWJpbGl0eSA9IHZpc2liaWxpdHkoewogIHRhYmxlOiAibWVzc2FnZXMiLAogIGtleTogImlkIiwKICBzZXRzOiB7fSwKICB3aGVyZTogeyBvcGVyYXRvcjogInB1YmxpYyIgfSwKfSk7CgpleHBvcnQgY29uc3QgbGlzdCA9IGxpdmVRdWVyeSh7CiAgYXJnczogc2NoZW1hLm9iamVjdCh7fSksCiAgcmVzdWx0OiBzY2hlbWEuYXJyYXkoc2NoZW1hLm9iamVjdCh7CiAgICBpZDogc2NoZW1hLmlkKCJtZXNzYWdlcyIpLAogICAgYm9keTogc2NoZW1hLnN0cmluZygpLAogICAgYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCiAgICBjcmVhdGVkX2F0OiBzY2hlbWEuZGF0ZXRpbWUoKSwKICB9KSksCiAgbGl2ZVF1ZXJ5UGxhbjogewogICAgdGFibGU6ICJtZXNzYWdlcyIsCiAgICBrZXk6ICJpZCIsCiAgICBjb2x1bW5zOiBbImlkIiwgImJvZHkiLCAiYXV0aG9yIiwgImNyZWF0ZWRfYXQiXSwKICAgIHNvcnQ6IHsKICAgICAgZGVmYXVsdENvbHVtbjogImNyZWF0ZWRfYXQiLAogICAgICBkZWZhdWx0RGlyZWN0aW9uOiAiYXNjIiwKICAgICAgYWxsb3dlZENvbHVtbnM6IFsiY3JlYXRlZF9hdCJdLAogICAgfSwKICB9LAogIHJ1bjogYXN5bmMgKCkgPT4gW10sCn0pOwoKZXhwb3J0IGNvbnN0IHNlbmQgPSByZWR1Y2VyKHsKICBhcmdzOiBzY2hlbWEub2JqZWN0KHsgYm9keTogc2NoZW1hLnN0cmluZygpIH0pLAogIHJlc3VsdDogc2NoZW1hLm9iamVjdCh7CiAgICBpZDogc2NoZW1hLmlkKCJtZXNzYWdlcyIpLAogICAgYm9keTogc2NoZW1hLnN0cmluZygpLAogICAgYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCiAgICBjcmVhdGVkX2F0OiBzY2hlbWEuZGF0ZXRpbWUoKSwKICB9KSwKICBvZmZsaW5lOiB7IG1vZGU6ICJvbmxpbmVPbmx5IiwgcmVhc29uOiAic2VydmVyIGFzc2lnbnMgdGhlIG1lc3NhZ2UgaWQiIH0sCiAgbm9uT3B0aW1pc3RpY1JlYXNvbjogInNlcnZlciBhc3NpZ25zIHRoZSBtZXNzYWdlIGlkIiwKICBydW46IGFzeW5jICh7IG5vdyB9LCBhcmdzKSA9PiAoewogICAgaWQ6ICJwZW5kaW5nIiwKICAgIGJvZHk6IGFyZ3MuYm9keSwKICAgIGF1dGhvcjogImRlbW8tdXNlciIsCiAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZShub3cpLnRvSVNPU3RyaW5nKCksCiAgfSksCn0pOwo=",
113
+ "migrations/0001_messages.sql": "LS0gZ29udmV4OnNjb3BlIHRlbmFudApDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBtZXNzYWdlcyAoCiAgaWQgdGV4dCBQUklNQVJZIEtFWSwKICBib2R5IHRleHQgTk9UIE5VTEwsCiAgYXV0aG9yIHRleHQgTk9UIE5VTEwsCiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTAopOwoKQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgYnlfY3JlYXRlZF9hdCBPTiBtZXNzYWdlcyAoY3JlYXRlZF9hdCk7Cg=="
114
+ },
115
+ "javascript": {
116
+ "path": "gonvex/_build/module.js",
117
+ "hash": "17879ed408db6c0a2bc9ffccbe77c58f6297156a71c39c513471e9d6f6ad7674",
118
+ "code": "Ly8jcmVnaW9uIC4uLy4uL3BhY2thZ2VzL21vZHVsZS1zZGsvZGlzdC9pbmRleC5qcwpjb25zdCBmcmVlemUgPSAodmFsdWUpID0+IE9iamVjdC5mcmVlemUodmFsdWUpOwovKiogQ29uc3RydWN0b3JzIGZvciB0aGUgbGFuZ3VhZ2UtbmV1dHJhbCBzY2hlbWEgc3Vic2V0LiAqLwpjb25zdCBzY2hlbWEgPSB7CglzdHJpbmcob3B0aW9ucyA9IHt9KSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQkuLi5vcHRpb25zCgkJfSk7Cgl9LAoJZW1haWwoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJlbWFpbCIKCQl9KTsKCX0sCgl1cmkoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJ1cmkiCgkJfSk7Cgl9LAoJdXVpZCgpIHsKCQlyZXR1cm4gZnJlZXplKHsKCQkJa2luZDogInN0cmluZyIsCgkJCWZvcm1hdDogInV1aWQiCgkJfSk7Cgl9LAoJZGF0ZXRpbWUoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJkYXRldGltZSIKCQl9KTsKCX0sCgludW1iZXIob3B0aW9ucyA9IHt9KSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJudW1iZXIiLAoJCQkuLi5vcHRpb25zCgkJfSk7Cgl9LAoJaW50ZWdlcihvcHRpb25zID0ge30pIHsKCQlyZXR1cm4gZnJlZXplKHsKCQkJa2luZDogIm51bWJlciIsCgkJCWludGVnZXI6IHRydWUsCgkJCS4uLm9wdGlvbnMKCQl9KTsKCX0sCglib29sZWFuKCkgewoJCXJldHVybiBmcmVlemUoeyBraW5kOiAiYm9vbGVhbiIgfSk7Cgl9LAoJbnVsbCgpIHsKCQlyZXR1cm4gZnJlZXplKHsga2luZDogIm51bGwiIH0pOwoJfSwKCWFueSgpIHsKCQlyZXR1cm4gZnJlZXplKHsga2luZDogImFueSIgfSk7Cgl9LAoJaWQoZW50aXR5KSB7CgkJaWYgKCFlbnRpdHkudHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoInNjaGVtYS5pZCByZXF1aXJlcyBhbiBlbnRpdHkgbmFtZSIpOwoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAiaWQiLAoJCQllbnRpdHkKCQl9KTsKCX0sCglsaXRlcmFsKHZhbHVlKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJsaXRlcmFsIiwKCQkJdmFsdWUKCQl9KTsKCX0sCglhcnJheShpdGVtcykgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAiYXJyYXkiLAoJCQlpdGVtcwoJCX0pOwoJfSwKCW9iamVjdChmaWVsZHMsIG9wdGlvbnMgPSB7fSkgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAib2JqZWN0IiwKCQkJZmllbGRzOiBmcmVlemUoeyAuLi5maWVsZHMgfSksCgkJCS4uLm9wdGlvbnMKCQl9KTsKCX0sCglyZWNvcmQodmFsdWVzKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJyZWNvcmQiLAoJCQl2YWx1ZXMKCQl9KTsKCX0sCglvcHRpb25hbCh2YWx1ZSkgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAib3B0aW9uYWwiLAoJCQl2YWx1ZQoJCX0pOwoJfQp9Owpjb25zdCBpc1JlY29yZCA9ICh2YWx1ZSkgPT4gdHlwZW9mIHZhbHVlID09PSAib2JqZWN0IiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7CmNvbnN0IHZhbGlkYXRlT2ZmbGluZVBvbGljeSA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkgfHwgdmFsdWUubW9kZSAhPT0gImZvcmJpZGRlbiIgJiYgdmFsdWUubW9kZSAhPT0gImFsbG93ZWQiICYmIHZhbHVlLm1vZGUgIT09ICJvbmxpbmVPbmx5IikgdGhyb3cgbmV3IEVycm9yKGByZWR1Y2VyICR7cGF0aH0gbXVzdCBkZWNsYXJlIGEgdmFsaWQgb2ZmbGluZSBwb2xpY3lgKTsKCWlmICh2YWx1ZS5tb2RlID09PSAib25saW5lT25seSIgJiYgKHR5cGVvZiB2YWx1ZS5yZWFzb24gIT09ICJzdHJpbmciIHx8ICF2YWx1ZS5yZWFzb24udHJpbSgpKSkgdGhyb3cgbmV3IEVycm9yKGByZWR1Y2VyICR7cGF0aH0gb25saW5lT25seSBwb2xpY3kgcmVxdWlyZXMgYSByZWFzb25gKTsKCWlmICh2YWx1ZS5tb2RlID09PSAiYWxsb3dlZCIgJiYgdmFsdWUuY29uZmxpY3QgIT09IHZvaWQgMCAmJiB2YWx1ZS5jb25mbGljdCAhPT0gInJlamVjdCIgJiYgdmFsdWUuY29uZmxpY3QgIT09ICJleHBlY3RlZFZlcnNpb24iICYmIHZhbHVlLmNvbmZsaWN0ICE9PSAibWVyZ2UiKSB0aHJvdyBuZXcgRXJyb3IoYHJlZHVjZXIgJHtwYXRofSBoYXMgYW4gaW52YWxpZCBvZmZsaW5lIGNvbmZsaWN0IHBvbGljeWApOwp9Owpjb25zdCB2YWxpZGF0ZU9wdGltaXN0aWNUcmFuc2FjdGlvbiA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuZWZmZWN0cykgfHwgdmFsdWUuZWZmZWN0cy5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgbWV0YWRhdGEgbXVzdCBjb250YWluIGEgbm9uLWVtcHR5IGVmZmVjdHMgYXJyYXlgKTsKCWlmICh2YWx1ZS5leHBlY3RlZFJldmlzaW9uICE9PSB2b2lkIDAgJiYgKHR5cGVvZiB2YWx1ZS5leHBlY3RlZFJldmlzaW9uICE9PSAibnVtYmVyIiB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUuZXhwZWN0ZWRSZXZpc2lvbikgfHwgdmFsdWUuZXhwZWN0ZWRSZXZpc2lvbiA8IDApKSB0aHJvdyBuZXcgRXJyb3IoYHJlZHVjZXIgJHtwYXRofSBvcHRpbWlzdGljIGV4cGVjdGVkUmV2aXNpb24gbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyYCk7Cglmb3IgKGNvbnN0IGVmZmVjdCBvZiB2YWx1ZS5lZmZlY3RzKSB7CgkJaWYgKCFpc1JlY29yZChlZmZlY3QpIHx8IGVmZmVjdC5vcGVyYXRpb24gIT09ICJwYXRjaCIgJiYgZWZmZWN0Lm9wZXJhdGlvbiAhPT0gInVwc2VydCIgJiYgZWZmZWN0Lm9wZXJhdGlvbiAhPT0gImRlbGV0ZSIpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IGhhcyBhbiBpbnZhbGlkIG9wdGltaXN0aWMgZWZmZWN0YCk7CgkJaWYgKHR5cGVvZiBlZmZlY3QuZW50aXR5ICE9PSAic3RyaW5nIiB8fCAhZWZmZWN0LmVudGl0eS50cmltKCkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgZWZmZWN0cyByZXF1aXJlIGFuIGVudGl0eWApOwoJCWlmICh0eXBlb2YgZWZmZWN0LmlkID09PSAic3RyaW5nIiAmJiAhZWZmZWN0LmlkLnRyaW0oKSB8fCB0eXBlb2YgZWZmZWN0LmlkICE9PSAic3RyaW5nIiAmJiAoIUFycmF5LmlzQXJyYXkoZWZmZWN0LmlkKSB8fCBlZmZlY3QuaWQubGVuZ3RoID09PSAwIHx8IGVmZmVjdC5pZC5zb21lKChwYXJ0KSA9PiB0eXBlb2YgcGFydCAhPT0gInN0cmluZyIgfHwgIXBhcnQudHJpbSgpKSkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgZWZmZWN0cyByZXF1aXJlIGEgc3RyaW5nIGlkIG9yIGlkIHJlZmVyZW5jZXNgKTsKCQlpZiAoKGVmZmVjdC5vcGVyYXRpb24gPT09ICJwYXRjaCIgfHwgZWZmZWN0Lm9wZXJhdGlvbiA9PT0gInVwc2VydCIpICYmICFpc1JlY29yZChlZmZlY3Qub3BlcmF0aW9uID09PSAicGF0Y2giID8gZWZmZWN0LmZpZWxkcyA6IGVmZmVjdC52YWx1ZSkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgJHtlZmZlY3Qub3BlcmF0aW9ufSBlZmZlY3RzIHJlcXVpcmUgYW4gb2JqZWN0IHZhbHVlYCk7Cgl9Cn07CmNvbnN0IHZhbGlkYXRlUmVwbGljYUNvbGxlY3Rpb24gPSAodmFsdWUsIHBhdGgpID0+IHsKCWlmICghaXNSZWNvcmQodmFsdWUpIHx8IHR5cGVvZiB2YWx1ZS50YWJsZSAhPT0gInN0cmluZyIgfHwgIXZhbHVlLnRhYmxlLnRyaW0oKSB8fCB0eXBlb2YgdmFsdWUua2V5ICE9PSAic3RyaW5nIiB8fCAhdmFsdWUua2V5LnRyaW0oKSB8fCAhQXJyYXkuaXNBcnJheSh2YWx1ZS5jb2x1bW5zKSB8fCB2YWx1ZS5jb2x1bW5zLnNvbWUoKGNvbHVtbikgPT4gdHlwZW9mIGNvbHVtbiAhPT0gInN0cmluZyIgfHwgIWNvbHVtbi50cmltKCkpKSB0aHJvdyBuZXcgRXJyb3IoYHJlcGxpY2EgY29sbGVjdGlvbiAke3BhdGh9IHJlcXVpcmVzIGEgdGFibGUsIGtleSwgYW5kIGNvbHVtbnNgKTsKCWZvciAoY29uc3QgZmllbGQgb2YgWwoJCSJtYXhSb3dzIiwKCQkibWF4Qnl0ZXMiLAoJCSJyZXRlbnRpb25NcyIKCV0pIHsKCQljb25zdCBidWRnZXQgPSB2YWx1ZVtmaWVsZF07CgkJaWYgKGJ1ZGdldCAhPT0gdm9pZCAwICYmICh0eXBlb2YgYnVkZ2V0ICE9PSAibnVtYmVyIiB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIoYnVkZ2V0KSB8fCBidWRnZXQgPD0gMCkpIHRocm93IG5ldyBFcnJvcihgcmVwbGljYSBjb2xsZWN0aW9uICR7cGF0aH0gJHtmaWVsZH0gbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXJgKTsKCX0KCWlmICh2YWx1ZS5tb2RlICE9PSB2b2lkIDAgJiYgdmFsdWUubW9kZSAhPT0gImVhZ2VyIiAmJiB2YWx1ZS5tb2RlICE9PSAicHJvZ3Jlc3NpdmUiKSB0aHJvdyBuZXcgRXJyb3IoYHJlcGxpY2EgY29sbGVjdGlvbiAke3BhdGh9IGhhcyBhbiBpbnZhbGlkIGNvbXBsZXRlbmVzcyBtb2RlYCk7CglpZiAodmFsdWUub3JkZXJEaXJlY3Rpb24gIT09IHZvaWQgMCAmJiB2YWx1ZS5vcmRlckRpcmVjdGlvbiAhPT0gImFzYyIgJiYgdmFsdWUub3JkZXJEaXJlY3Rpb24gIT09ICJkZXNjIikgdGhyb3cgbmV3IEVycm9yKGByZXBsaWNhIGNvbGxlY3Rpb24gJHtwYXRofSBoYXMgYW4gaW52YWxpZCBvcmRlciBkaXJlY3Rpb25gKTsKfTsKY29uc3QgdmFsaWRhdGVTdHJ1Y3R1cmVkUXVlcnlQbGFuID0gKHZhbHVlLCBwYXRoKSA9PiB7CglpZiAoIWlzUmVjb3JkKHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUudGFibGUgIT09ICJzdHJpbmciIHx8ICF2YWx1ZS50YWJsZS50cmltKCkgfHwgdHlwZW9mIHZhbHVlLmtleSAhPT0gInN0cmluZyIgfHwgIXZhbHVlLmtleS50cmltKCkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuY29sdW1ucykgfHwgdmFsdWUuY29sdW1ucy5sZW5ndGggPT09IDAgfHwgdmFsdWUuY29sdW1ucy5zb21lKChjb2x1bW4pID0+IHR5cGVvZiBjb2x1bW4gIT09ICJzdHJpbmciIHx8ICFjb2x1bW4udHJpbSgpKSkgdGhyb3cgbmV3IEVycm9yKGBvbmUtc2hvdCBxdWVyeSAke3BhdGh9IHJlcXVpcmVzIGEgc3RydWN0dXJlZCBsaXZlIHF1ZXJ5IHBsYW4gd2l0aCBhIHRhYmxlLCBrZXksIGFuZCBjb2x1bW5zYCk7CglpZiAoIXZhbHVlLmNvbHVtbnMuaW5jbHVkZXModmFsdWUua2V5KSkgdGhyb3cgbmV3IEVycm9yKGBvbmUtc2hvdCBxdWVyeSAke3BhdGh9IGxpdmUgcXVlcnkgcGxhbiBjb2x1bW5zIG11c3QgaW5jbHVkZSBpdHMga2V5YCk7CglpZiAodmFsdWUuZmlsdGVycyAhPT0gdm9pZCAwKSB7CgkJaWYgKCFpc1JlY29yZCh2YWx1ZS5maWx0ZXJzKSB8fCB0eXBlb2YgdmFsdWUuZmlsdGVycy5hcmd1bWVudCAhPT0gInN0cmluZyIgfHwgIXZhbHVlLmZpbHRlcnMuYXJndW1lbnQudHJpbSgpIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMpIHx8IHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMubGVuZ3RoID09PSAwIHx8IHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMuc29tZSgoY29sdW1uKSA9PiB0eXBlb2YgY29sdW1uICE9PSAic3RyaW5nIiB8fCAhY29sdW1uLnRyaW0oKSkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuZmlsdGVycy5hbGxvd2VkT3BlcmF0b3JzKSB8fCB2YWx1ZS5maWx0ZXJzLmFsbG93ZWRPcGVyYXRvcnMubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoYHN0cnVjdHVyZWQgcXVlcnkgcGxhbiAke3BhdGh9IGZpbHRlcnMgbXVzdCBkZWNsYXJlIGFuIGFyZ3VtZW50LCBhbGxvd2VkIGNvbHVtbnMsIGFuZCBhbGxvd2VkIG9wZXJhdG9yc2ApOwoJCWNvbnN0IG9wZXJhdG9ycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCQkJImNvbnRhaW5zIiwKCQkJIm5vdENvbnRhaW5zIiwKCQkJImVxdWFscyIsCgkJCSJub3RFcXVhbHMiLAoJCQkic3RhcnRzV2l0aCIsCgkJCSJlbmRzV2l0aCIsCgkJCSJlbXB0eSIsCgkJCSJub3RFbXB0eSIsCgkJCSJvbmVPZiIsCgkJCSJsZXNzVGhhbiIsCgkJCSJsZXNzVGhhbk9yRXF1YWwiLAoJCQkiZ3JlYXRlclRoYW4iLAoJCQkiZ3JlYXRlclRoYW5PckVxdWFsIiwKCQkJImluUmFuZ2UiCgkJXSk7CgkJaWYgKHZhbHVlLmZpbHRlcnMuYWxsb3dlZE9wZXJhdG9ycy5zb21lKChvcGVyYXRvcikgPT4gdHlwZW9mIG9wZXJhdG9yICE9PSAic3RyaW5nIiB8fCAhb3BlcmF0b3JzLmhhcyhvcGVyYXRvcikpKSB0aHJvdyBuZXcgRXJyb3IoYHN0cnVjdHVyZWQgcXVlcnkgcGxhbiAke3BhdGh9IGZpbHRlcnMgY29udGFpbnMgYW4gdW5zdXBwb3J0ZWQgb3BlcmF0b3JgKTsKCX0KfTsKY29uc3QgdmlzaWJpbGl0eU9wZXJhdG9ycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCSJwdWJsaWMiLAoJInBlcm1pc3Npb24iLAoJInJvbGUiLAoJImVxQ29udGV4dCIsCgkiaW5TZXQiLAoJImFuZCIsCgkib3IiLAoJIm5vdCIKXSk7CmNvbnN0IHZpc2liaWxpdHlDb250ZXh0cyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCSJhY2NvdW50LmlkIiwKCSJtZW1iZXIuaWQiLAoJInRlbmFudC5pZCIKXSk7CmNvbnN0IHZhbGlkYXRlRXhhY3RPYmplY3QgPSAodmFsdWUsIHBhdGgsIGZpZWxkcykgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofSBtdXN0IGJlIGFuIG9iamVjdGApOwoJY29uc3QgYWxsb3dlZCA9IG5ldyBTZXQoZmllbGRzKTsKCWNvbnN0IHVuZXhwZWN0ZWQgPSBPYmplY3Qua2V5cyh2YWx1ZSkuZmluZCgoZmllbGQpID0+ICFhbGxvd2VkLmhhcyhmaWVsZCkpOwoJaWYgKHVuZXhwZWN0ZWQgIT09IHZvaWQgMCkgdGhyb3cgbmV3IEVycm9yKGAke3BhdGh9IGhhcyB1bnN1cHBvcnRlZCBmaWVsZCAke3VuZXhwZWN0ZWR9YCk7Cn07CmNvbnN0IHJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nID0gKHZhbHVlLCBwYXRoKSA9PiB7CglpZiAodHlwZW9mIHZhbHVlICE9PSAic3RyaW5nIiB8fCAhdmFsdWUudHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdgKTsKCXJldHVybiB2YWx1ZTsKfTsKY29uc3QgdmFsaWRhdGVWaXNpYmlsaXR5Q29udGV4dCA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKHR5cGVvZiB2YWx1ZSAhPT0gInN0cmluZyIgfHwgIXZpc2liaWxpdHlDb250ZXh0cy5oYXModmFsdWUpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0gbXVzdCBiZSBhY2NvdW50LmlkLCBtZW1iZXIuaWQsIG9yIHRlbmFudC5pZGApOwoJcmV0dXJuIHZhbHVlOwp9Owpjb25zdCB2YWxpZGF0ZVZpc2liaWxpdHlFeHByZXNzaW9uID0gKHZhbHVlLCBwYXRoLCBzZXRzLCBhbmNlc3RvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKSA9PiB7Cgl2YWxpZGF0ZUV4YWN0T2JqZWN0KHZhbHVlLCBwYXRoLCBbCgkJIm9wZXJhdG9yIiwKCQkiY29sdW1uIiwKCQkiY29udGV4dCIsCgkJInNldCIsCgkJInZhbHVlIiwKCQkiY2hpbGRyZW4iCgldKTsKCWlmIChhbmNlc3RvcnMuaGFzKHZhbHVlKSkgdGhyb3cgbmV3IEVycm9yKGAke3BhdGh9IGNvbnRhaW5zIGEgY3ljbGVgKTsKCWNvbnN0IG9wZXJhdG9yID0gdmFsdWUub3BlcmF0b3I7CglpZiAodHlwZW9mIG9wZXJhdG9yICE9PSAic3RyaW5nIiB8fCAhdmlzaWJpbGl0eU9wZXJhdG9ycy5oYXMob3BlcmF0b3IpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0ub3BlcmF0b3IgaXMgdW5zdXBwb3J0ZWRgKTsKCWNvbnN0IG5lc3RlZCA9IG5ldyBTZXQoYW5jZXN0b3JzKTsKCW5lc3RlZC5hZGQodmFsdWUpOwoJc3dpdGNoIChvcGVyYXRvcikgewoJCWNhc2UgInB1YmxpYyI6CgkJCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsib3BlcmF0b3IiXSk7CgkJCXJldHVybjsKCQljYXNlICJwZXJtaXNzaW9uIjoKCQljYXNlICJyb2xlIjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJ2YWx1ZSJdKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcodmFsdWUudmFsdWUsIGAke3BhdGh9LnZhbHVlYCk7CgkJCXJldHVybjsKCQljYXNlICJlcUNvbnRleHQiOgoJCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KHZhbHVlLCBwYXRoLCBbCgkJCQkib3BlcmF0b3IiLAoJCQkJImNvbHVtbiIsCgkJCQkiY29udGV4dCIKCQkJXSk7CgkJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKHZhbHVlLmNvbHVtbiwgYCR7cGF0aH0uY29sdW1uYCk7CgkJCXZhbGlkYXRlVmlzaWJpbGl0eUNvbnRleHQodmFsdWUuY29udGV4dCwgYCR7cGF0aH0uY29udGV4dGApOwoJCQlyZXR1cm47CgkJY2FzZSAiaW5TZXQiOiB7CgkJCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsKCQkJCSJvcGVyYXRvciIsCgkJCQkiY29sdW1uIiwKCQkJCSJzZXQiCgkJCV0pOwoJCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyh2YWx1ZS5jb2x1bW4sIGAke3BhdGh9LmNvbHVtbmApOwoJCQljb25zdCBzZXQgPSByZXF1aXJlVmlzaWJpbGl0eVN0cmluZyh2YWx1ZS5zZXQsIGAke3BhdGh9LnNldGApOwoJCQlpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzZXRzLCBzZXQpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0uc2V0IHJlZmVyZW5jZXMgdW5rbm93biB2aXNpYmlsaXR5IHNldCAke3NldH1gKTsKCQkJcmV0dXJuOwoJCX0KCQljYXNlICJhbmQiOgoJCWNhc2UgIm9yIjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJjaGlsZHJlbiJdKTsKCQkJaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlLmNoaWxkcmVuKSB8fCB2YWx1ZS5jaGlsZHJlbi5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS4ke29wZXJhdG9yfSByZXF1aXJlcyBjaGlsZHJlbmApOwoJCQl2YWx1ZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCwgaW5kZXgpID0+IHZhbGlkYXRlVmlzaWJpbGl0eUV4cHJlc3Npb24oY2hpbGQsIGAke3BhdGh9LmNoaWxkcmVuWyR7aW5kZXh9XWAsIHNldHMsIG5lc3RlZCkpOwoJCQlyZXR1cm47CgkJY2FzZSAibm90IjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJjaGlsZHJlbiJdKTsKCQkJaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlLmNoaWxkcmVuKSB8fCB2YWx1ZS5jaGlsZHJlbi5sZW5ndGggIT09IDEpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS5ub3QgcmVxdWlyZXMgZXhhY3RseSBvbmUgY2hpbGRgKTsKCQkJdmFsaWRhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbih2YWx1ZS5jaGlsZHJlblswXSwgYCR7cGF0aH0uY2hpbGRyZW5bMF1gLCBzZXRzLCBuZXN0ZWQpOwoJCQlyZXR1cm47Cgl9Cn07CmNvbnN0IHZhbGlkYXRlVmlzaWJpbGl0eVBsYW4gPSAodmFsdWUsIHBhdGgpID0+IHsKCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsKCQkidGFibGUiLAoJCSJrZXkiLAoJCSJzZXRzIiwKCQkid2hlcmUiCgldKTsKCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKHZhbHVlLnRhYmxlLCBgJHtwYXRofS50YWJsZWApOwoJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcodmFsdWUua2V5LCBgJHtwYXRofS5rZXlgKTsKCWlmICghaXNSZWNvcmQodmFsdWUuc2V0cykpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS5zZXRzIG11c3QgYmUgYW4gb2JqZWN0YCk7Cglmb3IgKGNvbnN0IFtuYW1lLCBjYW5kaWRhdGVdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlLnNldHMpKSB7CgkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcobmFtZSwgYCR7cGF0aH0uc2V0cyBrZXlgKTsKCQljb25zdCBzZXRQYXRoID0gYCR7cGF0aH0uc2V0cy4ke25hbWV9YDsKCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KGNhbmRpZGF0ZSwgc2V0UGF0aCwgWwoJCQkidGFibGUiLAoJCQkic2VsZWN0IiwKCQkJImpvaW5zIiwKCQkJIndoZXJlIgoJCV0pOwoJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKGNhbmRpZGF0ZS50YWJsZSwgYCR7c2V0UGF0aH0udGFibGVgKTsKCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyhjYW5kaWRhdGUuc2VsZWN0LCBgJHtzZXRQYXRofS5zZWxlY3RgKTsKCQlpZiAoIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlLmpvaW5zKSkgdGhyb3cgbmV3IEVycm9yKGAke3NldFBhdGh9LmpvaW5zIG11c3QgYmUgYW4gYXJyYXlgKTsKCQljYW5kaWRhdGUuam9pbnMuZm9yRWFjaCgoam9pbiwgaW5kZXgpID0+IHsKCQkJY29uc3Qgam9pblBhdGggPSBgJHtzZXRQYXRofS5qb2luc1ske2luZGV4fV1gOwoJCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KGpvaW4sIGpvaW5QYXRoLCBbCgkJCQkidGFibGUiLAoJCQkJImxlZnRDb2x1bW4iLAoJCQkJInJpZ2h0Q29sdW1uIgoJCQldKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoam9pbi50YWJsZSwgYCR7am9pblBhdGh9LnRhYmxlYCk7CgkJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKGpvaW4ubGVmdENvbHVtbiwgYCR7am9pblBhdGh9LmxlZnRDb2x1bW5gKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoam9pbi5yaWdodENvbHVtbiwgYCR7am9pblBhdGh9LnJpZ2h0Q29sdW1uYCk7CgkJfSk7CgkJaWYgKCFBcnJheS5pc0FycmF5KGNhbmRpZGF0ZS53aGVyZSkpIHRocm93IG5ldyBFcnJvcihgJHtzZXRQYXRofS53aGVyZSBtdXN0IGJlIGFuIGFycmF5YCk7CgkJY2FuZGlkYXRlLndoZXJlLmZvckVhY2goKGNvbnN0cmFpbnQsIGluZGV4KSA9PiB7CgkJCWNvbnN0IGNvbnN0cmFpbnRQYXRoID0gYCR7c2V0UGF0aH0ud2hlcmVbJHtpbmRleH1dYDsKCQkJdmFsaWRhdGVFeGFjdE9iamVjdChjb25zdHJhaW50LCBjb25zdHJhaW50UGF0aCwgWwoJCQkJInRhYmxlIiwKCQkJCSJjb2x1bW4iLAoJCQkJImNvbnRleHQiCgkJCV0pOwoJCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyhjb25zdHJhaW50LnRhYmxlLCBgJHtjb25zdHJhaW50UGF0aH0udGFibGVgKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoY29uc3RyYWludC5jb2x1bW4sIGAke2NvbnN0cmFpbnRQYXRofS5jb2x1bW5gKTsKCQkJdmFsaWRhdGVWaXNpYmlsaXR5Q29udGV4dChjb25zdHJhaW50LmNvbnRleHQsIGAke2NvbnN0cmFpbnRQYXRofS5jb250ZXh0YCk7CgkJfSk7Cgl9Cgl2YWxpZGF0ZVZpc2liaWxpdHlFeHByZXNzaW9uKHZhbHVlLndoZXJlLCBgJHtwYXRofS53aGVyZWAsIHZhbHVlLnNldHMpOwp9Owpjb25zdCBmcmVlemVWaXNpYmlsaXR5RXhwcmVzc2lvbiA9IChleHByZXNzaW9uKSA9PiBmcmVlemUoewoJLi4uZXhwcmVzc2lvbiwKCWNoaWxkcmVuOiBleHByZXNzaW9uLmNoaWxkcmVuID09PSB2b2lkIDAgPyB2b2lkIDAgOiBmcmVlemUoZXhwcmVzc2lvbi5jaGlsZHJlbi5tYXAoZnJlZXplVmlzaWJpbGl0eUV4cHJlc3Npb24pKQp9KTsKY29uc3QgZnJlZXplVmlzaWJpbGl0eVBsYW4gPSAocGxhbikgPT4gewoJY29uc3Qgc2V0cyA9IHt9OwoJZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHBsYW4uc2V0cykuc29ydCgpKSB7CgkJY29uc3Qgc2V0ID0gcGxhbi5zZXRzW25hbWVdOwoJCXNldHNbbmFtZV0gPSBmcmVlemUoewoJCQkuLi5zZXQsCgkJCWpvaW5zOiBmcmVlemUoc2V0LmpvaW5zLm1hcCgoam9pbikgPT4gZnJlZXplKHsgLi4uam9pbiB9KSkpLAoJCQl3aGVyZTogZnJlZXplKHNldC53aGVyZS5tYXAoKGNvbnN0cmFpbnQpID0+IGZyZWV6ZSh7IC4uLmNvbnN0cmFpbnQgfSkpKQoJCX0pOwoJfQoJcmV0dXJuIGZyZWV6ZSh7CgkJLi4ucGxhbiwKCQlzZXRzOiBmcmVlemUoc2V0cyksCgkJd2hlcmU6IGZyZWV6ZVZpc2liaWxpdHlFeHByZXNzaW9uKHBsYW4ud2hlcmUpCgl9KTsKfTsKLyoqIERlY2xhcmUgYW5kIHZhbGlkYXRlIG9uZSBzb3VyY2UgdGFibGUncyBsYW5ndWFnZS1uZXV0cmFsIHZpc2liaWxpdHkgcGxhbi4gKi8KZnVuY3Rpb24gdmlzaWJpbGl0eShvcHRpb25zKSB7Cgl2YWxpZGF0ZVZpc2liaWxpdHlQbGFuKG9wdGlvbnMsICJ2aXNpYmlsaXR5Iik7CglyZXR1cm4gZnJlZXplVmlzaWJpbGl0eVBsYW4ob3B0aW9ucyk7Cn0KY29uc3QgZXhlY3V0YWJsZU9wdGlvbnMgPSAob3B0aW9ucykgPT4gZnJlZXplKHsgLi4ub3B0aW9ucyB9KTsKY29uc3QgcXVlcnlEZWZpbml0aW9uID0gKG9wdGlvbnMsIGRlbGl2ZXJ5T3ZlcnJpZGUpID0+IHsKCWNvbnN0IGxpdmVRdWVyeVBsYW4gPSBvcHRpb25zLmxpdmVRdWVyeVBsYW47Cgljb25zdCByZXBsaWNhID0gb3B0aW9ucy5yZXBsaWNhOwoJY29uc3QgZGVsaXZlcnkgPSBkZWxpdmVyeU92ZXJyaWRlID8/IG9wdGlvbnMuZGVsaXZlcnkgPz8gIm9uZVNob3QiOwoJaWYgKGRlbGl2ZXJ5ID09PSAibGl2ZSIgJiYgIWxpdmVRdWVyeVBsYW4pIHRocm93IG5ldyBFcnJvcigibGl2ZSBxdWVyeSByZXF1aXJlcyBhIGxpdmUgcXVlcnkgcGxhbiIpOwoJaWYgKGRlbGl2ZXJ5ID09PSAib25lU2hvdCIpIHsKCQlpZiAoIWxpdmVRdWVyeVBsYW4pIHRocm93IG5ldyBFcnJvcigib25lLXNob3QgcXVlcnkgcmVxdWlyZXMgYSBzdHJ1Y3R1cmVkIGxpdmUgcXVlcnkgcGxhbiIpOwoJCXZhbGlkYXRlU3RydWN0dXJlZFF1ZXJ5UGxhbihsaXZlUXVlcnlQbGFuLCAiPGV4cG9ydD4iKTsKCX0KCWlmIChkZWxpdmVyeSA9PT0gInJlcGxpY2EiKSB7CgkJaWYgKCFyZXBsaWNhKSB0aHJvdyBuZXcgRXJyb3IoInJlcGxpY2EgY29sbGVjdGlvbiByZXF1aXJlcyBhIHJlcGxpY2EgZGVmaW5pdGlvbiIpOwoJCXZhbGlkYXRlUmVwbGljYUNvbGxlY3Rpb24ocmVwbGljYSwgIjxleHBvcnQ+Iik7Cgl9CglyZXR1cm4gZnJlZXplKHsKCQlraW5kOiAicXVlcnkiLAoJCWRlbGl2ZXJ5LAoJCWxpdmVRdWVyeVBsYW4sCgkJcmVwbGljYSwKCQlvcHRpb25zOiBleGVjdXRhYmxlT3B0aW9ucyhvcHRpb25zKSwKCQloYW5kbGVyOiBvcHRpb25zLnJ1bgoJfSk7Cn07Ci8qKiBEZWNsYXJlIGFuIGV4ZWN1dGFibGUgbGl2ZSBxdWVyeSBleHBvcnQgd2l0aCBhIHN0cnVjdHVyZWQgbGl2ZSBwbGFuLiAqLwpmdW5jdGlvbiBsaXZlUXVlcnkob3B0aW9ucyA9IHt9KSB7CglyZXR1cm4gcXVlcnlEZWZpbml0aW9uKHsKCQkuLi5vcHRpb25zLAoJCWRlbGl2ZXJ5OiAibGl2ZSIKCX0sICJsaXZlIik7Cn0KY29uc3QgcmVkdWNlckRlZmluaXRpb24gPSAob3B0aW9ucywgaW50ZXJuYWwgPSBmYWxzZSkgPT4gewoJdmFsaWRhdGVPZmZsaW5lUG9saWN5KG9wdGlvbnMub2ZmbGluZSwgIjxleHBvcnQ+Iik7CglpZiAob3B0aW9ucy5vcHRpbWlzdGljICE9PSB2b2lkIDApIHZhbGlkYXRlT3B0aW1pc3RpY1RyYW5zYWN0aW9uKG9wdGlvbnMub3B0aW1pc3RpYywgIjxleHBvcnQ+Iik7CglpZiAob3B0aW9ucy5pbnRlcmFjdGl2ZSA9PT0gZmFsc2UgJiYgb3B0aW9ucy5vcHRpbWlzdGljICE9PSB2b2lkIDApIHRocm93IG5ldyBFcnJvcigibm9uLWludGVyYWN0aXZlIHJlZHVjZXIgPGV4cG9ydD4gY2Fubm90IGRlY2xhcmUgb3B0aW1pc3RpYyBtZXRhZGF0YSIpOwoJaWYgKG9wdGlvbnMuaW50ZXJhY3RpdmUgIT09IGZhbHNlICYmIG9wdGlvbnMub3B0aW1pc3RpYyA9PT0gdm9pZCAwICYmICFvcHRpb25zLm5vbk9wdGltaXN0aWNSZWFzb24/LnRyaW0oKSkgdGhyb3cgbmV3IEVycm9yKCJpbnRlcmFjdGl2ZSByZWR1Y2VyIDxleHBvcnQ+IHJlcXVpcmVzIGFuIG9wdGltaXN0aWMgdHJhbnNhY3Rpb24gb3Igbm9uT3B0aW1pc3RpY1JlYXNvbiIpOwoJcmV0dXJuIGZyZWV6ZSh7CgkJa2luZDogInJlZHVjZXIiLAoJCWludGVybmFsOiBpbnRlcm5hbCB8fCBvcHRpb25zLmludGVybmFsLAoJCW9wdGlvbnM6IGV4ZWN1dGFibGVPcHRpb25zKG9wdGlvbnMpLAoJCWhhbmRsZXI6IG9wdGlvbnMucnVuCgl9KTsKfTsKLyoqIERlY2xhcmUgYW4gZXhlY3V0YWJsZSBwdWJsaWMgcmVkdWNlciBleHBvcnQuICovCmZ1bmN0aW9uIHJlZHVjZXIob3B0aW9ucykgewoJcmV0dXJuIHJlZHVjZXJEZWZpbml0aW9uKG9wdGlvbnMpOwp9Ci8vI2VuZHJlZ2lvbgovLyNyZWdpb24gZ29udmV4L21lc3NhZ2VzLnRzCmNvbnN0IG1lc3NhZ2VzVmlzaWJpbGl0eSA9IHZpc2liaWxpdHkoewoJdGFibGU6ICJtZXNzYWdlcyIsCglrZXk6ICJpZCIsCglzZXRzOiB7fSwKCXdoZXJlOiB7IG9wZXJhdG9yOiAicHVibGljIiB9Cn0pOwpjb25zdCBsaXN0ID0gbGl2ZVF1ZXJ5KHsKCWFyZ3M6IHNjaGVtYS5vYmplY3Qoe30pLAoJcmVzdWx0OiBzY2hlbWEuYXJyYXkoc2NoZW1hLm9iamVjdCh7CgkJaWQ6IHNjaGVtYS5pZCgibWVzc2FnZXMiKSwKCQlib2R5OiBzY2hlbWEuc3RyaW5nKCksCgkJYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCgkJY3JlYXRlZF9hdDogc2NoZW1hLmRhdGV0aW1lKCkKCX0pKSwKCWxpdmVRdWVyeVBsYW46IHsKCQl0YWJsZTogIm1lc3NhZ2VzIiwKCQlrZXk6ICJpZCIsCgkJY29sdW1uczogWwoJCQkiaWQiLAoJCQkiYm9keSIsCgkJCSJhdXRob3IiLAoJCQkiY3JlYXRlZF9hdCIKCQldLAoJCXNvcnQ6IHsKCQkJZGVmYXVsdENvbHVtbjogImNyZWF0ZWRfYXQiLAoJCQlkZWZhdWx0RGlyZWN0aW9uOiAiYXNjIiwKCQkJYWxsb3dlZENvbHVtbnM6IFsiY3JlYXRlZF9hdCJdCgkJfQoJfSwKCXJ1bjogYXN5bmMgKCkgPT4gW10KfSk7CmNvbnN0IHNlbmQgPSByZWR1Y2VyKHsKCWFyZ3M6IHNjaGVtYS5vYmplY3QoeyBib2R5OiBzY2hlbWEuc3RyaW5nKCkgfSksCglyZXN1bHQ6IHNjaGVtYS5vYmplY3QoewoJCWlkOiBzY2hlbWEuaWQoIm1lc3NhZ2VzIiksCgkJYm9keTogc2NoZW1hLnN0cmluZygpLAoJCWF1dGhvcjogc2NoZW1hLnN0cmluZygpLAoJCWNyZWF0ZWRfYXQ6IHNjaGVtYS5kYXRldGltZSgpCgl9KSwKCW9mZmxpbmU6IHsKCQltb2RlOiAib25saW5lT25seSIsCgkJcmVhc29uOiAic2VydmVyIGFzc2lnbnMgdGhlIG1lc3NhZ2UgaWQiCgl9LAoJbm9uT3B0aW1pc3RpY1JlYXNvbjogInNlcnZlciBhc3NpZ25zIHRoZSBtZXNzYWdlIGlkIiwKCXJ1bjogYXN5bmMgKHsgbm93IH0sIGFyZ3MpID0+ICh7CgkJaWQ6ICJwZW5kaW5nIiwKCQlib2R5OiBhcmdzLmJvZHksCgkJYXV0aG9yOiAiZGVtby11c2VyIiwKCQljcmVhdGVkX2F0OiBuZXcgRGF0ZShub3cpLnRvSVNPU3RyaW5nKCkKCX0pCn0pOwovLyNlbmRyZWdpb24KZXhwb3J0IHsgbGlzdCwgbWVzc2FnZXNWaXNpYmlsaXR5LCBzZW5kIH07Cg=="
119
+ }
120
+ }
@@ -1,3 +1,3 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
- export { ConvexProvider, ConvexProviderWithAuth, ConvexReactClient, createGonvexAuth, GonvexAuthProvider, GonvexGoogleAuthButton, GonvexProvider, useAction, useConvex, useConvexAuth, useConvexConnectionState, useGonvexAuth, useMutation, usePaginatedQuery, useQuery, useSync, useSyncSelector } from "@gonvex/react";
3
- export type { GonvexAuthConfig, GonvexAuthTenant, GonvexAuthUser, GonvexAuthValue } from "@gonvex/react";
2
+ export { createGonvexAuth, GonvexAuthProvider, GonvexGoogleAuthButton, GonvexProvider, GonvexProviderWithAuth, useAction, useControlQuery, useCurrentTenantProfile, useEntity, useGonvexAuth, useGonvexAuthState, useGonvexClient, useGonvexConnectionState, useInvitationList, useLiveQuery, useLiveQueryState, useQuery, useReducer, useReplicaCollection, useReplicaCollectionState, useReplicaEntities, useReplicaSelector, useRetainedLiveQuery } from "@gonvex/react";
3
+ export type { GonvexAuthAccount, GonvexAuthConfig, GonvexAuthProviderName, GonvexAuthTenant, GonvexAuthValue } from "@gonvex/react";
@@ -1,7 +1,7 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
2
 
3
- export const landlord = {
4
- scope: "landlord",
3
+ export const controlPlane = {
4
+ scope: "control-plane",
5
5
  tables: {
6
6
  },
7
7
  } as const;
@@ -9,47 +9,17 @@ export const landlord = {
9
9
  export const tenant = {
10
10
  scope: "tenant",
11
11
  tables: {
12
- messages: {
13
- columns: {
14
- author: {
15
- nullable: false,
16
- primaryKey: false,
17
- type: "string",
18
- },
19
- body: {
20
- nullable: false,
21
- primaryKey: false,
22
- type: "string",
23
- },
24
- created_at: {
25
- nullable: false,
26
- primaryKey: false,
27
- type: "time",
28
- },
29
- id: {
30
- nullable: false,
31
- primaryKey: true,
32
- type: "id",
33
- },
34
- },
35
- indexes: {
36
- by_created_at: {
37
- columns: ["created_at"],
38
- unique: false,
39
- },
40
- },
41
- },
42
12
  },
43
13
  } as const;
44
14
 
45
15
  export const tables = tenant.tables;
46
16
 
47
17
  export const schema = {
48
- landlord,
18
+ controlPlane,
49
19
  tenant,
50
20
  tables,
51
21
  } as const;
52
22
 
53
- export type LandlordTableName = keyof typeof landlord.tables;
23
+ export type ControlPlaneTableName = keyof typeof controlPlane.tables;
54
24
  export type TenantTableName = keyof typeof tenant.tables;
55
25
  export type TableName = TenantTableName;
@@ -3,39 +3,10 @@
3
3
  export const schema = {
4
4
  scope: "tenant",
5
5
  tables: {
6
- messages: {
7
- columns: {
8
- author: {
9
- nullable: false,
10
- primaryKey: false,
11
- type: "string",
12
- },
13
- body: {
14
- nullable: false,
15
- primaryKey: false,
16
- type: "string",
17
- },
18
- created_at: {
19
- nullable: false,
20
- primaryKey: false,
21
- type: "time",
22
- },
23
- id: {
24
- nullable: false,
25
- primaryKey: true,
26
- type: "id",
27
- },
28
- },
29
- indexes: {
30
- by_created_at: {
31
- columns: ["created_at"],
32
- unique: false,
33
- },
34
- },
35
- },
36
6
  },
37
7
  } as const;
38
8
 
9
+ export const tenant = schema;
39
10
  export const tables = schema.tables;
40
11
 
41
12
  export type TableName = keyof typeof tables;
@@ -3,36 +3,6 @@
3
3
  export const scope = "tenant" as const;
4
4
 
5
5
  export const tables = {
6
- messages: {
7
- columns: {
8
- author: {
9
- nullable: false,
10
- primaryKey: false,
11
- type: "string",
12
- },
13
- body: {
14
- nullable: false,
15
- primaryKey: false,
16
- type: "string",
17
- },
18
- created_at: {
19
- nullable: false,
20
- primaryKey: false,
21
- type: "time",
22
- },
23
- id: {
24
- nullable: false,
25
- primaryKey: true,
26
- type: "id",
27
- },
28
- },
29
- indexes: {
30
- by_created_at: {
31
- columns: ["created_at"],
32
- unique: false,
33
- },
34
- },
35
- },
36
6
  } as const;
37
7
 
38
8
  export type TableName = keyof typeof tables;
@@ -0,0 +1 @@
1
+ export { list, send, messagesVisibility } from "./messages.ts";
@@ -0,0 +1,47 @@
1
+ import { liveQuery, reducer, schema, visibility } from "@gonvex/module-sdk";
2
+
3
+ export const messagesVisibility = visibility({
4
+ table: "messages",
5
+ key: "id",
6
+ sets: {},
7
+ where: { operator: "public" },
8
+ });
9
+
10
+ export const list = liveQuery({
11
+ args: schema.object({}),
12
+ result: schema.array(schema.object({
13
+ id: schema.id("messages"),
14
+ body: schema.string(),
15
+ author: schema.string(),
16
+ created_at: schema.datetime(),
17
+ })),
18
+ liveQueryPlan: {
19
+ table: "messages",
20
+ key: "id",
21
+ columns: ["id", "body", "author", "created_at"],
22
+ sort: {
23
+ defaultColumn: "created_at",
24
+ defaultDirection: "asc",
25
+ allowedColumns: ["created_at"],
26
+ },
27
+ },
28
+ run: async () => [],
29
+ });
30
+
31
+ export const send = reducer({
32
+ args: schema.object({ body: schema.string() }),
33
+ result: schema.object({
34
+ id: schema.id("messages"),
35
+ body: schema.string(),
36
+ author: schema.string(),
37
+ created_at: schema.datetime(),
38
+ }),
39
+ offline: { mode: "onlineOnly", reason: "server assigns the message id" },
40
+ nonOptimisticReason: "server assigns the message id",
41
+ run: async ({ now }, args) => ({
42
+ id: "pending",
43
+ body: args.body,
44
+ author: "demo-user",
45
+ created_at: new Date(now).toISOString(),
46
+ }),
47
+ });
@@ -0,0 +1,9 @@
1
+ -- gonvex:scope tenant
2
+ CREATE TABLE IF NOT EXISTS messages (
3
+ id text PRIMARY KEY,
4
+ body text NOT NULL,
5
+ author text NOT NULL,
6
+ created_at timestamptz NOT NULL
7
+ );
8
+
9
+ CREATE INDEX IF NOT EXISTS by_created_at ON messages (created_at);
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@gonvex/client": "latest",
18
+ "@gonvex/module-sdk": "latest",
18
19
  "@gonvex/react": "latest",
19
20
  "react": "latest",
20
21
  "react-dom": "latest"
@@ -1,6 +1,6 @@
1
1
  import { useState } from "react";
2
2
  import { api } from "../gonvex/_generated/api";
3
- import { useMutation, useQuery } from "../gonvex/_generated/react";
3
+ import { useLiveQuery, useReducer } from "../gonvex/_generated/react";
4
4
 
5
5
  type Message = {
6
6
  id: string;
@@ -10,8 +10,8 @@ type Message = {
10
10
  };
11
11
 
12
12
  export default function App(props: { runtimeURL: string }) {
13
- const messages = useQuery<Message[]>(api.messages.list, {}) ?? [];
14
- const sendMessage = useMutation(api.messages.send);
13
+ const messages = useLiveQuery<Message[]>(api.messages.list, {}) ?? [];
14
+ const sendMessage = useReducer(api.messages.send);
15
15
  const [body, setBody] = useState("");
16
16
 
17
17
  async function submit() {
@@ -25,9 +25,9 @@ export default function App(props: { runtimeURL: string }) {
25
25
  <main className="shell">
26
26
  <section className="hero">
27
27
  <div className="status">Connected to {props.runtimeURL}</div>
28
- <h1>Gonvex app code. Go backend. Realtime React.</h1>
28
+ <h1>Gonvex app code. TypeScript backend. Realtime React.</h1>
29
29
  <p>
30
- Edit <code>gonvex/messages.go</code> or <code>gonvex/schema.go</code>. The CLI regenerates bindings and syncs safe schema changes to the runtime.
30
+ Edit <code>gonvex/messages.ts</code> or the versioned SQL migration in <code>migrations/</code>. The CLI regenerates bindings and applies migrations to the runtime.
31
31
  </p>
32
32
  </section>
33
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonvex/cli",
3
- "version": "0.1.32",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "gonvex": "./dist/index.js"
@@ -25,8 +25,9 @@
25
25
  "README.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@gonvex/client": "0.1.32",
29
- "@gonvex/react": "0.1.32"
28
+ "rolldown": "^1.2.3",
29
+ "@gonvex/client": "0.3.1",
30
+ "@gonvex/react": "0.3.1"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@types/node": "^24.12.4",
@@ -1,38 +0,0 @@
1
- package backend
2
-
3
- import (
4
- "time"
5
-
6
- "github.com/gonvex/gonvex/pkg/gonvex"
7
- )
8
-
9
- type ListMessagesArgs struct{}
10
-
11
- type SendMessageArgs struct {
12
- Body string `json:"body"`
13
- }
14
-
15
- type Message struct {
16
- ID string `json:"id"`
17
- Body string `json:"body"`
18
- Author string `json:"author"`
19
- CreatedAt time.Time `json:"created_at"`
20
- }
21
-
22
- func Register(app *gonvex.App) {
23
- app.Query("messages.list", ListMessages)
24
- app.Mutation("messages.send", SendMessage)
25
- }
26
-
27
- func ListMessages(ctx *gonvex.QueryCtx, args ListMessagesArgs) ([]Message, error) {
28
- return []Message{}, nil
29
- }
30
-
31
- func SendMessage(ctx *gonvex.MutationCtx, args SendMessageArgs) (Message, error) {
32
- return Message{
33
- ID: "pending",
34
- Body: args.Body,
35
- Author: "demo-user",
36
- CreatedAt: time.Now().UTC(),
37
- }, nil
38
- }
@@ -1,14 +0,0 @@
1
- package backend
2
-
3
- import "github.com/gonvex/gonvex/pkg/gonvex"
4
-
5
- func Schema(s *gonvex.Schema) {
6
- s.TenantTable("messages", func(t *gonvex.Table) {
7
- t.ID("id")
8
- t.String("body")
9
- t.String("author")
10
- t.Time("created_at")
11
-
12
- t.Index("by_created_at", "created_at")
13
- })
14
- }