@browsersync/bslive 0.0.13 → 0.0.15
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/package.json +22 -17
- package/Cargo.toml +0 -34
- package/bslive/Cargo.toml +0 -35
- package/bslive/build.rs +0 -5
- package/bslive/src/lib.rs +0 -135
- package/bsnext/Cargo.toml +0 -21
- package/bsnext/src/main.rs +0 -116
- package/crates/bsnext_client/Cargo.toml +0 -8
- package/crates/bsnext_client/build.rs +0 -53
- package/crates/bsnext_client/generated/dto.ts +0 -147
- package/crates/bsnext_client/generated/schema.ts +0 -237
- package/crates/bsnext_client/inject/dist/index.js +0 -6540
- package/crates/bsnext_client/inject/package.json +0 -12
- package/crates/bsnext_client/inject/src/console.ts +0 -25
- package/crates/bsnext_client/inject/src/index.ts +0 -73
- package/crates/bsnext_client/package-lock.json +0 -2145
- package/crates/bsnext_client/package.json +0 -27
- package/crates/bsnext_client/src/lib.rs +0 -11
- package/crates/bsnext_client/tsconfig.json +0 -22
- package/crates/bsnext_client/ui/dist/index.css +0 -78
- package/crates/bsnext_client/ui/dist/index.js +0 -997
- package/crates/bsnext_client/ui/index.html +0 -18
- package/crates/bsnext_client/ui/input.yml +0 -19
- package/crates/bsnext_client/ui/package.json +0 -18
- package/crates/bsnext_client/ui/src/components/bs-debug.ts +0 -27
- package/crates/bsnext_client/ui/src/components/bs-header.ts +0 -33
- package/crates/bsnext_client/ui/src/components/bs-icon.ts +0 -101
- package/crates/bsnext_client/ui/src/components/bs-server-detail.ts +0 -21
- package/crates/bsnext_client/ui/src/components/bs-server-identity.ts +0 -24
- package/crates/bsnext_client/ui/src/components/bs-server-list.ts +0 -39
- package/crates/bsnext_client/ui/src/index.ts +0 -39
- package/crates/bsnext_client/ui/styles/base.css.ts +0 -17
- package/crates/bsnext_client/ui/styles/reset.css +0 -52
- package/crates/bsnext_client/ui/styles/style.css +0 -29
- package/crates/bsnext_client/ui/svg/wordmark-white.svg +0 -38
- package/crates/bsnext_core/Cargo.toml +0 -44
- package/crates/bsnext_core/src/common_layers.rs +0 -62
- package/crates/bsnext_core/src/dir_loader.rs +0 -230
- package/crates/bsnext_core/src/dto.rs +0 -341
- package/crates/bsnext_core/src/handlers/mod.rs +0 -1
- package/crates/bsnext_core/src/handlers/proxy.rs +0 -95
- package/crates/bsnext_core/src/lib.rs +0 -12
- package/crates/bsnext_core/src/meta/mod.rs +0 -5
- package/crates/bsnext_core/src/not_found/mod.rs +0 -1
- package/crates/bsnext_core/src/not_found/not_found_service.rs +0 -35
- package/crates/bsnext_core/src/panic_handler.rs +0 -32
- package/crates/bsnext_core/src/raw_loader.rs +0 -196
- package/crates/bsnext_core/src/server/actor.rs +0 -92
- package/crates/bsnext_core/src/server/error.rs +0 -41
- package/crates/bsnext_core/src/server/handler_change.rs +0 -85
- package/crates/bsnext_core/src/server/handler_listen.rs +0 -163
- package/crates/bsnext_core/src/server/handler_patch.rs +0 -42
- package/crates/bsnext_core/src/server/handler_routes_updated.rs +0 -27
- package/crates/bsnext_core/src/server/handler_stop.rs +0 -38
- package/crates/bsnext_core/src/server/mod.rs +0 -10
- package/crates/bsnext_core/src/server/router/assets.rs +0 -39
- package/crates/bsnext_core/src/server/router/mod.rs +0 -123
- package/crates/bsnext_core/src/server/router/pub_api.rs +0 -39
- package/crates/bsnext_core/src/server/router/snapshots/bsnext_core__server__router__tests__test__handlers.snap +0 -9
- package/crates/bsnext_core/src/server/router/tests.rs +0 -209
- package/crates/bsnext_core/src/server/signals.rs +0 -11
- package/crates/bsnext_core/src/server/state.rs +0 -23
- package/crates/bsnext_core/src/servers_supervisor/actor.rs +0 -199
- package/crates/bsnext_core/src/servers_supervisor/file_changed_handler.rs +0 -41
- package/crates/bsnext_core/src/servers_supervisor/get_servers_handler.rs +0 -24
- package/crates/bsnext_core/src/servers_supervisor/input_changed_handler.rs +0 -21
- package/crates/bsnext_core/src/servers_supervisor/mod.rs +0 -6
- package/crates/bsnext_core/src/servers_supervisor/start_handler.rs +0 -86
- package/crates/bsnext_core/src/servers_supervisor/stop_handler.rs +0 -26
- package/crates/bsnext_core/src/ws/mod.rs +0 -164
- package/crates/bsnext_example/Cargo.toml +0 -10
- package/crates/bsnext_example/src/basic.rs +0 -51
- package/crates/bsnext_example/src/lib.rs +0 -26
- package/crates/bsnext_example/src/lit.rs +0 -37
- package/crates/bsnext_example/src/md.rs +0 -18
- package/crates/bsnext_fs/Cargo.toml +0 -22
- package/crates/bsnext_fs/src/actor.rs +0 -123
- package/crates/bsnext_fs/src/buffered_debounce.rs +0 -166
- package/crates/bsnext_fs/src/filter.rs +0 -39
- package/crates/bsnext_fs/src/inner_fs_event_handler.rs +0 -94
- package/crates/bsnext_fs/src/lib.rs +0 -141
- package/crates/bsnext_fs/src/remove_path_handler.rs +0 -46
- package/crates/bsnext_fs/src/stop_handler.rs +0 -15
- package/crates/bsnext_fs/src/stream.rs +0 -167
- package/crates/bsnext_fs/src/test/mod.rs +0 -213
- package/crates/bsnext_fs/src/watch_path_handler.rs +0 -67
- package/crates/bsnext_fs/src/watcher.rs +0 -349
- package/crates/bsnext_input/Cargo.toml +0 -25
- package/crates/bsnext_input/src/input_test/mod.rs +0 -185
- package/crates/bsnext_input/src/input_test/snapshots/bsnext_input__input_test__deserialize_3_headers.snap +0 -29
- package/crates/bsnext_input/src/input_test/snapshots/bsnext_input__input_test__deserialize_3_headers_control.snap +0 -25
- package/crates/bsnext_input/src/lib.rs +0 -153
- package/crates/bsnext_input/src/md.rs +0 -541
- package/crates/bsnext_input/src/paths.rs +0 -64
- package/crates/bsnext_input/src/route.rs +0 -189
- package/crates/bsnext_input/src/route_manifest.rs +0 -186
- package/crates/bsnext_input/src/server_config.rs +0 -88
- package/crates/bsnext_input/src/target.rs +0 -7
- package/crates/bsnext_input/src/watch_opt_test/mod.rs +0 -68
- package/crates/bsnext_input/src/yml.rs +0 -1
- package/crates/bsnext_output/Cargo.toml +0 -16
- package/crates/bsnext_output/src/json.rs +0 -11
- package/crates/bsnext_output/src/lib.rs +0 -25
- package/crates/bsnext_output/src/pretty.rs +0 -147
- package/crates/bsnext_resp/Cargo.toml +0 -13
- package/crates/bsnext_resp/src/js/snippet.html +0 -1
- package/crates/bsnext_resp/src/js/ws.js +0 -1
- package/crates/bsnext_resp/src/lib.rs +0 -79
- package/crates/bsnext_system/Cargo.toml +0 -29
- package/crates/bsnext_system/src/args.rs +0 -47
- package/crates/bsnext_system/src/lib.rs +0 -227
- package/crates/bsnext_system/src/monitor.rs +0 -241
- package/crates/bsnext_system/src/monitor_any_watchables.rs +0 -133
- package/crates/bsnext_system/src/start_kind/snapshots/bsnext_system__start_kind__start_from_paths__test__test-2.snap +0 -12
- package/crates/bsnext_system/src/start_kind/snapshots/bsnext_system__start_kind__start_from_paths__test__test.snap +0 -30
- package/crates/bsnext_system/src/start_kind/start_from_example.rs +0 -49
- package/crates/bsnext_system/src/start_kind/start_from_inputs.rs +0 -67
- package/crates/bsnext_system/src/start_kind/start_from_paths.rs +0 -51
- package/crates/bsnext_system/src/start_kind.rs +0 -56
- package/crates/bsnext_system/src/startup.rs +0 -51
- package/crates/bsnext_tracing/Cargo.toml +0 -10
- package/crates/bsnext_tracing/src/lib.rs +0 -127
- package/examples/basic/input.yml +0 -5
- package/examples/basic/public/index.html +0 -15
- package/examples/basic/public/reset.css +0 -52
- package/examples/basic/public/script.js +0 -1
- package/examples/basic/public/styles.css +0 -3
- package/examples/kitchen-sink/a-file.md +0 -1
- package/examples/kitchen-sink/api/1.json +0 -1
- package/examples/kitchen-sink/api/2.json +0 -3
- package/examples/kitchen-sink/app.js +0 -1
- package/examples/kitchen-sink/input.html +0 -185
- package/examples/kitchen-sink/input.yml +0 -133
- package/examples/kitchen-sink/styles-2.css +0 -3
- package/examples/lit/index.html +0 -21
- package/examples/lit/input.yml +0 -5
- package/examples/lit/lit.js +0 -82
- package/examples/lit/package-lock.json +0 -62
- package/examples/lit/package.json +0 -15
- package/examples/md-single/frontmatter.md +0 -35
- package/examples/md-single/md-single.md +0 -35
- package/examples/openai/.nvm +0 -1
- package/examples/openai/build.mjs +0 -21
- package/examples/openai/index.html +0 -13
- package/examples/openai/input.yml +0 -59
- package/examples/openai/package-lock.json +0 -720
- package/examples/openai/package.json +0 -21
- package/examples/openai/src/index.js +0 -21
- package/examples/openai/sse/01.txt +0 -8
- package/examples/proxy-simple/input.yml +0 -9
- package/examples/single/input.yaml +0 -26
- package/run.sh +0 -6
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
use crate::route::{DirRoute, Route, RouteKind};
|
|
2
|
-
use crate::server_config::{Identity, ServerConfig};
|
|
3
|
-
use crate::{Input, PathDefinition, PathDefs, PathError};
|
|
4
|
-
use std::path::{Path, PathBuf};
|
|
5
|
-
|
|
6
|
-
pub fn from_paths<T: AsRef<str>>(
|
|
7
|
-
cwd: &Path,
|
|
8
|
-
paths: &[T],
|
|
9
|
-
identity: Identity,
|
|
10
|
-
) -> Result<Input, PathError> {
|
|
11
|
-
let path_defs = paths
|
|
12
|
-
.iter()
|
|
13
|
-
.map(|p| {
|
|
14
|
-
let pb = PathBuf::from(p.as_ref());
|
|
15
|
-
if pb.is_absolute() {
|
|
16
|
-
return PathDefinition {
|
|
17
|
-
input: p.as_ref().to_string(),
|
|
18
|
-
cwd: cwd.to_path_buf(),
|
|
19
|
-
absolute: pb,
|
|
20
|
-
};
|
|
21
|
-
} else {
|
|
22
|
-
return PathDefinition {
|
|
23
|
-
input: p.as_ref().to_string(),
|
|
24
|
-
cwd: cwd.to_path_buf(),
|
|
25
|
-
absolute: cwd.join(pb),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
.map(|path_def| {
|
|
30
|
-
let exists = path_def.absolute.exists();
|
|
31
|
-
(path_def, exists)
|
|
32
|
-
})
|
|
33
|
-
.collect::<Vec<(PathDefinition, bool)>>();
|
|
34
|
-
|
|
35
|
-
let invalid = path_defs
|
|
36
|
-
.into_iter()
|
|
37
|
-
.filter_map(|(pb, exists)| if exists { None } else { Some(pb) })
|
|
38
|
-
.collect::<Vec<_>>();
|
|
39
|
-
|
|
40
|
-
if !invalid.is_empty() {
|
|
41
|
-
return Err(PathError::MissingPaths {
|
|
42
|
-
paths: PathDefs(invalid),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let server = ServerConfig {
|
|
47
|
-
identity,
|
|
48
|
-
routes: paths
|
|
49
|
-
.iter()
|
|
50
|
-
.map(|p| -> Route {
|
|
51
|
-
let str = p.as_ref();
|
|
52
|
-
Route {
|
|
53
|
-
path: "/".to_string(),
|
|
54
|
-
kind: RouteKind::Dir(DirRoute { dir: str.into() }),
|
|
55
|
-
..Default::default()
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
.collect(),
|
|
59
|
-
..Default::default()
|
|
60
|
-
};
|
|
61
|
-
Ok(Input {
|
|
62
|
-
servers: vec![server],
|
|
63
|
-
})
|
|
64
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
use std::collections::BTreeMap;
|
|
2
|
-
use std::fmt::{Display, Formatter};
|
|
3
|
-
use std::hash::{Hash, Hasher};
|
|
4
|
-
use std::ops::Deref;
|
|
5
|
-
|
|
6
|
-
use typeshare::typeshare;
|
|
7
|
-
|
|
8
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
9
|
-
pub struct Route {
|
|
10
|
-
pub path: String,
|
|
11
|
-
#[serde(flatten)]
|
|
12
|
-
pub cors_opts: Option<CorsOpts>,
|
|
13
|
-
#[serde(flatten)]
|
|
14
|
-
pub delay_opts: Option<DelayOpts>,
|
|
15
|
-
#[serde(rename = "watch")]
|
|
16
|
-
#[serde(default)]
|
|
17
|
-
pub watch_opts: WatchOpts,
|
|
18
|
-
#[serde(flatten)]
|
|
19
|
-
pub kind: RouteKind,
|
|
20
|
-
pub headers: Option<BTreeMap<String, String>>,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
impl Default for Route {
|
|
24
|
-
fn default() -> Self {
|
|
25
|
-
Self {
|
|
26
|
-
path: "/".to_string(),
|
|
27
|
-
kind: RouteKind::Html {
|
|
28
|
-
html: "default".into(),
|
|
29
|
-
},
|
|
30
|
-
delay_opts: None,
|
|
31
|
-
cors_opts: None,
|
|
32
|
-
watch_opts: Default::default(),
|
|
33
|
-
headers: None,
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
impl AsRef<Route> for Route {
|
|
39
|
-
fn as_ref(&self) -> &Route {
|
|
40
|
-
self
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
impl Route {
|
|
45
|
-
pub fn path(&self) -> &str {
|
|
46
|
-
self.path.as_str()
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
#[derive(Debug, Hash, PartialEq, Clone, serde::Deserialize, serde::Serialize)]
|
|
51
|
-
#[serde(untagged)]
|
|
52
|
-
pub enum RouteKind {
|
|
53
|
-
Html { html: String },
|
|
54
|
-
Json { json: JsonWrapper },
|
|
55
|
-
Raw { raw: String },
|
|
56
|
-
Sse { sse: String },
|
|
57
|
-
Proxy(ProxyRoute),
|
|
58
|
-
Dir(DirRoute),
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#[derive(Debug, PartialEq, Clone, serde::Deserialize, serde::Serialize)]
|
|
62
|
-
pub struct JsonWrapper(serde_json::Value);
|
|
63
|
-
|
|
64
|
-
impl Display for JsonWrapper {
|
|
65
|
-
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
66
|
-
write!(f, "{}", serde_json::to_string(&self.0).expect("serde_json"))
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
impl Deref for JsonWrapper {
|
|
71
|
-
type Target = serde_json::Value;
|
|
72
|
-
|
|
73
|
-
fn deref(&self) -> &Self::Target {
|
|
74
|
-
&self.0
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
impl Hash for JsonWrapper {
|
|
79
|
-
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
80
|
-
//todo: implement hashing for serde_value
|
|
81
|
-
if let Ok(as_str) = serde_json::to_string(&self.0) {
|
|
82
|
-
state.write(as_str.as_bytes());
|
|
83
|
-
} else {
|
|
84
|
-
todo!("handle error here?")
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
#[typeshare]
|
|
90
|
-
impl RouteKind {
|
|
91
|
-
#[allow(dead_code)]
|
|
92
|
-
pub fn html(s: &str) -> Self {
|
|
93
|
-
Self::Html { html: s.into() }
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
98
|
-
pub struct DirRoute {
|
|
99
|
-
pub dir: String,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
103
|
-
pub struct ProxyRoute {
|
|
104
|
-
pub proxy: String,
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
108
|
-
pub enum CorsOpts {
|
|
109
|
-
#[serde(rename = "cors")]
|
|
110
|
-
Cors(bool),
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
114
|
-
pub enum DelayOpts {
|
|
115
|
-
#[serde(rename = "delay")]
|
|
116
|
-
Delay(DelayKind),
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
#[derive(
|
|
120
|
-
Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
121
|
-
)]
|
|
122
|
-
pub enum DelayKind {
|
|
123
|
-
#[serde(rename = "ms")]
|
|
124
|
-
Ms(u64),
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
#[derive(
|
|
128
|
-
Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
129
|
-
)]
|
|
130
|
-
pub enum DebounceDuration {
|
|
131
|
-
#[serde(rename = "ms")]
|
|
132
|
-
Ms(u64),
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
#[derive(
|
|
136
|
-
Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
137
|
-
)]
|
|
138
|
-
#[serde(untagged)]
|
|
139
|
-
pub enum FilterKind {
|
|
140
|
-
StringGlob(String),
|
|
141
|
-
Extension { ext: String },
|
|
142
|
-
Glob { glob: String },
|
|
143
|
-
List(Vec<FilterKind>),
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
#[derive(
|
|
147
|
-
Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
148
|
-
)]
|
|
149
|
-
pub struct Spec {
|
|
150
|
-
#[serde(flatten)]
|
|
151
|
-
pub opts: Option<SpecOpts>,
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
#[derive(
|
|
155
|
-
Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
156
|
-
)]
|
|
157
|
-
pub struct SpecOpts {
|
|
158
|
-
pub debounce: Option<DebounceDuration>,
|
|
159
|
-
pub filter: Option<FilterKind>,
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
#[derive(Debug, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize)]
|
|
163
|
-
#[serde(untagged)]
|
|
164
|
-
pub enum WatchOpts {
|
|
165
|
-
Bool(bool),
|
|
166
|
-
InlineGlob(String),
|
|
167
|
-
Spec(Spec),
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
impl Default for WatchOpts {
|
|
171
|
-
fn default() -> Self {
|
|
172
|
-
Self::Bool(true)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
impl WatchOpts {
|
|
177
|
-
pub fn is_enabled(&self) -> bool {
|
|
178
|
-
!matches!(self, WatchOpts::Bool(false))
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
#[derive(
|
|
183
|
-
Debug, PartialOrd, Ord, Eq, PartialEq, Hash, Clone, serde::Deserialize, serde::Serialize,
|
|
184
|
-
)]
|
|
185
|
-
pub struct Watcher {
|
|
186
|
-
pub dir: String,
|
|
187
|
-
pub debounce_ms: Option<u64>,
|
|
188
|
-
pub filter: Option<FilterKind>,
|
|
189
|
-
}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
use crate::route::{Route, RouteKind};
|
|
2
|
-
use std::collections::{HashMap, HashSet};
|
|
3
|
-
use std::hash::{DefaultHasher, Hash, Hasher};
|
|
4
|
-
|
|
5
|
-
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
6
|
-
pub struct RoutesManifest {
|
|
7
|
-
inner: HashMap<RouteIdentity, u64>,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
impl RoutesManifest {
|
|
11
|
-
pub fn changeset_for(&self, other: &Self) -> RouteChangeSet {
|
|
12
|
-
let prev = self.inner.keys().collect::<HashSet<_>>();
|
|
13
|
-
let next = other.inner.keys().collect::<HashSet<_>>();
|
|
14
|
-
let changed_only = prev
|
|
15
|
-
.intersection(&next)
|
|
16
|
-
.filter_map(|id| {
|
|
17
|
-
let old = self.inner.get(*id);
|
|
18
|
-
let new = other.inner.get(*id);
|
|
19
|
-
match (old, new) {
|
|
20
|
-
(Some(old), Some(new)) if old != new => Some((*id).to_owned()),
|
|
21
|
-
_ => None,
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
.collect::<Vec<_>>();
|
|
25
|
-
RouteChangeSet {
|
|
26
|
-
added: next.difference(&prev).map(|x| (*x).to_owned()).collect(),
|
|
27
|
-
removed: prev.difference(&next).map(|x| (*x).to_owned()).collect(),
|
|
28
|
-
changed: changed_only,
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
pub fn new<A: AsRef<Route>>(routes: &[A]) -> Self {
|
|
32
|
-
Self {
|
|
33
|
-
inner: routes
|
|
34
|
-
.iter()
|
|
35
|
-
.map(|a| {
|
|
36
|
-
let route = a.as_ref();
|
|
37
|
-
let mut hasher = DefaultHasher::new();
|
|
38
|
-
route.hash(&mut hasher);
|
|
39
|
-
let r2_hash = hasher.finish();
|
|
40
|
-
let id: RouteIdentity = a.as_ref().into();
|
|
41
|
-
(id, r2_hash)
|
|
42
|
-
})
|
|
43
|
-
.collect::<HashMap<RouteIdentity, u64>>(),
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
#[derive(Debug, PartialEq, Hash, Eq, Clone)]
|
|
49
|
-
pub struct RouteIdentity {
|
|
50
|
-
pub path: String,
|
|
51
|
-
pub kind_str: String,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
impl From<&Route> for RouteIdentity {
|
|
55
|
-
fn from(value: &Route) -> Self {
|
|
56
|
-
Self {
|
|
57
|
-
path: value.path.clone(),
|
|
58
|
-
kind_str: match value.kind {
|
|
59
|
-
RouteKind::Html { .. } => "RouteKind::Html",
|
|
60
|
-
RouteKind::Json { .. } => "RouteKind::Json",
|
|
61
|
-
RouteKind::Raw { .. } => "RouteKind::Raw",
|
|
62
|
-
RouteKind::Sse { .. } => "RouteKind::Sse",
|
|
63
|
-
RouteKind::Proxy(_) => "RouteKind::Proxy",
|
|
64
|
-
RouteKind::Dir(_) => "RouteKind::Dir",
|
|
65
|
-
}
|
|
66
|
-
.to_string(),
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
71
|
-
pub struct RouteChangeSet {
|
|
72
|
-
pub added: Vec<RouteIdentity>,
|
|
73
|
-
pub removed: Vec<RouteIdentity>,
|
|
74
|
-
pub changed: Vec<RouteIdentity>,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
#[cfg(test)]
|
|
78
|
-
mod test {
|
|
79
|
-
use super::*;
|
|
80
|
-
|
|
81
|
-
use std::hash::DefaultHasher;
|
|
82
|
-
#[test]
|
|
83
|
-
fn test_route_hash() -> anyhow::Result<()> {
|
|
84
|
-
let r1 = Route {
|
|
85
|
-
path: "/".to_string(),
|
|
86
|
-
kind: RouteKind::Html {
|
|
87
|
-
html: String::from("hello world!"),
|
|
88
|
-
},
|
|
89
|
-
..Default::default()
|
|
90
|
-
};
|
|
91
|
-
let r2 = r#"
|
|
92
|
-
path: /
|
|
93
|
-
html: hello world!
|
|
94
|
-
"#;
|
|
95
|
-
let r2: Route = serde_yaml::from_str(&r2).expect("test");
|
|
96
|
-
|
|
97
|
-
let mut hasher = DefaultHasher::new();
|
|
98
|
-
r1.hash(&mut hasher);
|
|
99
|
-
let r1_hash = hasher.finish();
|
|
100
|
-
|
|
101
|
-
let mut hasher = DefaultHasher::new();
|
|
102
|
-
r2.hash(&mut hasher);
|
|
103
|
-
let r2_hash = hasher.finish();
|
|
104
|
-
|
|
105
|
-
assert_eq!(r1_hash, r2_hash);
|
|
106
|
-
|
|
107
|
-
Ok(())
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
#[test]
|
|
111
|
-
fn test_route_hash_2() -> anyhow::Result<()> {
|
|
112
|
-
let r1 = r#"
|
|
113
|
-
path: /
|
|
114
|
-
html: hello world!
|
|
115
|
-
"#;
|
|
116
|
-
let r2 = r#"
|
|
117
|
-
path: /api
|
|
118
|
-
html: hello world!
|
|
119
|
-
"#;
|
|
120
|
-
let r2_edited = r#"
|
|
121
|
-
path: /api
|
|
122
|
-
html: hello world
|
|
123
|
-
"#;
|
|
124
|
-
|
|
125
|
-
let r1: Route = serde_yaml::from_str(&r1).expect("test");
|
|
126
|
-
let r2: Route = serde_yaml::from_str(&r2).expect("test");
|
|
127
|
-
let r2_edited: Route = serde_yaml::from_str(&r2_edited).expect("test");
|
|
128
|
-
|
|
129
|
-
let routes_orig = RoutesManifest::new(&[&r1, &r2]);
|
|
130
|
-
let routes_next = RoutesManifest::new(&[&r1]);
|
|
131
|
-
let routes_next_dup = RoutesManifest::new(&[&r1, &r2]);
|
|
132
|
-
let routes_next_3 = RoutesManifest::new(&[&r1, &r2_edited]);
|
|
133
|
-
|
|
134
|
-
let changeset_1 = routes_orig.changeset_for(&routes_next);
|
|
135
|
-
let changeset_2 = routes_orig.changeset_for(&routes_next_dup);
|
|
136
|
-
let changeset_3 = routes_orig.changeset_for(&routes_next_3);
|
|
137
|
-
|
|
138
|
-
assert_eq!(
|
|
139
|
-
changeset_1,
|
|
140
|
-
RouteChangeSet {
|
|
141
|
-
added: vec![],
|
|
142
|
-
removed: vec![RouteIdentity {
|
|
143
|
-
path: "/api".to_string(),
|
|
144
|
-
kind_str: "RouteKind::Html".to_string()
|
|
145
|
-
}],
|
|
146
|
-
changed: vec![],
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
assert_eq!(
|
|
151
|
-
changeset_1,
|
|
152
|
-
RouteChangeSet {
|
|
153
|
-
added: vec![],
|
|
154
|
-
removed: vec![RouteIdentity {
|
|
155
|
-
path: "/api".to_string(),
|
|
156
|
-
kind_str: "RouteKind::Html".to_string()
|
|
157
|
-
}],
|
|
158
|
-
changed: vec![],
|
|
159
|
-
}
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
// dbg!(changeset_1);
|
|
163
|
-
assert_eq!(
|
|
164
|
-
changeset_2,
|
|
165
|
-
RouteChangeSet {
|
|
166
|
-
added: vec![],
|
|
167
|
-
removed: vec![],
|
|
168
|
-
changed: vec![],
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
assert_eq!(
|
|
173
|
-
changeset_3,
|
|
174
|
-
RouteChangeSet {
|
|
175
|
-
added: vec![],
|
|
176
|
-
removed: vec![],
|
|
177
|
-
changed: vec![RouteIdentity {
|
|
178
|
-
path: "/api".to_string(),
|
|
179
|
-
kind_str: "RouteKind::Html".to_string()
|
|
180
|
-
}],
|
|
181
|
-
}
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
Ok(())
|
|
185
|
-
}
|
|
186
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
use crate::route::{Route, Watcher};
|
|
2
|
-
use crate::{rand_word, PortError};
|
|
3
|
-
use std::hash::{DefaultHasher, Hash, Hasher};
|
|
4
|
-
use std::net::SocketAddr;
|
|
5
|
-
use std::str::FromStr;
|
|
6
|
-
|
|
7
|
-
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
|
8
|
-
pub struct ServerConfig {
|
|
9
|
-
#[serde(flatten)]
|
|
10
|
-
pub identity: Identity,
|
|
11
|
-
#[serde(default)]
|
|
12
|
-
pub routes: Vec<Route>,
|
|
13
|
-
#[serde(default)]
|
|
14
|
-
pub watchers: Vec<Watcher>,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
#[derive(
|
|
18
|
-
Debug, Ord, PartialOrd, PartialEq, Hash, Eq, Clone, serde::Deserialize, serde::Serialize,
|
|
19
|
-
)]
|
|
20
|
-
#[serde(untagged)]
|
|
21
|
-
pub enum Identity {
|
|
22
|
-
Both { name: String, bind_address: String },
|
|
23
|
-
Address { bind_address: String },
|
|
24
|
-
Named { name: String },
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
impl Default for Identity {
|
|
28
|
-
fn default() -> Self {
|
|
29
|
-
Self::named()
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
impl Identity {
|
|
34
|
-
pub fn named() -> Self {
|
|
35
|
-
Self::Named { name: rand_word() }
|
|
36
|
-
}
|
|
37
|
-
pub fn address<A: AsRef<str>>(a: A) -> Self {
|
|
38
|
-
Self::Address {
|
|
39
|
-
bind_address: a.as_ref().to_string(),
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/// if a port was provided, try to use it by validating it first
|
|
43
|
-
/// otherwise default to a named identity
|
|
44
|
-
pub fn from_port_or_named(port: Option<u16>) -> Result<Self, PortError> {
|
|
45
|
-
let result = port.map(|port| {
|
|
46
|
-
SocketAddr::from_str(&format!("0.0.0.0:{port}"))
|
|
47
|
-
.map_err(|err| PortError::InvalidPort { port, err })
|
|
48
|
-
});
|
|
49
|
-
match result {
|
|
50
|
-
None => Ok(Identity::named()),
|
|
51
|
-
Some(Ok(addr)) => Ok(Identity::address(addr.to_string())),
|
|
52
|
-
Some(Err(err)) => Err(err),
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
pub fn as_id(&self) -> u64 {
|
|
57
|
-
let mut hasher = DefaultHasher::new();
|
|
58
|
-
self.hash(&mut hasher);
|
|
59
|
-
hasher.finish()
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
#[test]
|
|
64
|
-
fn server_config_as_enum() {
|
|
65
|
-
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
66
|
-
struct C {
|
|
67
|
-
servers: Vec<ServerConfig>,
|
|
68
|
-
}
|
|
69
|
-
let input = r#"
|
|
70
|
-
servers:
|
|
71
|
-
- bind_address: 127.0.0.1:3000
|
|
72
|
-
- name: server_1
|
|
73
|
-
- name: server_2
|
|
74
|
-
bind_address: 127.0.0.1:3001
|
|
75
|
-
routes:
|
|
76
|
-
- path: /
|
|
77
|
-
dir: .
|
|
78
|
-
"#;
|
|
79
|
-
let c: C = serde_yaml::from_str(input).unwrap();
|
|
80
|
-
|
|
81
|
-
// let baseline = ServerConfigInput::Named { name: "server_1".into() };
|
|
82
|
-
let baseline = Identity::Address {
|
|
83
|
-
bind_address: "127.0.0.1x:3000".into(),
|
|
84
|
-
};
|
|
85
|
-
for x in &c.servers {
|
|
86
|
-
assert_eq!(x.identity == baseline, false);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
use crate::route::{DebounceDuration, FilterKind, Spec, SpecOpts, WatchOpts};
|
|
2
|
-
|
|
3
|
-
#[test]
|
|
4
|
-
fn test_watch_opts_debounce() {
|
|
5
|
-
let input = r#"
|
|
6
|
-
debounce:
|
|
7
|
-
ms: 200
|
|
8
|
-
filter: "**/*.css"
|
|
9
|
-
"#;
|
|
10
|
-
let expected = WatchOpts::Spec(Spec {
|
|
11
|
-
opts: Some(SpecOpts {
|
|
12
|
-
debounce: Some(DebounceDuration::Ms(200)),
|
|
13
|
-
filter: Some(FilterKind::StringGlob("**/*.css".into())),
|
|
14
|
-
}),
|
|
15
|
-
});
|
|
16
|
-
let actual: WatchOpts = serde_yaml::from_str(input).unwrap();
|
|
17
|
-
assert_eq!(actual, expected);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
#[test]
|
|
21
|
-
fn test_watch_opts_inline_filter() {
|
|
22
|
-
let input = r#"
|
|
23
|
-
filter: "**/*.css"
|
|
24
|
-
"#;
|
|
25
|
-
let expected = WatchOpts::Spec(Spec {
|
|
26
|
-
opts: Some(SpecOpts {
|
|
27
|
-
debounce: None,
|
|
28
|
-
filter: Some(FilterKind::StringGlob("**/*.css".into())),
|
|
29
|
-
}),
|
|
30
|
-
});
|
|
31
|
-
let actual: WatchOpts = serde_yaml::from_str(input).unwrap();
|
|
32
|
-
assert_eq!(actual, expected);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
#[test]
|
|
36
|
-
fn test_watch_opts_explicit_filter_ext() {
|
|
37
|
-
let input = r#"
|
|
38
|
-
filter:
|
|
39
|
-
ext: "css"
|
|
40
|
-
"#;
|
|
41
|
-
let expected = WatchOpts::Spec(Spec {
|
|
42
|
-
opts: Some(SpecOpts {
|
|
43
|
-
debounce: None,
|
|
44
|
-
filter: Some(FilterKind::Extension {
|
|
45
|
-
ext: "css".to_string(),
|
|
46
|
-
}),
|
|
47
|
-
}),
|
|
48
|
-
});
|
|
49
|
-
let actual: WatchOpts = serde_yaml::from_str(input).unwrap();
|
|
50
|
-
assert_eq!(actual, expected);
|
|
51
|
-
}
|
|
52
|
-
#[test]
|
|
53
|
-
fn test_watch_opts_explicit_filter_glob() {
|
|
54
|
-
let input = r#"
|
|
55
|
-
filter:
|
|
56
|
-
glob: "**/*.css"
|
|
57
|
-
"#;
|
|
58
|
-
let expected = WatchOpts::Spec(Spec {
|
|
59
|
-
opts: Some(SpecOpts {
|
|
60
|
-
debounce: None,
|
|
61
|
-
filter: Some(FilterKind::Glob {
|
|
62
|
-
glob: "**/*.css".into(),
|
|
63
|
-
}),
|
|
64
|
-
}),
|
|
65
|
-
});
|
|
66
|
-
let actual: WatchOpts = serde_yaml::from_str(input).unwrap();
|
|
67
|
-
assert_eq!(actual, expected);
|
|
68
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
name = "bsnext_output"
|
|
3
|
-
version = "0.1.0"
|
|
4
|
-
edition = "2021"
|
|
5
|
-
|
|
6
|
-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
7
|
-
|
|
8
|
-
[dependencies]
|
|
9
|
-
bsnext_core = { path = "../bsnext_core" }
|
|
10
|
-
|
|
11
|
-
ansi_term = { version = "0.12.1" }
|
|
12
|
-
|
|
13
|
-
anyhow = { workspace = true }
|
|
14
|
-
clap = { workspace = true }
|
|
15
|
-
serde = { workspace = true }
|
|
16
|
-
serde_json = { workspace = true }
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
use crate::OutputWriter;
|
|
2
|
-
use bsnext_core::dto::ExternalEvents;
|
|
3
|
-
use std::io::Write;
|
|
4
|
-
|
|
5
|
-
pub struct JsonPrint;
|
|
6
|
-
|
|
7
|
-
impl OutputWriter for JsonPrint {
|
|
8
|
-
fn handle_event<W: Write>(&self, sink: &mut W, evt: &ExternalEvents) -> anyhow::Result<()> {
|
|
9
|
-
write!(sink, "{}", serde_json::to_string(&evt)?).map_err(|e| anyhow::anyhow!(e.to_string()))
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
use crate::json::JsonPrint;
|
|
2
|
-
use crate::pretty::PrettyPrint;
|
|
3
|
-
use bsnext_core::dto::ExternalEvents;
|
|
4
|
-
use std::io::Write;
|
|
5
|
-
|
|
6
|
-
pub mod json;
|
|
7
|
-
pub mod pretty;
|
|
8
|
-
|
|
9
|
-
pub trait OutputWriter {
|
|
10
|
-
fn handle_event<W: Write>(&self, sink: &mut W, evt: &ExternalEvents) -> anyhow::Result<()>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub enum Writers {
|
|
14
|
-
Pretty,
|
|
15
|
-
Json,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
impl OutputWriter for Writers {
|
|
19
|
-
fn handle_event<W: Write>(&self, sink: &mut W, evt: &ExternalEvents) -> anyhow::Result<()> {
|
|
20
|
-
match self {
|
|
21
|
-
Writers::Pretty => PrettyPrint.handle_event(sink, evt),
|
|
22
|
-
Writers::Json => JsonPrint.handle_event(sink, evt),
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|