@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.
- package/README.md +22 -9
- package/dist/cli.js +24 -14
- package/dist/cli.js.map +1 -1
- package/dist/{server-DMnWDdJ6.js → server-BhnO9_Zu.js} +56 -7
- package/dist/server-BhnO9_Zu.js.map +1 -0
- package/dist/templates/showcase/.env +2 -2
- package/dist/templates/showcase/dot.ts +22 -2
- package/dist/templates/showcase/pages/basics/bars/controller.ts +2 -2
- package/dist/templates/showcase/pages/basics/bars/view.dml +2 -1
- package/dist/templates/showcase/pages/basics/bindings/state.ts +2 -2
- package/dist/templates/showcase/pages/basics/bindings/view.dml +2 -2
- package/dist/templates/showcase/pages/basics/colors/controller.ts +1 -1
- package/dist/templates/showcase/pages/basics/concert/view.dml +1 -1
- package/dist/templates/showcase/pages/basics/control-flow/controller.ts +1 -1
- package/dist/templates/showcase/pages/basics/control-flow/view.dml +1 -1
- package/dist/templates/showcase/pages/basics/events/controller.ts +1 -1
- package/dist/templates/showcase/pages/basics/events/view.dml +1 -1
- package/dist/templates/showcase/pages/basics/hooks/controller.ts +2 -1
- package/dist/templates/showcase/pages/basics/hooks/view.dml +2 -2
- package/dist/templates/showcase/pages/basics/navigation/controller.ts +1 -0
- package/dist/templates/showcase/pages/basics/navigation/view.dml +1 -1
- package/dist/templates/showcase/pages/basics/pick-genre/controller.ts +3 -3
- package/dist/templates/showcase/pages/basics/share/view.dml +2 -2
- package/dist/templates/showcase/pages/basics/state/controller.ts +9 -0
- package/dist/templates/showcase/pages/basics/state/state.ts +3 -0
- package/dist/templates/showcase/pages/basics/theme/controller.ts +28 -0
- package/dist/templates/showcase/pages/basics/theme/state.ts +4 -0
- package/dist/templates/showcase/pages/basics/theme/view.dml +50 -0
- package/dist/templates/showcase/pages/components/capture/controller.ts +25 -0
- package/dist/templates/showcase/pages/components/capture/state.ts +7 -0
- package/dist/templates/showcase/pages/components/capture/view.dml +32 -0
- package/dist/templates/showcase/pages/components/carousel/view.dml +2 -2
- package/dist/templates/showcase/pages/components/feedback/controller.ts +2 -1
- package/dist/templates/showcase/pages/components/feedback/state.ts +2 -2
- package/dist/templates/showcase/pages/components/feedback/view.dml +2 -2
- package/dist/templates/showcase/pages/components/forms/controller.ts +2 -2
- package/dist/templates/showcase/pages/components/forms/state.ts +1 -1
- package/dist/templates/showcase/pages/components/forms/view.dml +6 -5
- package/dist/templates/showcase/pages/components/icons/controller.ts +1 -0
- package/dist/templates/showcase/pages/components/icons/state.ts +1 -1
- package/dist/templates/showcase/pages/components/images/controller.ts +1 -1
- package/dist/templates/showcase/pages/components/images/state.ts +1 -1
- package/dist/templates/showcase/pages/components/images/view.dml +4 -4
- package/dist/templates/showcase/pages/components/layout/controller.ts +5 -1
- package/dist/templates/showcase/pages/components/layout/state.ts +2 -0
- package/dist/templates/showcase/pages/components/layout/view.dml +44 -6
- package/dist/templates/showcase/pages/components/lists/view.dml +12 -7
- package/dist/templates/showcase/pages/components/money/controller.ts +1 -1
- package/dist/templates/showcase/pages/components/money/view.dml +2 -2
- package/dist/templates/showcase/pages/components/pinned/controller.ts +10 -0
- package/dist/templates/showcase/pages/components/pinned/state.ts +25 -0
- package/dist/templates/showcase/pages/components/pinned/view.dml +42 -0
- package/dist/templates/showcase/pages/components/reading/state.ts +2 -2
- package/dist/templates/showcase/pages/components/sheets/controller.ts +1 -1
- package/dist/templates/showcase/pages/components/sheets/view.dml +1 -1
- package/dist/templates/showcase/pages/components/styles/view.dml +39 -4
- package/dist/templates/showcase/pages/components/tabs/state.ts +2 -2
- package/dist/templates/showcase/pages/components/tabs/view.dml +6 -5
- package/dist/templates/showcase/pages/components/text/view.dml +4 -4
- package/dist/templates/showcase/pages/dash/account/controller.ts +3 -0
- package/dist/templates/showcase/pages/dash/account/view.dml +2 -2
- package/dist/templates/showcase/pages/dash/cache/controller.ts +45 -16
- package/dist/templates/showcase/pages/dash/cache/state.ts +1 -0
- package/dist/templates/showcase/pages/dash/cache/view.dml +4 -0
- package/dist/templates/showcase/pages/dash/calls/controller.ts +3 -2
- package/dist/templates/showcase/pages/dash/contacts/controller.ts +1 -0
- package/dist/templates/showcase/pages/dash/crypto/controller.ts +2 -0
- package/dist/templates/showcase/pages/dash/crypto/view.dml +1 -1
- package/dist/templates/showcase/pages/dash/files/controller.ts +67 -32
- package/dist/templates/showcase/pages/dash/files/state.ts +1 -0
- package/dist/templates/showcase/pages/dash/files/view.dml +5 -1
- package/dist/templates/showcase/pages/dash/media/controller.ts +7 -1
- package/dist/templates/showcase/pages/dash/media/state.ts +2 -0
- package/dist/templates/showcase/pages/dash/network/controller.ts +5 -1
- package/dist/templates/showcase/pages/dash/network/view.dml +1 -1
- package/dist/templates/showcase/pages/dash/payments/cases.ts +40 -22
- package/dist/templates/showcase/pages/dash/payments/controller.ts +27 -3
- package/dist/templates/showcase/pages/dash/payments/state.ts +2 -0
- package/dist/templates/showcase/pages/dash/payments/view.dml +3 -1
- package/dist/templates/showcase/pages/dash/reminders/controller.ts +73 -0
- package/dist/templates/showcase/pages/dash/reminders/state.ts +6 -0
- package/dist/templates/showcase/pages/dash/reminders/view.dml +34 -0
- package/dist/templates/showcase/pages/dash/secrets/controller.ts +37 -14
- package/dist/templates/showcase/pages/dash/secrets/state.ts +1 -0
- package/dist/templates/showcase/pages/dash/secrets/view.dml +4 -0
- package/dist/templates/showcase/pages/dash/system/controller.ts +5 -0
- package/dist/templates/showcase/pages/dash/system/view.dml +4 -4
- package/dist/templates/showcase/pages/dash/ui/controller.ts +6 -1
- package/dist/templates/showcase/pages/index/controller.ts +1 -0
- package/dist/templates/showcase/pages/index/state.ts +30 -6
- package/dist/templates/showcase/statics/icons/ticket-stub.svg +1 -0
- package/dist/templates/starter/.env +2 -2
- package/dist/templates/starter/dot.ts +1 -0
- package/dist/templates/starter/pages/index/controller.ts +2 -0
- package/dist/templates/starter/pages/index/state.ts +2 -0
- package/dist/templates/starter/pages/index/view.dml +2 -1
- package/package.json +6 -6
- 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
|
|
4
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
56
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
589
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
899
|
-
|
|
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-
|
|
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("
|
|
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();
|