@monimesl/dot-cli 1.0.0-beta.0 → 1.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +22 -9
  2. package/dist/cli.js +24 -14
  3. package/dist/cli.js.map +1 -1
  4. package/dist/{server-DMnWDdJ6.js → server-BhnO9_Zu.js} +56 -7
  5. package/dist/server-BhnO9_Zu.js.map +1 -0
  6. package/dist/templates/showcase/.env +2 -2
  7. package/dist/templates/showcase/dot.ts +22 -2
  8. package/dist/templates/showcase/pages/basics/bars/controller.ts +2 -2
  9. package/dist/templates/showcase/pages/basics/bars/view.dml +2 -1
  10. package/dist/templates/showcase/pages/basics/bindings/state.ts +2 -2
  11. package/dist/templates/showcase/pages/basics/bindings/view.dml +2 -2
  12. package/dist/templates/showcase/pages/basics/colors/controller.ts +1 -1
  13. package/dist/templates/showcase/pages/basics/concert/view.dml +1 -1
  14. package/dist/templates/showcase/pages/basics/control-flow/controller.ts +1 -1
  15. package/dist/templates/showcase/pages/basics/control-flow/view.dml +1 -1
  16. package/dist/templates/showcase/pages/basics/events/controller.ts +1 -1
  17. package/dist/templates/showcase/pages/basics/events/view.dml +1 -1
  18. package/dist/templates/showcase/pages/basics/hooks/controller.ts +2 -1
  19. package/dist/templates/showcase/pages/basics/hooks/view.dml +2 -2
  20. package/dist/templates/showcase/pages/basics/navigation/controller.ts +1 -0
  21. package/dist/templates/showcase/pages/basics/navigation/view.dml +1 -1
  22. package/dist/templates/showcase/pages/basics/pick-genre/controller.ts +3 -3
  23. package/dist/templates/showcase/pages/basics/share/view.dml +2 -2
  24. package/dist/templates/showcase/pages/basics/state/controller.ts +9 -0
  25. package/dist/templates/showcase/pages/basics/state/state.ts +3 -0
  26. package/dist/templates/showcase/pages/basics/theme/controller.ts +28 -0
  27. package/dist/templates/showcase/pages/basics/theme/state.ts +4 -0
  28. package/dist/templates/showcase/pages/basics/theme/view.dml +50 -0
  29. package/dist/templates/showcase/pages/components/capture/controller.ts +25 -0
  30. package/dist/templates/showcase/pages/components/capture/state.ts +7 -0
  31. package/dist/templates/showcase/pages/components/capture/view.dml +32 -0
  32. package/dist/templates/showcase/pages/components/carousel/view.dml +2 -2
  33. package/dist/templates/showcase/pages/components/feedback/controller.ts +2 -1
  34. package/dist/templates/showcase/pages/components/feedback/state.ts +2 -2
  35. package/dist/templates/showcase/pages/components/feedback/view.dml +2 -2
  36. package/dist/templates/showcase/pages/components/forms/controller.ts +2 -2
  37. package/dist/templates/showcase/pages/components/forms/state.ts +1 -1
  38. package/dist/templates/showcase/pages/components/forms/view.dml +6 -5
  39. package/dist/templates/showcase/pages/components/icons/controller.ts +1 -0
  40. package/dist/templates/showcase/pages/components/icons/state.ts +1 -1
  41. package/dist/templates/showcase/pages/components/images/controller.ts +1 -1
  42. package/dist/templates/showcase/pages/components/images/state.ts +1 -1
  43. package/dist/templates/showcase/pages/components/images/view.dml +4 -4
  44. package/dist/templates/showcase/pages/components/layout/controller.ts +5 -1
  45. package/dist/templates/showcase/pages/components/layout/state.ts +2 -0
  46. package/dist/templates/showcase/pages/components/layout/view.dml +44 -6
  47. package/dist/templates/showcase/pages/components/lists/view.dml +12 -7
  48. package/dist/templates/showcase/pages/components/money/controller.ts +1 -1
  49. package/dist/templates/showcase/pages/components/money/view.dml +2 -2
  50. package/dist/templates/showcase/pages/components/pinned/controller.ts +10 -0
  51. package/dist/templates/showcase/pages/components/pinned/state.ts +25 -0
  52. package/dist/templates/showcase/pages/components/pinned/view.dml +42 -0
  53. package/dist/templates/showcase/pages/components/reading/state.ts +2 -2
  54. package/dist/templates/showcase/pages/components/sheets/controller.ts +1 -1
  55. package/dist/templates/showcase/pages/components/sheets/view.dml +1 -1
  56. package/dist/templates/showcase/pages/components/styles/view.dml +39 -4
  57. package/dist/templates/showcase/pages/components/tabs/state.ts +2 -2
  58. package/dist/templates/showcase/pages/components/tabs/view.dml +6 -5
  59. package/dist/templates/showcase/pages/components/text/view.dml +4 -4
  60. package/dist/templates/showcase/pages/dash/account/controller.ts +3 -0
  61. package/dist/templates/showcase/pages/dash/account/view.dml +2 -2
  62. package/dist/templates/showcase/pages/dash/cache/controller.ts +45 -16
  63. package/dist/templates/showcase/pages/dash/cache/state.ts +1 -0
  64. package/dist/templates/showcase/pages/dash/cache/view.dml +4 -0
  65. package/dist/templates/showcase/pages/dash/calls/controller.ts +3 -2
  66. package/dist/templates/showcase/pages/dash/contacts/controller.ts +1 -0
  67. package/dist/templates/showcase/pages/dash/crypto/controller.ts +2 -0
  68. package/dist/templates/showcase/pages/dash/crypto/view.dml +1 -1
  69. package/dist/templates/showcase/pages/dash/files/controller.ts +67 -32
  70. package/dist/templates/showcase/pages/dash/files/state.ts +1 -0
  71. package/dist/templates/showcase/pages/dash/files/view.dml +5 -1
  72. package/dist/templates/showcase/pages/dash/media/controller.ts +7 -1
  73. package/dist/templates/showcase/pages/dash/media/state.ts +2 -0
  74. package/dist/templates/showcase/pages/dash/network/controller.ts +5 -1
  75. package/dist/templates/showcase/pages/dash/network/view.dml +1 -1
  76. package/dist/templates/showcase/pages/dash/payments/cases.ts +40 -22
  77. package/dist/templates/showcase/pages/dash/payments/controller.ts +27 -3
  78. package/dist/templates/showcase/pages/dash/payments/state.ts +2 -0
  79. package/dist/templates/showcase/pages/dash/payments/view.dml +3 -1
  80. package/dist/templates/showcase/pages/dash/reminders/controller.ts +73 -0
  81. package/dist/templates/showcase/pages/dash/reminders/state.ts +6 -0
  82. package/dist/templates/showcase/pages/dash/reminders/view.dml +34 -0
  83. package/dist/templates/showcase/pages/dash/secrets/controller.ts +37 -14
  84. package/dist/templates/showcase/pages/dash/secrets/state.ts +1 -0
  85. package/dist/templates/showcase/pages/dash/secrets/view.dml +4 -0
  86. package/dist/templates/showcase/pages/dash/system/controller.ts +5 -0
  87. package/dist/templates/showcase/pages/dash/system/view.dml +4 -4
  88. package/dist/templates/showcase/pages/dash/ui/controller.ts +6 -1
  89. package/dist/templates/showcase/pages/index/controller.ts +1 -0
  90. package/dist/templates/showcase/pages/index/state.ts +30 -6
  91. package/dist/templates/showcase/statics/icons/ticket-stub.svg +1 -0
  92. package/dist/templates/starter/.env +2 -2
  93. package/dist/templates/starter/dot.ts +1 -0
  94. package/dist/templates/starter/pages/index/controller.ts +2 -0
  95. package/dist/templates/starter/pages/index/state.ts +2 -0
  96. package/dist/templates/starter/pages/index/view.dml +2 -1
  97. package/package.json +6 -6
  98. package/dist/server-DMnWDdJ6.js.map +0 -1
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # @monimesl/dot-cli
2
2
 
