@phreshos/cli 0.1.3 → 0.1.5
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 +42 -9
- package/dist/build-template.js +90 -0
- package/dist/cli.js +134 -202
- package/dist/create.js +139 -0
- package/dist/derive.js +4 -4
- package/dist/init.js +115 -137
- package/dist/pack.js +9 -8
- package/dist/program-intake.js +10 -2
- package/dist/project-dependency.js +115 -38
- package/dist/project.js +2 -3
- package/dist/prompts.js +105 -0
- package/dist/style.js +9 -14
- package/dist/template/README.md +28 -0
- package/dist/template/api-docs.md +38 -0
- package/dist/template/gitignore +30 -0
- package/dist/template/icon.png +0 -0
- package/dist/template/package.json +28 -0
- package/dist/template/phresh.config.ts +109 -0
- package/dist/template/source/build.ts +17 -0
- package/dist/template/source/client/app.tsx +36 -0
- package/dist/template/source/client/dec.d.ts +1 -0
- package/dist/template/source/client/index.html +13 -0
- package/dist/template/source/client/main.tsx +8 -0
- package/dist/template/source/client/style.css +81 -0
- package/dist/template/source/server/dec.d.ts +1 -0
- package/dist/template/source/server/main.ts +14 -0
- package/dist/template/tsconfig.json +24 -0
- package/dist/template/vite.client.ts +22 -0
- package/dist/template/vite.server.ts +27 -0
- package/dist/template.json +5 -0
- package/package.json +9 -4
- package/dist/relative-value.js +0 -118
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color: #20242a;
|
|
3
|
+
background: #f3f4f6;
|
|
4
|
+
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
5
|
+
font-synthesis: none;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
* { box-sizing: border-box; }
|
|
9
|
+
|
|
10
|
+
html, body, #root { min-height: 100vh; display: grid; }
|
|
11
|
+
|
|
12
|
+
body { margin: 0; }
|
|
13
|
+
|
|
14
|
+
button { font: inherit; }
|
|
15
|
+
|
|
16
|
+
#root {
|
|
17
|
+
min-height: 100vh;
|
|
18
|
+
display: grid;
|
|
19
|
+
place-items: center;
|
|
20
|
+
padding: 1.5rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.counter-card {
|
|
24
|
+
width: min(26rem, 100%);
|
|
25
|
+
display: grid;
|
|
26
|
+
justify-items: start;
|
|
27
|
+
gap: 1rem;
|
|
28
|
+
padding: 2rem;
|
|
29
|
+
border: 1px solid #d8dce2;
|
|
30
|
+
border-radius: 0.75rem;
|
|
31
|
+
background: #ffffff;
|
|
32
|
+
margin: auto;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.label {
|
|
36
|
+
color: #646b76;
|
|
37
|
+
font-size: 0.72rem;
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
letter-spacing: 0.1em;
|
|
40
|
+
text-transform: uppercase;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
h1 {
|
|
44
|
+
margin: 0;
|
|
45
|
+
font-size: 2rem;
|
|
46
|
+
line-height: 1.1;
|
|
47
|
+
letter-spacing: -0.04em;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
p {
|
|
51
|
+
margin: 0;
|
|
52
|
+
color: #5f6670;
|
|
53
|
+
font-size: 0.95rem;
|
|
54
|
+
line-height: 1.55;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.counter-card button {
|
|
58
|
+
min-width: 9rem;
|
|
59
|
+
min-height: 2.75rem;
|
|
60
|
+
padding: 0.65rem 1rem;
|
|
61
|
+
border: 0;
|
|
62
|
+
border-radius: 0.5rem;
|
|
63
|
+
color: #ffffff;
|
|
64
|
+
background: #2563eb;
|
|
65
|
+
cursor: pointer;
|
|
66
|
+
font-weight: 650;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.counter-card button:hover { background: #1d4ed8; }
|
|
70
|
+
|
|
71
|
+
.counter-card button:active { background: #1e40af; }
|
|
72
|
+
|
|
73
|
+
.counter-card button:focus-visible {
|
|
74
|
+
outline: 3px solid rgba(37, 99, 235, 0.25);
|
|
75
|
+
outline-offset: 2px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.loading {
|
|
79
|
+
color: #646b76;
|
|
80
|
+
font-size: 0.9rem;
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="@types/node" />
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { current } from "@phreshos/server"
|
|
2
|
+
|
|
3
|
+
// The Server owns the value. Every Client representation reads and changes
|
|
4
|
+
// this same state instead of keeping an independent browser counter.
|
|
5
|
+
let count = 0
|
|
6
|
+
|
|
7
|
+
current.answer("read", () => count)
|
|
8
|
+
|
|
9
|
+
current.subscribe("increment", async function () {
|
|
10
|
+
|
|
11
|
+
count += 1
|
|
12
|
+
|
|
13
|
+
current.publish("changed", count)
|
|
14
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"moduleResolution": "bundler",
|
|
4
|
+
"noUnusedParameters": true,
|
|
5
|
+
"noUnusedLocals": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"target": "ESNext",
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"paths": {
|
|
13
|
+
"@/*": [
|
|
14
|
+
"./*"
|
|
15
|
+
],
|
|
16
|
+
"@server/*": [
|
|
17
|
+
"./source/server/*"
|
|
18
|
+
],
|
|
19
|
+
"@client/*": [
|
|
20
|
+
"./source/client/*"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import react from "@vitejs/plugin-react"
|
|
2
|
+
import { defineConfig } from "vite"
|
|
3
|
+
import { resolve } from "node:path"
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
root: "source/client",
|
|
7
|
+
plugins: [react()],
|
|
8
|
+
base: "./",
|
|
9
|
+
resolve: {
|
|
10
|
+
tsconfigPaths: true,
|
|
11
|
+
dedupe: ["react"]
|
|
12
|
+
},
|
|
13
|
+
server: {
|
|
14
|
+
cors: true,
|
|
15
|
+
port: 5200,
|
|
16
|
+
strictPort: true
|
|
17
|
+
},
|
|
18
|
+
build: {
|
|
19
|
+
emptyOutDir: true,
|
|
20
|
+
outDir: resolve(import.meta.dirname, "dist/client")
|
|
21
|
+
}
|
|
22
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import packageConfig from "./package.json" with { type: "json" }
|
|
2
|
+
import { defineConfig } from "vite"
|
|
3
|
+
import { resolve } from "node:path"
|
|
4
|
+
|
|
5
|
+
export const externalDependencies: (keyof typeof packageConfig.dependencies)[] = [
|
|
6
|
+
|
|
7
|
+
// Add packages here that should NOT be bundled during server, Example: "sqlite3"
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
root: "source/server",
|
|
12
|
+
resolve: {
|
|
13
|
+
tsconfigPaths: true
|
|
14
|
+
},
|
|
15
|
+
ssr: {
|
|
16
|
+
noExternal: true,
|
|
17
|
+
external: externalDependencies
|
|
18
|
+
},
|
|
19
|
+
build: {
|
|
20
|
+
ssr: true,
|
|
21
|
+
emptyOutDir: true,
|
|
22
|
+
outDir: resolve(import.meta.dirname, "dist/server"),
|
|
23
|
+
rolldownOptions: {
|
|
24
|
+
input: "main.ts"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
})
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"description": "The Phresh command-line interface for Program projects and system management.",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
7
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
8
|
+
"compile": "tsc --noEmit false --outDir dist --rootDir source --rewriteRelativeImportExtensions true --allowImportingTsExtensions true",
|
|
9
|
+
"build": "node --run clean && node --run compile && node dist/build-template.js",
|
|
8
10
|
"prepack": "node --run build"
|
|
9
11
|
},
|
|
10
12
|
"bin": {
|
|
@@ -15,8 +17,11 @@
|
|
|
15
17
|
"README.md"
|
|
16
18
|
],
|
|
17
19
|
"dependencies": {
|
|
18
|
-
"@
|
|
19
|
-
"
|
|
20
|
+
"@clack/prompts": "^1.7.0",
|
|
21
|
+
"@phreshos/core": "^0.1.1",
|
|
22
|
+
"adm-zip": "^0.6.0",
|
|
23
|
+
"commander": "^15.0.0",
|
|
24
|
+
"picocolors": "^1.1.1"
|
|
20
25
|
},
|
|
21
26
|
"devDependencies": {
|
|
22
27
|
"@types/adm-zip": "^0.5.8",
|
package/dist/relative-value.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reduces a strict linear expression into `span * relative + pixels`.
|
|
3
|
-
*
|
|
4
|
-
* Numbers are absolute values. Percentages and `n/d` fractions are relative
|
|
5
|
-
* values. Addition and subtraction combine terms; multiplication and division
|
|
6
|
-
* scale the preceding term by a number. No arbitrary code or CSS is accepted.
|
|
7
|
-
*/
|
|
8
|
-
export function parseRelativeValue(input) {
|
|
9
|
-
if (typeof input === "number")
|
|
10
|
-
return Number.isFinite(input) ? { relative: 0, pixels: clean(input) } : null;
|
|
11
|
-
if (typeof input !== "string" || input.trim().length === 0)
|
|
12
|
-
return null;
|
|
13
|
-
return new Reader(input).parse();
|
|
14
|
-
}
|
|
15
|
-
/** Returns whether a value belongs to the linear relative-value grammar. */
|
|
16
|
-
export function isRelativeValue(value) {
|
|
17
|
-
return parseRelativeValue(value) !== null;
|
|
18
|
-
}
|
|
19
|
-
class Reader {
|
|
20
|
-
position = 0;
|
|
21
|
-
source;
|
|
22
|
-
constructor(source) {
|
|
23
|
-
this.source = source;
|
|
24
|
-
}
|
|
25
|
-
parse() {
|
|
26
|
-
const value = { relative: 0, pixels: 0 };
|
|
27
|
-
let direction = this.sign();
|
|
28
|
-
while (this.position < this.source.length) {
|
|
29
|
-
const term = this.term();
|
|
30
|
-
if (!term)
|
|
31
|
-
return null;
|
|
32
|
-
value.relative += term.relative * direction;
|
|
33
|
-
value.pixels += term.pixels * direction;
|
|
34
|
-
if (!finite(value))
|
|
35
|
-
return null;
|
|
36
|
-
this.space();
|
|
37
|
-
if (this.position === this.source.length)
|
|
38
|
-
return { relative: clean(value.relative), pixels: clean(value.pixels) };
|
|
39
|
-
const operator = this.source[this.position];
|
|
40
|
-
if (operator !== "+" && operator !== "-")
|
|
41
|
-
return null;
|
|
42
|
-
this.position += 1;
|
|
43
|
-
direction = (operator === "+" ? 1 : -1) * this.sign();
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
term() {
|
|
48
|
-
const value = this.measurement();
|
|
49
|
-
if (!value)
|
|
50
|
-
return null;
|
|
51
|
-
while (true) {
|
|
52
|
-
this.space();
|
|
53
|
-
const operator = this.source[this.position];
|
|
54
|
-
if (operator !== "*" && operator !== "/")
|
|
55
|
-
return value;
|
|
56
|
-
this.position += 1;
|
|
57
|
-
const scalar = this.scalar();
|
|
58
|
-
if (scalar === null || operator === "/" && scalar === 0)
|
|
59
|
-
return null;
|
|
60
|
-
const factor = operator === "*" ? scalar : 1 / scalar;
|
|
61
|
-
value.relative *= factor;
|
|
62
|
-
value.pixels *= factor;
|
|
63
|
-
if (!finite(value))
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
measurement() {
|
|
68
|
-
this.space();
|
|
69
|
-
const remainder = this.source.slice(this.position);
|
|
70
|
-
const fraction = remainder.match(/^(\d+(?:\.\d+)?|\.\d+)\s*\/\s*(\d+(?:\.\d+)?|\.\d+)(?![\d.])/);
|
|
71
|
-
if (fraction) {
|
|
72
|
-
const denominator = Number(fraction[2]);
|
|
73
|
-
if (!denominator)
|
|
74
|
-
return null;
|
|
75
|
-
this.position += fraction[0].length;
|
|
76
|
-
return { relative: Number(fraction[1]) / denominator, pixels: 0 };
|
|
77
|
-
}
|
|
78
|
-
const percentage = remainder.match(/^(\d+(?:\.\d+)?|\.\d+)\s*%/);
|
|
79
|
-
if (percentage) {
|
|
80
|
-
this.position += percentage[0].length;
|
|
81
|
-
return { relative: Number(percentage[1]) / 100, pixels: 0 };
|
|
82
|
-
}
|
|
83
|
-
const number = this.number();
|
|
84
|
-
return number === null ? null : { relative: 0, pixels: number };
|
|
85
|
-
}
|
|
86
|
-
scalar() {
|
|
87
|
-
const direction = this.sign();
|
|
88
|
-
const value = this.number();
|
|
89
|
-
return value === null ? null : value * direction;
|
|
90
|
-
}
|
|
91
|
-
number() {
|
|
92
|
-
this.space();
|
|
93
|
-
const number = this.source.slice(this.position).match(/^(\d+(?:\.\d+)?|\.\d+)/)?.[0];
|
|
94
|
-
if (!number)
|
|
95
|
-
return null;
|
|
96
|
-
this.position += number.length;
|
|
97
|
-
return Number(number);
|
|
98
|
-
}
|
|
99
|
-
sign() {
|
|
100
|
-
this.space();
|
|
101
|
-
const sign = this.source[this.position];
|
|
102
|
-
if (sign !== "+" && sign !== "-")
|
|
103
|
-
return 1;
|
|
104
|
-
this.position += 1;
|
|
105
|
-
this.space();
|
|
106
|
-
return sign === "-" ? -1 : 1;
|
|
107
|
-
}
|
|
108
|
-
space() {
|
|
109
|
-
while (/\s/.test(this.source[this.position] ?? ""))
|
|
110
|
-
this.position += 1;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function finite(value) {
|
|
114
|
-
return Number.isFinite(value.relative) && Number.isFinite(value.pixels);
|
|
115
|
-
}
|
|
116
|
-
function clean(value) {
|
|
117
|
-
return Object.is(value, -0) ? 0 : value;
|
|
118
|
-
}
|