@weft-js/cli 0.1.1 → 0.1.2
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 +38 -14
- package/bin/weft.mjs +8 -1
- package/docs/async.md +16 -6
- package/docs/browser.md +22 -8
- package/docs/config.md +39 -9
- package/docs/core.md +30 -0
- package/docs/deploy.md +33 -8
- package/docs/design.md +12 -3
- package/docs/entrypoints.md +79 -0
- package/docs/fonts.md +12 -2
- package/docs/icons.md +13 -7
- package/docs/lists.md +3 -1
- package/docs/meta.md +13 -3
- package/docs/plugins.md +32 -9
- package/docs/props.md +13 -2
- package/docs/reactivity.md +26 -0
- package/docs/rules.md +19 -12
- package/docs/rust.md +47 -17
- package/docs/start-short.md +3 -2
- package/docs/start.md +226 -52
- package/docs/state.md +33 -7
- package/docs/style.md +31 -8
- package/docs/surface.md +61 -15
- package/docs/testing.md +15 -5
- package/docs/theme.md +182 -0
- package/docs/ui-state.md +19 -6
- package/docs/verify.md +13 -0
- package/package.json +13 -4
- package/src/add/config.mjs +93 -0
- package/src/add/errors.mjs +2 -0
- package/src/add/setup.mjs +88 -0
- package/src/add-rust.mjs +82 -27
- package/src/add.mjs +209 -181
- package/src/agents-md.mjs +144 -43
- package/src/alias.mjs +16 -5
- package/src/audit/page.mjs +313 -0
- package/src/audit/report.mjs +69 -0
- package/src/audit/utils.mjs +5 -0
- package/src/audit.mjs +159 -206
- package/src/browser/cli.mjs +24 -5
- package/src/browser/client.mjs +189 -25
- package/src/browser/commands.mjs +166 -51
- package/src/catalog/audit.mjs +129 -0
- package/src/catalog/auth.mjs +40 -0
- package/src/catalog/compiler.mjs +337 -0
- package/src/catalog/contracts.mjs +18 -0
- package/src/catalog/database.mjs +52 -0
- package/src/catalog/deploy.mjs +117 -0
- package/src/catalog/design.mjs +159 -0
- package/src/catalog/forms.mjs +25 -0
- package/src/catalog/hydration.mjs +29 -0
- package/src/catalog/icons.mjs +24 -0
- package/src/catalog/media.mjs +163 -0
- package/src/catalog/metadata.mjs +116 -0
- package/src/catalog/plugins.mjs +228 -0
- package/src/catalog/realtime.mjs +195 -0
- package/src/catalog/rust.mjs +75 -0
- package/src/catalog/server-functions.mjs +92 -0
- package/src/catalog/state.mjs +39 -0
- package/src/catalog/style-groups.mjs +54 -0
- package/src/catalog/tests.mjs +127 -0
- package/src/catalog/text.mjs +200 -0
- package/src/catalog/ui-state.mjs +42 -0
- package/src/catalog.mjs +67 -460
- package/src/check/runtime.mjs +280 -0
- package/src/check.mjs +198 -208
- package/src/cli/authoring.mjs +213 -0
- package/src/cli/project.mjs +302 -0
- package/src/cli.mjs +222 -250
- package/src/config.mjs +1 -1
- package/src/contributions.mjs +75 -25
- package/src/db-layer.mjs +13 -5
- package/src/deploy/cdn.mjs +94 -16
- package/src/deploy/files.mjs +100 -21
- package/src/deploy/fit.mjs +127 -23
- package/src/deploy/hosts.mjs +90 -20
- package/src/deploy/index/cli.mjs +20 -0
- package/src/deploy/index/environment.mjs +69 -0
- package/src/deploy/index/steps.mjs +87 -0
- package/src/deploy/index.mjs +228 -114
- package/src/deploy/needs.mjs +88 -31
- package/src/design-checks/accessible-names.mjs +62 -0
- package/src/design-checks/contrast.mjs +43 -0
- package/src/design-checks/csp.mjs +60 -0
- package/src/design-checks/files.mjs +59 -0
- package/src/design-checks/heading-links.mjs +61 -0
- package/src/design-checks/interaction.mjs +65 -0
- package/src/design-checks/jsx.mjs +67 -0
- package/src/design-checks/layout-values.mjs +68 -0
- package/src/design-checks/native-controls.mjs +48 -0
- package/src/design-checks/outline.mjs +39 -0
- package/src/design-checks/reporter.mjs +37 -0
- package/src/design-checks/rules.mjs +274 -0
- package/src/design-checks/values.mjs +262 -0
- package/src/design-checks.mjs +10 -400
- package/src/diag.mjs +32 -8
- package/src/docs.mjs +138 -43
- package/src/doctor.mjs +20 -8
- package/src/files.mjs +18 -5
- package/src/fix.mjs +10 -2
- package/src/gate/after.mjs +40 -0
- package/src/gate/before.mjs +54 -0
- package/src/gate/classify.mjs +72 -0
- package/src/gate/mutation.mjs +209 -0
- package/src/gate/resolve-cases.mjs +22 -0
- package/src/gate/result.mjs +63 -0
- package/src/gate/run.mjs +75 -0
- package/src/gate.mjs +104 -202
- package/src/infer/box-props.cjs +140 -0
- package/src/infer/core-boxes.cjs +46 -0
- package/src/infer/derived-writes.cjs +95 -0
- package/src/infer/engine/checks.cjs +193 -0
- package/src/infer/engine/flow.cjs +293 -0
- package/src/infer/engine/report.cjs +158 -0
- package/src/infer/engine/utils.cjs +15 -0
- package/src/infer/engine.cjs +108 -368
- package/src/infer/facts/sites.cjs +114 -0
- package/src/infer/facts.cjs +210 -117
- package/src/infer/hosts.cjs +69 -22
- package/src/infer/lsp.mjs +149 -40
- package/src/infer/session.cjs +73 -17
- package/src/infer/shadow.cjs +13 -5
- package/src/infer/worker.cjs +57 -9
- package/src/jsx-scan.mjs +63 -21
- package/src/load-config/schema.mjs +281 -0
- package/src/load-config.mjs +137 -138
- package/src/map.mjs +93 -26
- package/src/mcp/browser-tools.mjs +155 -0
- package/src/mcp.mjs +147 -69
- package/src/meta-table.mjs +43 -8
- package/src/mutate.mjs +120 -36
- package/src/plugin-checks.mjs +52 -23
- package/src/plugins.mjs +125 -39
- package/src/project.mjs +170 -79
- package/src/props-checks.mjs +24 -6
- package/src/props-listener.mjs +27 -9
- package/src/react-checks.mjs +35 -4
- package/src/server-state-checks.mjs +34 -0
- package/src/share-checks.mjs +121 -37
- package/src/site.mjs +33 -6
- package/src/slots.mjs +104 -19
- package/src/start/build.mjs +116 -0
- package/src/start/routes.mjs +38 -0
- package/src/start.mjs +193 -95
- package/src/state-checks/core-state.mjs +223 -0
- package/src/state-checks/modules.mjs +17 -0
- package/src/state-checks/scan.mjs +232 -0
- package/src/state-checks/server-graph.mjs +65 -0
- package/src/state-checks.mjs +109 -133
- package/src/style/find.mjs +121 -0
- package/src/style.mjs +133 -127
- package/src/surface-checks.mjs +212 -46
- package/src/tailwind.mjs +5 -4
- package/src/tasks.mjs +189 -27
- package/src/test-rules/context.mjs +109 -0
- package/src/test-rules/file-rules.mjs +279 -0
- package/src/test-rules/rule-helpers.mjs +244 -0
- package/src/test-rules/syntax.mjs +223 -0
- package/src/test-rules/test-rules.mjs +127 -0
- package/src/testdiff.mjs +94 -32
- package/src/tests.mjs +31 -483
- package/src/text-checks.mjs +229 -69
- package/src/tokens.mjs +12 -4
- package/src/trust/scan.mjs +95 -0
- package/src/trust.mjs +214 -102
- package/src/weft.mjs +41 -9
- package/src/workspace.mjs +96 -19
- package/ts-plugin/context.js +57 -0
- package/ts-plugin/index.js +4 -124
- package/ts-plugin/mapping.js +65 -0
- package/ts-plugin/proxy.js +144 -0
package/src/add-rust.mjs
CHANGED
|
@@ -6,28 +6,39 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
|
6
6
|
import { dirname, join, relative } from 'node:path'
|
|
7
7
|
import { start } from './start.mjs'
|
|
8
8
|
|
|
9
|
-
const refused = message => Object.assign(new Error(message), { code: 'E_ADD' })
|
|
10
|
-
const usage = message => Object.assign(new Error(message), { code: 'E_USAGE' })
|
|
9
|
+
const refused = (message) => Object.assign(new Error(message), { code: 'E_ADD' })
|
|
10
|
+
const usage = (message) => Object.assign(new Error(message), { code: 'E_USAGE' })
|
|
11
11
|
const TOOLCHAIN = '1.99.1'
|
|
12
12
|
|
|
13
|
-
const camel = name => name.replace(/[-_](.)/g, (_, c) => c.toUpperCase())
|
|
14
|
-
const pascal = name => {
|
|
15
|
-
const
|
|
13
|
+
const camel = (name) => name.replace(/[-_](.)/g, (_, c) => c.toUpperCase())
|
|
14
|
+
const pascal = (name) => {
|
|
15
|
+
const c = camel(name)
|
|
16
|
+
return c[0].toUpperCase() + c.slice(1)
|
|
17
|
+
}
|
|
18
|
+
const lib = (name) => name.replaceAll('-', '_')
|
|
16
19
|
|
|
17
20
|
const manifest = (name, crate, remote) => `[package]
|
|
18
21
|
name = "${name}"
|
|
19
22
|
version = "0.0.0"
|
|
20
23
|
edition = "2024"
|
|
21
24
|
publish = false
|
|
22
|
-
${
|
|
25
|
+
${
|
|
26
|
+
remote
|
|
27
|
+
? ''
|
|
28
|
+
: `
|
|
23
29
|
[lib]
|
|
24
30
|
crate-type = ["cdylib"]
|
|
25
|
-
`
|
|
31
|
+
`
|
|
32
|
+
}
|
|
26
33
|
[dependencies]
|
|
27
34
|
serde = { version = "1", features = ["derive"] }
|
|
28
35
|
serde_json = "1"
|
|
29
|
-
${
|
|
30
|
-
|
|
36
|
+
${
|
|
37
|
+
remote
|
|
38
|
+
? `tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
|
39
|
+
weft = { path = "${crate}" }`
|
|
40
|
+
: `weft = { path = "${crate}", default-features = false, features = ["native"] }`
|
|
41
|
+
}
|
|
31
42
|
|
|
32
43
|
[build-dependencies]
|
|
33
44
|
weft = { path = "${crate}", default-features = false, features = ["build"] }
|
|
@@ -43,7 +54,10 @@ codegen-units = 1
|
|
|
43
54
|
[workspace]
|
|
44
55
|
`
|
|
45
56
|
|
|
46
|
-
const body = (
|
|
57
|
+
const body = (
|
|
58
|
+
name,
|
|
59
|
+
remote,
|
|
60
|
+
) => `weft::contract!(); // types and a \`Service\` trait, generated from your Zod: never hand-written
|
|
47
61
|
use contract::*;
|
|
48
62
|
|
|
49
63
|
struct ${pascal(name)};
|
|
@@ -54,14 +68,18 @@ impl Service for ${pascal(name)} {
|
|
|
54
68
|
Ok(DigestOutput { bytes: input.text.len() as i64, hash: format!("{hash:08x}") })
|
|
55
69
|
}
|
|
56
70
|
}
|
|
57
|
-
${
|
|
71
|
+
${
|
|
72
|
+
remote
|
|
73
|
+
? `
|
|
58
74
|
#[tokio::main]
|
|
59
75
|
async fn main() -> std::io::Result<()> {
|
|
60
76
|
weft::serve(weft::router(contract::functions(${pascal(name)}))).await
|
|
61
77
|
}
|
|
62
|
-
`
|
|
78
|
+
`
|
|
79
|
+
: `
|
|
63
80
|
weft::native!(contract::functions(${pascal(name)}));
|
|
64
|
-
`
|
|
81
|
+
`
|
|
82
|
+
}`
|
|
65
83
|
|
|
66
84
|
const fn = (name, binding) => `import { query } from '@weft-js/start/data'
|
|
67
85
|
import { z } from 'zod'
|
|
@@ -78,33 +96,63 @@ export const digest = query({
|
|
|
78
96
|
/** The path Cargo gets. `crate/` is in a packed @weft-js/start; a linked one is in this repository, next to the crates. */
|
|
79
97
|
async function weftCrate(root, dir) {
|
|
80
98
|
const { startDir } = await start(root, 'vite')
|
|
81
|
-
const found = [
|
|
99
|
+
const found = [
|
|
100
|
+
join(startDir, '..', 'crate'),
|
|
101
|
+
join(startDir, '..', '..', '..', 'crates', 'weft'),
|
|
102
|
+
].find((d) => existsSync(join(d, 'Cargo.toml')))
|
|
82
103
|
if (!found) throw refused('this @weft-js/start has no `weft` crate in it. Nothing was changed.')
|
|
83
104
|
return relative(dir, found).replaceAll('\\', '/')
|
|
84
105
|
}
|
|
85
106
|
|
|
86
|
-
export async function addRust(
|
|
87
|
-
|
|
88
|
-
|
|
107
|
+
export async function addRust(
|
|
108
|
+
root,
|
|
109
|
+
name = 'media',
|
|
110
|
+
{ remote = false, dryRun = false, install, installSpecs },
|
|
111
|
+
) {
|
|
112
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(name))
|
|
113
|
+
throw usage(
|
|
114
|
+
`\`${name}\` isn't a service name: lower case, then letters, digits, \`-\` or \`_\``,
|
|
115
|
+
)
|
|
116
|
+
if (!existsSync(join(root, 'package.json')))
|
|
117
|
+
throw refused('`weft add rust` needs a package.json. Nothing was changed.')
|
|
89
118
|
const dir = join(root, 'crates', name)
|
|
90
119
|
const module = join(root, 'src', 'server', `${name}.ts`)
|
|
91
|
-
const taken = [dir, module].filter(existsSync).map(f => relative(root, f))
|
|
92
|
-
if (taken.length)
|
|
120
|
+
const taken = [dir, module].filter(existsSync).map((f) => relative(root, f))
|
|
121
|
+
if (taken.length)
|
|
122
|
+
throw refused(
|
|
123
|
+
`${taken.join(', ')} already exist${taken.length > 1 ? '' : 's'}. Pick another name: \`weft add rust <name>\`. Nothing was changed.`,
|
|
124
|
+
)
|
|
93
125
|
const binding = camel(name)
|
|
94
126
|
const factory = remote ? 'remote' : 'native'
|
|
95
127
|
const call = remote ? `remote('rust://${name}')` : `native('${name}')`
|
|
96
128
|
const rustFile = join(root, 'src', 'server', 'rust.ts')
|
|
97
|
-
const had = existsSync(rustFile)
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
const had = existsSync(rustFile)
|
|
130
|
+
? readFileSync(rustFile, 'utf8')
|
|
131
|
+
: '// The only place Rust targets are named.\n'
|
|
132
|
+
if (new RegExp(`\\b${binding}\\b`).test(had))
|
|
133
|
+
throw refused(`src/server/rust.ts already names \`${binding}\`. Nothing was changed.`)
|
|
134
|
+
const imported = new RegExp(
|
|
135
|
+
`import\\s*\\{[^}]*\\b${factory}\\b[^}]*\\}\\s*from\\s*['"]@weft-js/start/rust['"]`,
|
|
136
|
+
).test(had)
|
|
100
137
|
const nextRust = `${imported ? had : had.replace(/^((?:\/\/.*\n)*)/, `$1import { ${factory} } from '@weft-js/start/rust'\n`)}${had.endsWith('\n') ? '' : '\n'}\nexport const ${binding} = ${call}\n`
|
|
101
138
|
|
|
102
139
|
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
|
|
103
140
|
const needsZod = !pkg.dependencies?.zod && !pkg.devDependencies?.zod
|
|
104
141
|
const gitignore = join(root, '.gitignore')
|
|
105
|
-
const ignored =
|
|
106
|
-
|
|
107
|
-
|
|
142
|
+
const ignored =
|
|
143
|
+
existsSync(gitignore) &&
|
|
144
|
+
/^\/?target\/?$|^\*\*\/target\/?$/m.test(readFileSync(gitignore, 'utf8'))
|
|
145
|
+
const actions = [
|
|
146
|
+
`create crates/${name}`,
|
|
147
|
+
`create src/server/${name}.ts`,
|
|
148
|
+
`add \`${binding}\` to src/server/rust.ts`,
|
|
149
|
+
...(needsZod && install ? ['install zod'] : []),
|
|
150
|
+
...(ignored ? [] : ['ignore target/']),
|
|
151
|
+
'this crate needs Rust (`cargo`, from rustup.rs); the rest of weft does not',
|
|
152
|
+
'next: `weft check`, then `weft dev`',
|
|
153
|
+
]
|
|
154
|
+
if (dryRun)
|
|
155
|
+
return { ok: true, feature: 'rust', service: name, kind: factory, actions, dryRun: true }
|
|
108
156
|
|
|
109
157
|
const crate = await weftCrate(root, dir)
|
|
110
158
|
const write = (file, text) => {
|
|
@@ -113,11 +161,18 @@ export async function addRust(root, name = 'media', { remote = false, dryRun = f
|
|
|
113
161
|
}
|
|
114
162
|
write(join(dir, 'Cargo.toml'), manifest(name, crate, remote))
|
|
115
163
|
write(join(dir, 'build.rs'), `fn main() {\n weft::build::generate("${name}");\n}\n`)
|
|
116
|
-
write(
|
|
164
|
+
write(
|
|
165
|
+
join(dir, 'rust-toolchain.toml'),
|
|
166
|
+
`[toolchain]\nchannel = "${TOOLCHAIN}"\n${remote ? '' : 'targets = ["wasm32-unknown-unknown"]\n'}`,
|
|
167
|
+
)
|
|
117
168
|
write(join(dir, 'src', remote ? 'main.rs' : 'lib.rs'), body(lib(name), remote))
|
|
118
169
|
write(module, fn(name, binding))
|
|
119
170
|
write(rustFile, nextRust)
|
|
120
|
-
if (!ignored)
|
|
171
|
+
if (!ignored)
|
|
172
|
+
writeFileSync(
|
|
173
|
+
gitignore,
|
|
174
|
+
`${existsSync(gitignore) ? readFileSync(gitignore, 'utf8').replace(/\n?$/, '\n') : ''}target/\n`,
|
|
175
|
+
)
|
|
121
176
|
if (needsZod && install) installSpecs(['zod'])
|
|
122
177
|
return { ok: true, feature: 'rust', service: name, kind: factory, actions }
|
|
123
178
|
}
|