3
- The `dotctl` command. It creates dots, builds them and runs them in the simulator. Later it will
4
- also package, sign and publish them.
3
+ The `dotctl` command. It creates dots, builds them and runs them in the simulator and on phones.
4
+ Later it will also publish them.
5
5
 
6
6
  ```sh
7
7
  dotctl create [dir] # create a dot (asks for its name, package name and template)
8
8
  dotctl create page <path> # add a page to the dot you are in
9
- dotctl build [root] # build the dot, minified, into dist/ui and dist/logic
9
+ dotctl build [root] # build the dot for Dash into dist/, with the ZIP Dash downloads
10
10
  dotctl dev [root] # run the dot in the browser simulator and reload it on each change
11
11
  dotctl preview [root] # build as `build` does, then run that build in the browser simulator
12
12
  dotctl keys show # print this computer's developer key: its public key and key ID
@@ -18,7 +18,7 @@ dotctl lsp # start the .dml language server (editors run this)
18
18
  | `--out-dir <dir>` | `build`, `dev`, `preview` | Output directory (default: `<root>/dist`) |
19
19
  | `--conditions <list>` | `build`, `dev`, `preview` | Extra export conditions, such as `@monimesl/dot-source` |
20
20
  | `--port <port>` | `dev`, `preview` | Simulator port (default: `3680`, or the next free one) |
21
- | `--device` | `dev` | Also serve the dot to the Dot example apps on phones, through a QR code |
21
+ | `--device` | `dev` | Also serve the dot to phones on your network, through a QR code |
22
22
  | `--name <name>` | `create` | The dot's name, instead of asking |
23
23
  | `--package <name>` | `create` | The dot's package name, such as `com.mysalone.thing`, instead of asking |
24
24
  | `--template <name>` | `create` | `starter` (one page to build on, the default) or `showcase` (all features) |
@@ -28,10 +28,10 @@ dotctl lsp # start the .dml language server (editors run this)
28
28
 
29
29
  Creates a self-contained project for a new dot. It asks for:
30
30
 
31
- - **The name.** The default is `Dot`. The project goes in `dir`, or a folder named after the dot in
32
- kebab case.
31
+ - **The name.** The default comes from `dir`, such as `Plasas Kitchen` for `plasas-kitchen`, or is
32
+ `Dot`. The project goes in `dir`, or a folder named after the dot in kebab case.
33
33
  - **The package name.** A reverse domain name you own, such as `com.mysalone.thing`. It can't change
34
- after the dot is published. The default is `com.example.<the folder's name>`.
34
+ after the dot is published. The default is `com.example.<the name in kebab case>`.
35
35
  - **The template.** `starter` is one page to build on. `showcase` has a page for each feature.
