fix: do some fix
This commit is contained in:
parent
f94e175082
commit
07ac7e3376
@ -1,5 +1,4 @@
|
||||
[alias]
|
||||
recorder = "run -p recorder --bin recorder_cli -- --environment development"
|
||||
recorder-playground = "run -p recorder --example playground -- --environment development"
|
||||
|
||||
[build]
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -158,11 +158,8 @@ web_modules/
|
||||
.yarn-integrity
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.*.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
@ -219,6 +216,7 @@ index.d.ts.map
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
/ide-target
|
||||
!/examples/.gitkeep
|
||||
/.env
|
||||
/.env.bk
|
||||
|
448
Cargo.lock
generated
448
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,6 @@
|
||||
}
|
||||
```
|
||||
|
||||
^https://konobangu.com/api/playground*** reqHeaders://{x-forwarded.json} http://127.0.0.1:5002/api/playground$1
|
||||
^wss://konobangu.com/api/playground*** reqHeaders://{x-forwarded.json} ws://127.0.0.1:5002/api/playground$1
|
||||
^https://konobangu.com/api*** reqHeaders://{x-forwarded.json} http://127.0.0.1:5001/api$1 excludeFilter://^^https://konobangu.com/api/playground***
|
||||
^https://konobangu.com/api*** reqHeaders://{x-forwarded.json} http://127.0.0.1:5001/api$1
|
||||
^https://konobangu.com/*** reqHeaders://{x-forwarded.json} http://127.0.0.1:5000/$1 excludeFilter://^https://konobangu.com/api***
|
||||
^wss://konobangu.com/*** reqHeaders://{x-forwarded.json} ws://127.0.0.1:5000/$1 excludeFilter://^wss://konobangu.com/api/playground***
|
||||
^wss://konobangu.com/*** reqHeaders://{x-forwarded.json} ws://127.0.0.1:5000/$1 excludeFilter://^wss://konobangu.com/api
|
8
apps/recorder/.env
Normal file
8
apps/recorder/.env
Normal file
@ -0,0 +1,8 @@
|
||||
AUTH_TYPE = "basic" # or oidc
|
||||
BASIC_USER = "konobangu"
|
||||
BASIC_PASSWORD = "konobangu"
|
||||
# OIDC_ISSUER="https://auth.logto.io/oidc"
|
||||
# OIDC_API_AUDIENCE = "https://konobangu.com/api"
|
||||
# OIDC_CLIENT_ID = "client_id"
|
||||
# OIDC_CLIENT_SECRET = "client_secret" # optional
|
||||
# OIDC_EXTRA_SCOPES = "read:konobangu write:konobangu"
|
@ -29,7 +29,7 @@ pub struct AppBuilder {
|
||||
dotenv_file: Option<String>,
|
||||
config_file: Option<String>,
|
||||
working_dir: String,
|
||||
enviornment: Environment,
|
||||
environment: Environment,
|
||||
}
|
||||
|
||||
impl AppBuilder {
|
||||
@ -70,21 +70,21 @@ impl AppBuilder {
|
||||
|
||||
pub async fn build(self) -> RResult<App> {
|
||||
AppConfig::load_dotenv(
|
||||
&self.enviornment,
|
||||
&self.environment,
|
||||
&self.working_dir,
|
||||
self.dotenv_file.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let config = AppConfig::load_config(
|
||||
&self.enviornment,
|
||||
&self.environment,
|
||||
&self.working_dir,
|
||||
self.config_file.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let app_context = Arc::new(
|
||||
AppContext::new(self.enviornment.clone(), config, self.working_dir.clone()).await?,
|
||||
AppContext::new(self.environment.clone(), config, self.working_dir.clone()).await?,
|
||||
);
|
||||
|
||||
Ok(App {
|
||||
@ -101,7 +101,7 @@ impl AppBuilder {
|
||||
|
||||
pub fn environment(self, environment: Environment) -> Self {
|
||||
let mut ret = self;
|
||||
ret.enviornment = environment;
|
||||
ret.environment = environment;
|
||||
ret
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ impl AppBuilder {
|
||||
impl Default for AppBuilder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enviornment: Environment::Production,
|
||||
environment: Environment::Production,
|
||||
dotenv_file: None,
|
||||
config_file: None,
|
||||
working_dir: String::from("."),
|
||||
|
@ -34,12 +34,13 @@ impl App {
|
||||
|
||||
let mut router = Router::<Arc<dyn AppContextTrait>>::new();
|
||||
|
||||
let (graphqlc, oidcc) = try_join!(
|
||||
let (graphql_c, oidc_c, metadata_c) = try_join!(
|
||||
controller::graphql::create(context.clone()),
|
||||
controller::oidc::create(context.clone()),
|
||||
controller::metadata::create(context.clone())
|
||||
)?;
|
||||
|
||||
for c in [graphqlc, oidcc] {
|
||||
for c in [graphql_c, oidc_c, metadata_c] {
|
||||
router = c.apply_to(router);
|
||||
}
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
import { LogLevel, type OpenIdConfiguration } from 'oidc-client-rx';
|
||||
|
||||
export const isBasicAuth = process.env.AUTH_TYPE === 'basic';
|
||||
|
||||
export function buildOidcConfig(): OpenIdConfiguration {
|
||||
const origin = window.location.origin;
|
||||
|
||||
const resource = process.env.OIDC_AUDIENCE!;
|
||||
|
||||
return {
|
||||
authority: process.env.OIDC_ISSUER!,
|
||||
redirectUrl: `${origin}/api/playground/oidc/callback`,
|
||||
postLogoutRedirectUri: `${origin}/api/playground`,
|
||||
clientId: process.env.OIDC_CLIENT_ID!,
|
||||
clientSecret: process.env.OIDC_CLIENT_SECRET,
|
||||
scope: process.env.OIDC_EXTRA_SCOPES
|
||||
? `openid profile email offline_access ${process.env.OIDC_EXTRA_SCOPES}`
|
||||
: 'openid profile email offline_access',
|
||||
triggerAuthorizationResultEvent: true,
|
||||
responseType: 'code',
|
||||
silentRenew: true,
|
||||
useRefreshToken: true,
|
||||
logLevel: LogLevel.Debug,
|
||||
autoUserInfo: !resource,
|
||||
renewUserInfoAfterTokenRenew: !resource,
|
||||
customParamsAuthRequest: {
|
||||
prompt: 'consent',
|
||||
resource,
|
||||
},
|
||||
customParamsRefreshTokenRequest: {
|
||||
resource,
|
||||
},
|
||||
customParamsCodeRequest: {
|
||||
resource,
|
||||
},
|
||||
};
|
||||
}
|
@ -45,7 +45,7 @@ pub enum AuthError {
|
||||
#[error("Invalid oidc request callback code")]
|
||||
OidcInvalidCodeError,
|
||||
#[error(transparent)]
|
||||
OidcCallbackTokenConfigrationError(#[from] ConfigurationError),
|
||||
OidcCallbackTokenConfigurationError(#[from] ConfigurationError),
|
||||
#[error(transparent)]
|
||||
OidcRequestTokenError(
|
||||
#[from] RequestTokenError<HttpClientError, StandardErrorResponse<CoreErrorResponseType>>,
|
||||
@ -120,22 +120,26 @@ fn display_graphql_permission_error(
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AuthErrorBody {
|
||||
pub error_code: i32,
|
||||
pub error_msg: String,
|
||||
pub struct AuthErrorResponse {
|
||||
pub success: bool,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl From<AuthError> for AuthErrorBody {
|
||||
impl From<AuthError> for AuthErrorResponse {
|
||||
fn from(value: AuthError) -> Self {
|
||||
AuthErrorBody {
|
||||
error_code: StatusCode::UNAUTHORIZED.as_u16() as i32,
|
||||
error_msg: value.to_string(),
|
||||
AuthErrorResponse {
|
||||
success: false,
|
||||
message: value.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for AuthError {
|
||||
fn into_response(self) -> Response {
|
||||
(StatusCode::UNAUTHORIZED, Json(AuthErrorBody::from(self))).into_response()
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(AuthErrorResponse::from(self)),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { runInInjectionContext } from '@outposts/injection-js';
|
||||
import { autoLoginPartialRoutesGuard } from 'oidc-client-rx';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import type { RouterContext } from '../web/controller/__root';
|
||||
|
||||
export const beforeLoadGuard = async ({
|
||||
context,
|
||||
}: { context: RouterContext }) => {
|
||||
if (!context.isAuthenticated) {
|
||||
const guard$ = runInInjectionContext(context.injector, () =>
|
||||
autoLoginPartialRoutesGuard()
|
||||
);
|
||||
|
||||
const isAuthenticated = await firstValueFrom(guard$);
|
||||
if (!isAuthenticated) {
|
||||
throw !isAuthenticated;
|
||||
}
|
||||
}
|
||||
};
|
@ -1,52 +0,0 @@
|
||||
import { useObservableEagerState, useObservableState } from 'observable-hooks';
|
||||
import {
|
||||
InjectorContextVoidInjector,
|
||||
useOidcClient,
|
||||
} from 'oidc-client-rx/adapters/react';
|
||||
import { useMemo } from 'react';
|
||||
import { NEVER, type Observable, of } from 'rxjs';
|
||||
import { isBasicAuth } from './config';
|
||||
import {
|
||||
CHECK_AUTH_RESULT_EVENT,
|
||||
type CheckAuthResultEventType,
|
||||
} from './event';
|
||||
|
||||
const BASIC_AUTH_IS_AUTHENTICATED$ = of({
|
||||
isAuthenticated: true,
|
||||
allConfigsAuthenticated: [],
|
||||
});
|
||||
|
||||
const BASIC_AUTH_USER_DATA$ = of({
|
||||
userData: {},
|
||||
allUserData: [],
|
||||
});
|
||||
|
||||
export function useAuth() {
|
||||
const { oidcSecurityService, injector } = isBasicAuth
|
||||
? { oidcSecurityService: undefined, injector: InjectorContextVoidInjector }
|
||||
: // biome-ignore lint/correctness/useHookAtTopLevel: <explanation>
|
||||
useOidcClient();
|
||||
|
||||
const { isAuthenticated } = useObservableEagerState(
|
||||
oidcSecurityService?.isAuthenticated$ ?? BASIC_AUTH_IS_AUTHENTICATED$
|
||||
);
|
||||
|
||||
const { userData } = useObservableEagerState(
|
||||
oidcSecurityService?.userData$ ?? BASIC_AUTH_USER_DATA$
|
||||
);
|
||||
|
||||
const checkAuthResultEvent = useObservableState(
|
||||
useMemo(
|
||||
() => (isBasicAuth ? NEVER : injector.get(CHECK_AUTH_RESULT_EVENT)),
|
||||
[injector]
|
||||
) as Observable<CheckAuthResultEventType>
|
||||
);
|
||||
|
||||
return {
|
||||
oidcSecurityService,
|
||||
isAuthenticated,
|
||||
userData,
|
||||
injector,
|
||||
checkAuthResultEvent,
|
||||
};
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
use std::{borrow::Cow, error::Error as StdError};
|
||||
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum::{
|
||||
Json,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use http::StatusCode;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use thiserror::Error as ThisError;
|
||||
@ -105,11 +108,33 @@ impl RError {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone)]
|
||||
pub struct StandardErrorResponse<T = ()> {
|
||||
pub success: bool,
|
||||
pub message: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub result: Option<T>,
|
||||
}
|
||||
|
||||
impl<T> From<String> for StandardErrorResponse<T> {
|
||||
fn from(value: String) -> Self {
|
||||
StandardErrorResponse {
|
||||
success: false,
|
||||
message: value,
|
||||
result: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for RError {
|
||||
fn into_response(self) -> Response {
|
||||
match self {
|
||||
Self::AuthError(auth_error) => auth_error.into_response(),
|
||||
err => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response(),
|
||||
err => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json::<StandardErrorResponse>(StandardErrorResponse::from(err.to_string())),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use crate::{
|
||||
},
|
||||
fetch::{html::fetch_html, image::fetch_image},
|
||||
storage::StorageContentCategory,
|
||||
tasks::core::{StandardStreamTaskReplayLayout, StreamTaskRunnerTrait},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -349,24 +348,15 @@ pub async fn extract_mikan_bangumi_meta_from_bangumi_homepage(
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ExtractMikanBangumisMetaFromMyBangumiRequest {
|
||||
pub my_bangumi_page_url: Url,
|
||||
pub auth_securcy: Option<MikanAuthSecrecy>,
|
||||
}
|
||||
|
||||
pub type ExtractMikanBangumisMetaFromMyBangumiTask =
|
||||
StandardStreamTaskReplayLayout<ExtractMikanBangumisMetaFromMyBangumiRequest, MikanBangumiMeta>;
|
||||
|
||||
#[instrument(skip_all, fields(my_bangumi_page_url, auth_securcy = ?auth_securcy, history = history.len()))]
|
||||
#[instrument(skip_all, fields(my_bangumi_page_url, auth_secrecy = ?auth_secrecy, history = history.len()))]
|
||||
pub fn extract_mikan_bangumis_meta_from_my_bangumi_page(
|
||||
context: Arc<dyn AppContextTrait>,
|
||||
my_bangumi_page_url: Url,
|
||||
auth_securcy: Option<MikanAuthSecrecy>,
|
||||
auth_secrecy: Option<MikanAuthSecrecy>,
|
||||
history: &[Arc<RResult<MikanBangumiMeta>>],
|
||||
) -> impl Stream<Item = RResult<MikanBangumiMeta>> {
|
||||
try_stream! {
|
||||
let http_client = &context.mikan().fork_with_auth(auth_securcy.clone())?;
|
||||
let http_client = &context.mikan().fork_with_auth(auth_secrecy.clone())?;
|
||||
|
||||
let mikan_base_url = Url::parse(&my_bangumi_page_url.origin().unicode_serialization())?;
|
||||
|
||||
@ -498,22 +488,6 @@ pub fn extract_mikan_bangumis_meta_from_my_bangumi_page(
|
||||
}
|
||||
}
|
||||
|
||||
impl StreamTaskRunnerTrait for ExtractMikanBangumisMetaFromMyBangumiTask {
|
||||
fn run(
|
||||
context: Arc<dyn AppContextTrait>,
|
||||
request: &Self::Request,
|
||||
history: &[Arc<RResult<Self::Item>>],
|
||||
) -> impl Stream<Item = RResult<Self::Item>> {
|
||||
let context = context.clone();
|
||||
extract_mikan_bangumis_meta_from_my_bangumi_page(
|
||||
context,
|
||||
request.my_bangumi_page_url.clone(),
|
||||
request.auth_securcy.clone(),
|
||||
history,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#![allow(unused_variables)]
|
||||
|
@ -1,38 +0,0 @@
|
||||
// use std::borrow::Cow;
|
||||
|
||||
// use futures::{TryStreamExt, pin_mut};
|
||||
|
||||
// use crate::{
|
||||
// app::AppContextTrait,
|
||||
// errors::RResult,
|
||||
// extract::mikan::{
|
||||
// MikanAuthSecrecy,
|
||||
// web_extract::extract_mikan_bangumis_meta_from_my_bangumi_page, },
|
||||
// tasks::core::{StreamTaskTrait, TaskVars},
|
||||
// };
|
||||
|
||||
// #[derive(Debug)]
|
||||
// pub struct CreateMikanRSSFromMyBangumiTask {
|
||||
// pub subscriber_id: i32,
|
||||
// pub task_id: String,
|
||||
// pub auth_secrecy: MikanAuthSecrecy,
|
||||
// }
|
||||
|
||||
// async fn run(app_context: &dyn AppContextTrait, _vars: &TaskVars) ->
|
||||
// RResult<()> { let mikan_client = app_context
|
||||
// .mikan
|
||||
// .fork_with_auth(todo!().auth_secrecy.clone())?;
|
||||
|
||||
// {
|
||||
// let bangumi_metas = extract_mikan_bangumis_meta_from_my_bangumi_page(
|
||||
// &mikan_client,
|
||||
// mikan_client.base_url().join("/Home/MyBangumi")?,
|
||||
// );
|
||||
|
||||
// pin_mut!(bangumi_metas);
|
||||
|
||||
// let _bangumi_metas = bangumi_metas.try_collect::<Vec<_>>().await?;
|
||||
// }
|
||||
|
||||
// Ok(())
|
||||
// }
|
@ -0,0 +1,37 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::Stream;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
app::AppContextTrait,
|
||||
errors::RResult,
|
||||
extract::mikan::{MikanAuthSecrecy, MikanBangumiMeta, web_extract},
|
||||
tasks::core::{StandardStreamTaskReplayLayout, StreamTaskRunnerTrait},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ExtractMikanBangumisMetaFromMyBangumiRequest {
|
||||
pub my_bangumi_page_url: Url,
|
||||
pub auth_secrecy: Option<MikanAuthSecrecy>,
|
||||
}
|
||||
|
||||
pub type ExtractMikanBangumisMetaFromMyBangumiTask =
|
||||
StandardStreamTaskReplayLayout<ExtractMikanBangumisMetaFromMyBangumiRequest, MikanBangumiMeta>;
|
||||
|
||||
impl StreamTaskRunnerTrait for ExtractMikanBangumisMetaFromMyBangumiTask {
|
||||
fn run(
|
||||
context: Arc<dyn AppContextTrait>,
|
||||
request: &Self::Request,
|
||||
history: &[Arc<RResult<Self::Item>>],
|
||||
) -> impl Stream<Item = RResult<Self::Item>> {
|
||||
let context = context.clone();
|
||||
web_extract::extract_mikan_bangumis_meta_from_my_bangumi_page(
|
||||
context,
|
||||
request.my_bangumi_page_url.clone(),
|
||||
request.auth_secrecy.clone(),
|
||||
history,
|
||||
)
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
pub mod create_mikan_bangumi_subscriptions_from_my_bangumi_page;
|
||||
pub mod extract_mikan_bangumis_meta_from_my_bangumi;
|
||||
|
@ -1 +1,4 @@
|
||||
#[derive(Debug)]
|
||||
pub struct TaskService {}
|
||||
|
||||
impl TaskService {}
|
||||
|
40
apps/recorder/src/web/controller/metadata/mod.rs
Normal file
40
apps/recorder/src/web/controller/metadata/mod.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{Json, Router, extract::State, routing::get};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{app::AppContextTrait, errors::RResult, web::controller::Controller};
|
||||
|
||||
pub const CONTROLLER_PREFIX: &str = "/api/metadata";
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct StandardResponse {
|
||||
pub success: bool,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
async fn health(State(ctx): State<Arc<dyn AppContextTrait>>) -> RResult<Json<StandardResponse>> {
|
||||
ctx.db().ping().await.inspect_err(
|
||||
|err| tracing::error!(err.msg = %err, err.detail = ?err, "health check database ping error"),
|
||||
)?;
|
||||
|
||||
Ok(Json(StandardResponse {
|
||||
success: true,
|
||||
message: "ok".to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
async fn ping() -> Json<StandardResponse> {
|
||||
Json(StandardResponse {
|
||||
success: true,
|
||||
message: "ok".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn create(_context: Arc<dyn AppContextTrait>) -> RResult<Controller> {
|
||||
let router = Router::<Arc<dyn AppContextTrait>>::new()
|
||||
.route("/health", get(health))
|
||||
.route("/ping", get(ping));
|
||||
|
||||
Ok(Controller::from_prefix(CONTROLLER_PREFIX, router))
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
pub mod core;
|
||||
pub mod graphql;
|
||||
pub mod metadata;
|
||||
pub mod oidc;
|
||||
|
||||
pub use core::{Controller, ControllerTrait, PrefixController};
|
||||
|
1
apps/recorder/temp/clippy/rustrover/.rustc_info.json
Normal file
1
apps/recorder/temp/clippy/rustrover/.rustc_info.json
Normal file
@ -0,0 +1 @@
|
||||
{"rustc_fingerprint":12631718921104437280,"outputs":{"9566862992471862046":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\code\\scoop\\persist\\rustup\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\nfmt_debug=\"full\"\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"lahfsahf\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"x87\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"pc\"\nub_checks\nwindows\n","stderr":""},"5537925964935398022":{"success":true,"status":"","code":0,"stdout":"rustc 1.86.0-nightly (43ca9d18e 2025-02-08)\nbinary: rustc\ncommit-hash: 43ca9d18e333797f0aa3b525501a7cec8d61a96b\ncommit-date: 2025-02-08\nhost: x86_64-pc-windows-msvc\nrelease: 1.86.0-nightly\nLLVM version: 19.1.7\n","stderr":""}},"successes":{}}
|
3
apps/recorder/temp/clippy/rustrover/CACHEDIR.TAG
Normal file
3
apps/recorder/temp/clippy/rustrover/CACHEDIR.TAG
Normal file
@ -0,0 +1,3 @@
|
||||
Signature: 8a477f597d28d172789f06886806bc55
|
||||
# This file is a cache directory tag created by cargo.
|
||||
# For information about cache directory tags see https://bford.info/cachedir/
|
13
apps/webui/.env
Normal file
13
apps/webui/.env
Normal file
@ -0,0 +1,13 @@
|
||||
HOST="konobangu.com"
|
||||
DATABASE_URL = "postgres://konobangu:konobangu@localhost:5432/konobangu"
|
||||
STORAGE_DATA_DIR = "./data"
|
||||
AUTH_TYPE = "basic" # or oidc
|
||||
BASIC_USER = "konobangu"
|
||||
BASIC_PASSWORD = "konobangu"
|
||||
# OIDC_ISSUER="https://auth.logto.io/oidc"
|
||||
# OIDC_API_AUDIENCE = "https://konobangu.com/api"
|
||||
# OIDC_CLIENT_ID = "client_id"
|
||||
# OIDC_CLIENT_SECRET = "client_secret" # optional
|
||||
# OIDC_EXTRA_SCOPES = "read:konobangu write:konobangu"
|
||||
# OIDC_EXTRA_CLAIM_KEY = ""
|
||||
# OIDC_EXTRA_CLAIM_VALUE = ""
|
1
apps/webui/public/assets/favicon.webp
Symbolic link
1
apps/webui/public/assets/favicon.webp
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../assets/favicon.webp
|
@ -1,4 +1,4 @@
|
||||
import { Image } from '@kobalte/core/image';
|
||||
import {Image} from '@kobalte/core/image';
|
||||
import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
@ -13,13 +13,14 @@ export function AppIcon() {
|
||||
size="lg"
|
||||
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<div
|
||||
class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<Image fallbackDelay={1000}>
|
||||
<Image.Img
|
||||
src="/assets/favicon.png"
|
||||
class="size-8 object-cover"
|
||||
/>
|
||||
<Image.Fallback>KONOBANGU</Image.Fallback>
|
||||
<Image.Fallback>KO</Image.Fallback>
|
||||
</Image>
|
||||
</div>
|
||||
<div class="grid flex-1 gap-1 py-1 text-left text-sm leading-tight">
|
||||
|
110
bacon.toml
110
bacon.toml
@ -1,116 +1,10 @@
|
||||
# This is a configuration file for the bacon tool
|
||||
#
|
||||
# Complete help on configuration: https://dystroy.org/bacon/config/
|
||||
#
|
||||
# You may check the current default at
|
||||
# https://github.com/Canop/bacon/blob/main/defaults/default-bacon.toml
|
||||
|
||||
default_job = "check"
|
||||
env.CARGO_TERM_COLOR = "always"
|
||||
|
||||
[jobs.recorder]
|
||||
command = ["cargo", "recorder"]
|
||||
command = ["cargo", "run", "-p", "recorder", "--bin", "recorder_cli", "--", "--environment", "development"]
|
||||
watch = ["apps/recorder"]
|
||||
need_stdout = true
|
||||
|
||||
[jobs.check]
|
||||
command = ["cargo", "check"]
|
||||
need_stdout = false
|
||||
|
||||
[jobs.check-all]
|
||||
command = ["cargo", "check", "--all-targets"]
|
||||
need_stdout = false
|
||||
|
||||
# Run clippy on the default target
|
||||
[jobs.clippy]
|
||||
command = ["cargo", "clippy"]
|
||||
need_stdout = false
|
||||
|
||||
# Run clippy on all targets
|
||||
# To disable some lints, you may change the job this way:
|
||||
# [jobs.clippy-all]
|
||||
# command = [
|
||||
# "cargo", "clippy",
|
||||
# "--all-targets",
|
||||
# "--",
|
||||
# "-A", "clippy::bool_to_int_with_if",
|
||||
# "-A", "clippy::collapsible_if",
|
||||
# "-A", "clippy::derive_partial_eq_without_eq",
|
||||
# ]
|
||||
# need_stdout = false
|
||||
[jobs.clippy-all]
|
||||
command = ["cargo", "clippy", "--all-targets"]
|
||||
need_stdout = false
|
||||
|
||||
# This job lets you run
|
||||
# - all tests: bacon test
|
||||
# - a specific test: bacon test -- config::test_default_files
|
||||
# - the tests of a package: bacon test -- -- -p config
|
||||
[jobs.test]
|
||||
command = ["cargo", "test"]
|
||||
need_stdout = true
|
||||
|
||||
[jobs.nextest]
|
||||
command = [
|
||||
"cargo", "nextest", "run",
|
||||
"--hide-progress-bar", "--failure-output", "final"
|
||||
]
|
||||
need_stdout = true
|
||||
analyzer = "nextest"
|
||||
|
||||
[jobs.doc]
|
||||
command = ["cargo", "doc", "--no-deps"]
|
||||
need_stdout = false
|
||||
|
||||
# If the doc compiles, then it opens in your browser and bacon switches
|
||||
# to the previous job
|
||||
[jobs.doc-open]
|
||||
command = ["cargo", "doc", "--no-deps", "--open"]
|
||||
need_stdout = false
|
||||
on_success = "back" # so that we don't open the browser at each change
|
||||
|
||||
# You can run your application and have the result displayed in bacon,
|
||||
# if it makes sense for this crate.
|
||||
[jobs.run]
|
||||
command = [
|
||||
"cargo", "run",
|
||||
# put launch parameters for your program behind a `--` separator
|
||||
]
|
||||
need_stdout = true
|
||||
allow_warnings = true
|
||||
background = true
|
||||
|
||||
# Run your long-running application (eg server) and have the result displayed in bacon.
|
||||
# For programs that never stop (eg a server), `background` is set to false
|
||||
# to have the cargo run output immediately displayed instead of waiting for
|
||||
# program's end.
|
||||
# 'on_change_strategy' is set to `kill_then_restart` to have your program restart
|
||||
# on every change (an alternative would be to use the 'F5' key manually in bacon).
|
||||
# If you often use this job, it makes sense to override the 'r' key by adding
|
||||
# a binding `r = job:run-long` at the end of this file .
|
||||
[jobs.run-long]
|
||||
command = [
|
||||
"cargo", "run",
|
||||
# put launch parameters for your program behind a `--` separator
|
||||
]
|
||||
need_stdout = true
|
||||
allow_warnings = true
|
||||
background = false
|
||||
on_change_strategy = "kill_then_restart"
|
||||
|
||||
# This parameterized job runs the example of your choice, as soon
|
||||
# as the code compiles.
|
||||
# Call it as
|
||||
# bacon ex -- my-example
|
||||
[jobs.ex]
|
||||
command = ["cargo", "run", "--example"]
|
||||
need_stdout = true
|
||||
allow_warnings = true
|
||||
|
||||
# You may define here keybindings that would be specific to
|
||||
# a project, for example a shortcut to launch a specific job.
|
||||
# Shortcuts to internal functions (scrolling, toggling, etc.)
|
||||
# should go in your personal global prefs.toml file instead.
|
||||
[keybindings]
|
||||
# alt-m = "job:my-job"
|
||||
c = "job:clippy-all" # comment this to have 'c' run clippy on only the default target
|
||||
kill = ["kill", "-s", "INT"]
|
14
justfile
14
justfile
@ -1,16 +1,16 @@
|
||||
set windows-shell := ["pwsh.exe", "-c"]
|
||||
set dotenv-load
|
||||
set dotenv-load := true
|
||||
|
||||
prepare-dev-recorder:
|
||||
cargo install sea-orm-cli
|
||||
cargo install cargo-watch
|
||||
cargo install sea-orm-cli
|
||||
cargo install cargo-watch
|
||||
|
||||
dev-webui:
|
||||
pnpm run --filter=webui dev
|
||||
pnpm run --filter=webui dev
|
||||
|
||||
dev-proxy:
|
||||
pnpm run --filter=proxy dev
|
||||
pnpm run --filter=proxy dev
|
||||
|
||||
# bacon recorder # crash on windows
|
||||
dev-recorder:
|
||||
bacon recorder
|
||||
|
||||
cargo watch -w "apps/recorder" -x "run -p recorder --bin recorder_cli -- --environment development"
|
||||
|
@ -3,7 +3,10 @@
|
||||
"version": "0.0.0",
|
||||
"description": "Kono bangumi?",
|
||||
"license": "MIT",
|
||||
"workspaces": ["packages/*", "apps/*"],
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
"apps/*"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dumtruck/konobangu.git"
|
||||
@ -14,7 +17,7 @@
|
||||
"bump-deps": "npx --yes npm-check-updates --deep -u -x react-day-picker && pnpm install",
|
||||
"clean": "git clean -xdf node_modules"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.4",
|
||||
"packageManager": "pnpm@10.6.1",
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
@ -23,7 +26,6 @@
|
||||
"@auto-it/first-time-contributor": "^11.3.0",
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/node": "^22.13.8",
|
||||
"shx": "^0.3.4",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.8.2",
|
||||
"ultracite": "^4.1.15"
|
||||
|
85
pnpm-lock.yaml
generated
85
pnpm-lock.yaml
generated
@ -20,9 +20,6 @@ importers:
|
||||
'@types/node':
|
||||
specifier: ^22.13.8
|
||||
version: 22.13.8
|
||||
shx:
|
||||
specifier: ^0.3.4
|
||||
version: 0.3.4
|
||||
tsx:
|
||||
specifier: ^4.19.2
|
||||
version: 4.19.2
|
||||
@ -3138,9 +3135,6 @@ packages:
|
||||
bottleneck@2.19.5:
|
||||
resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==}
|
||||
|
||||
brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
|
||||
@ -3348,9 +3342,6 @@ packages:
|
||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
concat-stream@1.6.2:
|
||||
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
|
||||
engines: {'0': node >= 0.8}
|
||||
@ -3832,9 +3823,6 @@ packages:
|
||||
fs-extra2@1.0.1:
|
||||
resolution: {integrity: sha512-0/5G6ZVzzMwH3VbBrPSDoNKY4dT3jPWN7GqmFlqa407N6KyILEOdXepUzCH6uulSHIn0l7b+0z9sU+Ugjm8aAw==}
|
||||
|
||||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
@ -3912,10 +3900,6 @@ packages:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
hasBin: true
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
globals@11.12.0:
|
||||
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
||||
engines: {node: '>=4'}
|
||||
@ -4074,10 +4058,6 @@ packages:
|
||||
resolution: {integrity: sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
@ -4092,10 +4072,6 @@ packages:
|
||||
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
interpret@1.4.0:
|
||||
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
io-ts@2.2.22:
|
||||
resolution: {integrity: sha512-FHCCztTkHoV9mdBsHpocLpdTAfh956ZQcIkWQxxS0U5HT53vtrcuYdQneEJKH6xILaLNzXVl2Cvwtoy8XNN0AA==}
|
||||
peerDependencies:
|
||||
@ -4532,9 +4508,6 @@ packages:
|
||||
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
@ -5084,10 +5057,6 @@ packages:
|
||||
resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
|
||||
rechoir@0.6.2:
|
||||
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
reduce-configs@1.1.0:
|
||||
resolution: {integrity: sha512-DQxy6liNadHfrLahZR7lMdc227NYVaQZhY5FMsxLEjX8X0SCuH+ESHSLCoz2yDZFq1/CLMDOAHdsEHwOEXKtvg==}
|
||||
|
||||
@ -5302,16 +5271,6 @@ packages:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
shelljs@0.8.5:
|
||||
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
shx@0.3.4:
|
||||
resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
side-channel-list@1.0.0:
|
||||
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -9289,11 +9248,6 @@ snapshots:
|
||||
|
||||
bottleneck@2.19.5: {}
|
||||
|
||||
brace-expansion@1.1.11:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
@ -9501,8 +9455,6 @@ snapshots:
|
||||
|
||||
commander@4.1.1: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
concat-stream@1.6.2:
|
||||
dependencies:
|
||||
buffer-from: 1.1.2
|
||||
@ -10160,8 +10112,6 @@ snapshots:
|
||||
jsonfile: 2.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
@ -10257,15 +10207,6 @@ snapshots:
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
glob@7.2.3:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
|
||||
globals@11.12.0: {}
|
||||
|
||||
globalthis@1.0.4:
|
||||
@ -10426,11 +10367,6 @@ snapshots:
|
||||
dependencies:
|
||||
resolve-from: 5.0.0
|
||||
|
||||
inflight@1.0.6:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
ini@1.3.8: {}
|
||||
@ -10457,8 +10393,6 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
side-channel: 1.1.0
|
||||
|
||||
interpret@1.4.0: {}
|
||||
|
||||
io-ts@2.2.22(fp-ts@2.16.9):
|
||||
dependencies:
|
||||
fp-ts: 2.16.9
|
||||
@ -10852,10 +10786,6 @@ snapshots:
|
||||
|
||||
mimic-fn@2.1.0: {}
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
@ -11384,10 +11314,6 @@ snapshots:
|
||||
|
||||
readdirp@4.0.2: {}
|
||||
|
||||
rechoir@0.6.2:
|
||||
dependencies:
|
||||
resolve: 1.22.10
|
||||
|
||||
reduce-configs@1.1.0: {}
|
||||
|
||||
reflect.getprototypeof@1.0.10:
|
||||
@ -11681,17 +11607,6 @@ snapshots:
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
shelljs@0.8.5:
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
interpret: 1.4.0
|
||||
rechoir: 0.6.2
|
||||
|
||||
shx@0.3.4:
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
shelljs: 0.8.5
|
||||
|
||||
side-channel-list@1.0.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
@ -1,3 +1,9 @@
|
||||
packages:
|
||||
- "packages/*"
|
||||
- "apps/*"
|
||||
- packages/*
|
||||
- apps/*
|
||||
onlyBuiltDependencies:
|
||||
- '@biomejs/biome'
|
||||
- bufferutil
|
||||
- core-js
|
||||
- esbuild
|
||||
- sharp
|
||||
|
Loading…
Reference in New Issue
Block a user