36
36
 
37
37
  The dot depends on `@monimesl/dot-runtime` and `@monimesl/dot-cli`. Inside the Dot repository it
@@ -42,6 +42,17 @@ Then it offers to install the dependencies and start the simulator. If more than
42
42
  manager is installed (npm, pnpm, yarn or bun), it asks which to use. The default is the one that
43
43
  ran `dotctl`, or npm.
44
44
 
45
+ ## `dotctl build`
46
+
47
+ Builds the dot, minified, into `dist/`:
48
+
49
+ - `ui/` and `logic/` hold the two bundles. `ui/` also has the dot's `statics/` images.
50
+ - `manifest.json` tells Dash how to run the build.
51
+ - `<package>-<version>.zip` holds all of it. It's the one file Dash downloads.
52
+
53
+ The build fails if `network.hosts` in `dot.json` lists a local address, such as `localhost`. Dash
54
+ refuses those in a published dot. `dotctl dev` allows them.
55
+
45
56
  ## `dotctl dev`
46
57
 
47
58
  Builds the dot, opens it in the browser simulator, and builds it again each time you save:
@@ -52,8 +63,10 @@ Builds the dot, opens it in the browser simulator, and builds it again each time
52
63
  pages it had open.
53
64
  - If a build fails, the simulator shows the error and keeps running the last good build.
54
65
 
55
- With `--device`, it also serves each build to the Dot example apps on your local network. It prints
56
- a QR code. Scan it with an example app, and the app follows the dot in the same way. See
66
+ With `--device`, it also serves each build to phones on your local network. It prints a QR code.
67
+ Scan it with Live Test in Dash, or with a Dot example app, and the phone follows the dot in the
68
+ same way. To scan it in Dash, turn on Enable Dot Debugging in Developer Settings, then tap Live
69
+ Test on the Dots tab. Dash needs a [developer key](#developer-keys). See also
57
70
  [the example apps](../hosts/native/README.md#the-example-apps).
58
71
 
59
72
  ## `dotctl preview`
package/dist/cli.js CHANGED
@@ -158,6 +158,7 @@ function dotJson({ name, dotPackage, template }) {
158
158
  photoLibrary: "Choose a photo for your concert ticket",
159
159
  files: "Attach your concert ticket",
160
160
  contacts: "Choose a friend to send a ticket to",
161
+ reminders: "Remind you before your concert",
161
162
  payments: "Pay for concert tickets"
162
163
  };
163
164
  dot.network = { hosts: [
@@ -234,7 +235,7 @@ function formatJson(value) {
234
235
  }
235
236
  //#endregion
236
237
  //#region src/create/create.ts
237
- const DOT_PACKAGE_RULE = "Use lowercase words joined by dots, such as com.mysalone.thing.";
238
+ const DOT_PACKAGE_RULE = "Use lowercase words joined by dots, such as com.mysalone.thing";
238
239
  async function create({ name, dir, dotPackage, template = "starter" }) {
239
240
  const root = resolve(dir);
240
241
  if (existsSync(root) && readdirSync(root).length > 0) throw new CommandError(`${dir} already exists and is not empty. Choose another folder`);
@@ -387,7 +388,7 @@ async function loadDeveloperKey(path = defaultDeveloperKeyPath()) {
387
388
  throw error;
388
389
  }
389
390
  const privateKey = createPrivateKey(pem);
390
- if (privateKey.asymmetricKeyType !== "ed25519") throw new Error(`${path} is not an Ed25519 key. Make one with: openssl genpkey -algorithm ed25519 -out ${path}`);
391
+ if (privateKey.asymmetricKeyType !== "ed25519") throw new CommandError(`${path} isn't an Ed25519 key. Make one with: openssl genpkey -algorithm ed25519 -out ${path}`);
391
392
  return toDeveloperKey(privateKey);
392
393
  }
393
394
  function toDeveloperKey(privateKey) {
@@ -423,7 +424,7 @@ function buildMac(secret, body) {
423
424
  return hmacWithSecret(secret, `dotdev-build\n${body}`);
424
425
  }
425
426
  async function startDeviceServer({ address = localNetworkAddress(), port = 0, onLog = () => {}, onConnect = () => {}, developerKey } = {}) {
426
- if (address === void 0) throw new Error("This computer has no local network address, so devices can't reach it. Connect to a network and try again");
427
+ if (address === void 0) throw new CommandError("This computer has no local network address, so phones can't reach it. Connect to Wi-Fi and try again");
427
428
  const deviceServer = new LocalDeviceServer(onLog, onConnect);
428
429
  await deviceServer.listen(port, address, developerKey);
429
430
  return deviceServer;
@@ -585,8 +586,15 @@ function hmacWithSecret(secret, text) {
585
586
  const key = Buffer.from(secret, "base64url");
586
587
  return createHmac("sha256", key).update(text, "utf8").digest("base64url");
587
588
  }
588
- function localNetworkAddress() {
589
- for (const addresses of Object.values(networkInterfaces())) for (const candidate of addresses ?? []) if (candidate.family === "IPv4" && !candidate.internal) return candidate.address;
589
+ const UNREACHABLE_INTERFACE = /^(bridge|utun|tun|tap|ipsec|ppp|awdl|llw|vmnet|vboxnet|docker|br-|veth|virbr|zt|tailscale|wg)/i;
590
+ function localNetworkAddress(interfaces = networkInterfaces()) {
591
+ let fallback;
592
+ for (const [name, addresses] of Object.entries(interfaces)) for (const candidate of addresses ?? []) {
593
+ if (candidate.family !== "IPv4" || candidate.internal) continue;
594
+ if (!candidate.address.startsWith("169.254.") && !UNREACHABLE_INTERFACE.test(name)) return candidate.address;
595
+ fallback ??= candidate.address;
596
+ }
597
+ return fallback;
590
598
  }
591
599
  async function readBuild(dir) {
592
600
  const files = /* @__PURE__ */ new Map();
@@ -879,14 +887,15 @@ const USAGE = `Usage:
879
887
  page for each feature
880
888
  dotctl create page <path> Add a page to the dot you are in. Writes
881
889
  pages/<path>/ with view.dml, state.ts and controller.ts
882
- dotctl build [root] [options] Build the minified bundles the host app runs
890
+ dotctl build [root] [options] Build the dot for Dash: minified bundles in dist/, and
891
+ the ZIP that Dash downloads
883
892
  dotctl dev [root] [options] Run the dot in the browser simulator and rebuild on
884
893
  every change
885
894
  dotctl preview [root] [options] Build as \`build\` does, then run that build in the
886
- browser simulator, exactly as the host app gets it
895
+ browser simulator, exactly as Dash gets it
887
896
  dotctl keys show Show this computer's developer key: its public key
888
897
  and key ID. The key signs the links that
889
- \`dev --device\` shows, so Dash will open them
898
+ \`dev --device\` shows, so Dash opens them
890
899
  dotctl lsp [--stdio] Start the .dml language server for editors. It talks
891
900
  over stdin and stdout
892
901
 
@@ -895,9 +904,9 @@ Options:
895
904
  --conditions <list> Extra export conditions, separated by commas
896
905
  --port <port> Simulator port for \`dev\` and \`preview\`. If it is taken, the
897
906
  next free port is used (default: ${DEFAULT_PORT})
898
- --device With \`dev\`, also serve the dot to the Dot example apps on phones
899
- on your local network, through a link and QR code. The apps
900
- reload after each build
907
+ --device With \`dev\`, also serve the dot to phones on your local network,
908
+ through a link and QR code. Open it with Live Test in Dash, or
909
+ with a Dot example app. Phones reload after each build
901
910
  -h, --help Show this message`;
902
911
  async function main(argv) {
903
912
  const { values, positionals } = parseArgs({
@@ -939,6 +948,7 @@ async function main(argv) {
939
948
  case "dev":
940
949
  case "preview": break;
941
950
  default:
951
+ if (command !== void 0) console.error(`There is no "${command}" command. See the commands below.\n`);
942
952
  console.log(USAGE);
943
953
  return 1;
944
954
  }
@@ -958,7 +968,7 @@ async function main(argv) {
958
968
  return runBuild(options);
959
969
  }
960
970
  async function serveLanguageServer() {
961
- const { serveStdio } = await import("./server-DMnWDdJ6.js");
971
+ const { serveStdio } = await import("./server-BhnO9_Zu.js");
962
972
  serveStdio();
963
973
  return new Promise(() => {});
964
974
  }
@@ -974,7 +984,7 @@ async function runDev(options, port, device) {
974
984
  }
975
985
  async function runPreview(options, port, device) {
976
986
  if (device) {
977
- console.error("--device only works with dotctl dev");
987
+ console.error("--device only works with dotctl dev. Run dotctl dev --device instead");
978
988
  return 1;
979
989
  }
980
990
  const simulator = await preview({
@@ -1000,7 +1010,7 @@ function waitForCtrlC() {
1000
1010
  }
1001
1011
  async function showKeys(action) {
1002
1012
  if (action !== "show") {
1003
- console.error("Usage: dotctl keys show");
1013
+ console.error("Run dotctl keys show to see this computer's developer key");
1004
1014
  return 1;
1005
1015
  }
1006
1016
  const path = defaultDeveloperKeyPath();