diff --git a/core.wasi-browser.js b/core.wasi-browser.js index 0b93b31..fc00bf1 100644 --- a/core.wasi-browser.js +++ b/core.wasi-browser.js @@ -58,4 +58,5 @@ const { export default __napiModule.exports export const TransformKind = __napiModule.exports.TransformKind export const Nephrit = __napiModule.exports.Nephrit +export const JsNephrit = __napiModule.exports.JsNephrit export const NephritLogLevel = __napiModule.exports.NephritLogLevel diff --git a/core.wasi.cjs b/core.wasi.cjs index 971a28a..dc61d2d 100644 --- a/core.wasi.cjs +++ b/core.wasi.cjs @@ -110,4 +110,5 @@ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule module.exports = __napiModule.exports module.exports.TransformKind = __napiModule.exports.TransformKind module.exports.Nephrit = __napiModule.exports.Nephrit +module.exports.JsNephrit = __napiModule.exports.JsNephrit module.exports.NephritLogLevel = __napiModule.exports.NephritLogLevel diff --git a/crates/bindings/src/parser.rs b/crates/bindings/src/parser.rs index 3591350..f631e4b 100644 --- a/crates/bindings/src/parser.rs +++ b/crates/bindings/src/parser.rs @@ -8,12 +8,6 @@ pub struct TokenFile { pub content: String, } -#[derive(Clone, Debug)] -pub struct ParsedFile { - pub path: String, - pub content: serde_json::Value, -} - #[napi(object)] #[derive(Clone)] pub struct Parser<'parser> { diff --git a/crates/bindings/src/token.rs b/crates/bindings/src/token.rs index dfc006a..331e080 100644 --- a/crates/bindings/src/token.rs +++ b/crates/bindings/src/token.rs @@ -18,6 +18,38 @@ pub struct ResolvedToken { pub file_path: String, } +impl ResolvedToken { + fn to_transformed_token(&self) -> TransformedToken { + let formatted_value = match &self.value { + serde_json::Value::String(s) => s.clone(), + _ => self.value.to_string(), + }; + + TransformedToken { + key: self.key.clone(), + value: formatted_value, + file_path: self.file_path.clone(), + is_source: true, + original: self.original_value.clone(), + name: self.name.clone(), + attributes: TokenAttrs::from_path(&self.path), + path: self.path.clone(), + } + } +} + +impl Into for ResolvedToken { + fn into(self) -> TransformedToken { + self.to_transformed_token() + } +} + +impl From<&ResolvedToken> for TransformedToken { + fn from(resolved_token: &ResolvedToken) -> Self { + resolved_token.to_transformed_token() + } +} + #[napi(object)] #[derive(Debug, Clone, serde::Serialize)] pub struct TokenAttrs { @@ -54,23 +86,3 @@ pub struct TransformedToken { pub attributes: TokenAttrs, pub path: Vec, } - -impl TransformedToken { - pub fn from_resolved_token(resolved_token: &ResolvedToken) -> Self { - let formatted_value = match &resolved_token.value { - serde_json::Value::String(s) => s.clone(), - _ => resolved_token.value.to_string(), - }; - - Self { - key: resolved_token.key.clone(), - value: formatted_value, - file_path: resolved_token.file_path.clone(), - is_source: true, - original: resolved_token.original_value.clone(), - name: resolved_token.name.clone(), - attributes: TokenAttrs::from_path(&resolved_token.path), - path: resolved_token.path.clone(), - } - } -} diff --git a/crates/builtin/Cargo.toml b/crates/builtin/Cargo.toml new file mode 100644 index 0000000..247dfb3 --- /dev/null +++ b/crates/builtin/Cargo.toml @@ -0,0 +1,10 @@ +[package] +edition = "2021" +license = "MIT" +name = "builtin" +repository = "https://github.com/pmqueiroz/nephrit.git" +version = "0.1.0" + +[dependencies] +bindings = { path = "../bindings" } +log = { path = "../log" } diff --git a/crates/builtin/src/lib.rs b/crates/builtin/src/lib.rs new file mode 100644 index 0000000..0ba0ffb --- /dev/null +++ b/crates/builtin/src/lib.rs @@ -0,0 +1,3 @@ +mod transformers; + +pub use transformers::*; diff --git a/crates/builtin/src/transformers/interfaces/mod.rs b/crates/builtin/src/transformers/interfaces/mod.rs new file mode 100644 index 0000000..e94894b --- /dev/null +++ b/crates/builtin/src/transformers/interfaces/mod.rs @@ -0,0 +1,7 @@ +use bindings::token::TransformedToken; + +pub trait BuiltinTransformer { + fn transform(&self, token: &TransformedToken) -> TransformedToken; + + fn name(&self) -> String; +} diff --git a/crates/builtin/src/transformers/mod.rs b/crates/builtin/src/transformers/mod.rs new file mode 100644 index 0000000..511070b --- /dev/null +++ b/crates/builtin/src/transformers/mod.rs @@ -0,0 +1,11 @@ +mod interfaces; +mod name_kebab; + +pub use interfaces::BuiltinTransformer; +pub use name_kebab::NAME_KEBAB_TRANSFORMER; + +const TRANSFORMERS: &[&dyn BuiltinTransformer] = &[&NAME_KEBAB_TRANSFORMER]; + +pub fn get_transformers() -> &'static [&'static dyn BuiltinTransformer] { + TRANSFORMERS +} diff --git a/crates/builtin/src/transformers/name_kebab.rs b/crates/builtin/src/transformers/name_kebab.rs new file mode 100644 index 0000000..b3121dd --- /dev/null +++ b/crates/builtin/src/transformers/name_kebab.rs @@ -0,0 +1,35 @@ +use bindings::token::TransformedToken; + +pub struct NameKebab; + +impl super::interfaces::BuiltinTransformer for NameKebab { + fn transform(&self, token: &TransformedToken) -> TransformedToken { + let mut transformed = token.value.clone(); + transformed = transformed + .chars() + .map(|c| { + if c.is_uppercase() { + format!("-{}", c.to_lowercase()) + } else { + c.to_string() + } + }) + .collect::(); + let transformed = if transformed.starts_with('-') { + transformed.trim_start_matches('-').to_string() + } else { + transformed + }; + + TransformedToken { + value: transformed, + ..token.clone() + } + } + + fn name(&self) -> String { + "name/kebab".to_string() + } +} + +pub const NAME_KEBAB_TRANSFORMER: NameKebab = NameKebab {}; diff --git a/crates/kernel/Cargo.toml b/crates/kernel/Cargo.toml index f7353a5..a741cec 100644 --- a/crates/kernel/Cargo.toml +++ b/crates/kernel/Cargo.toml @@ -6,7 +6,7 @@ repository = "https://github.com/pmqueiroz/nephrit.git" version = "0.1.0" [dependencies] -bindings = { path = "../bindings" } +builtin = { path = "../builtin" } glob = "0.3.3" log = { path = "../log" } napi = "3.0.0" diff --git a/crates/kernel/src/build/transform_tokens.rs b/crates/kernel/src/build/transform_tokens.rs index b2e1bbc..897e21c 100644 --- a/crates/kernel/src/build/transform_tokens.rs +++ b/crates/kernel/src/build/transform_tokens.rs @@ -19,7 +19,7 @@ pub fn transform_tokens<'transforms>( if let Ok(filter_func) = transformer.filter.borrow_back(env) { let token_ref = match transformed_tokens.get(&token.key) { Some(t) => t.clone(), - None => TransformedToken::from_resolved_token(token), + None => token.into(), }; let bool_result = filter_func.call(token_ref.clone()); diff --git a/crates/kernel/src/interfaces/mod.rs b/crates/kernel/src/interfaces/mod.rs new file mode 100644 index 0000000..67c567f --- /dev/null +++ b/crates/kernel/src/interfaces/mod.rs @@ -0,0 +1 @@ +pub mod parser; diff --git a/crates/kernel/src/interfaces/parser.rs b/crates/kernel/src/interfaces/parser.rs new file mode 100644 index 0000000..c165c34 --- /dev/null +++ b/crates/kernel/src/interfaces/parser.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug)] +pub struct ParsedFile { + pub path: String, + pub content: serde_json::Value, +} diff --git a/crates/kernel/src/lib.rs b/crates/kernel/src/lib.rs index 3f7cdcf..1a2228e 100644 --- a/crates/kernel/src/lib.rs +++ b/crates/kernel/src/lib.rs @@ -1,9 +1,9 @@ -extern crate bindings; +extern crate builtin; extern crate log; extern crate napi; extern crate rayon; extern crate utils; -use bindings::parser::ParsedFile; +use interfaces::parser::ParsedFile; use napi::bindgen_prelude::Env; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; @@ -79,6 +79,8 @@ mod bucket; mod build; mod config; mod helpers; +mod interfaces; +pub mod nephrit; pub use bucket::TokensBucket; pub use build::{build, resolve_transformers}; diff --git a/crates/kernel/src/nephrit/mod.rs b/crates/kernel/src/nephrit/mod.rs new file mode 100644 index 0000000..67afbd1 --- /dev/null +++ b/crates/kernel/src/nephrit/mod.rs @@ -0,0 +1,68 @@ +mod transformers; + +use bindings::token::{TokenAttrs, TransformedToken}; +pub use transformers::*; + +use crate::Config; +use std::collections::HashMap; + +pub struct Nephrit<'env> { + config: Config<'env>, + transforms: HashMap, +} + +impl<'env> Nephrit<'env> { + pub fn new(config: Config<'env>) -> Self { + Self { + config, + transforms: HashMap::new(), + } + } + + pub fn get_config(&self) -> &Config<'env> { + &self.config + } + + pub fn register_transform(&mut self, name: String, transform: transformers::InternalTransformer) { + self.transforms.insert(name, transform); + } + + pub fn build(&self, transform: String) -> TransformedToken { + if let Some(transformer) = self.transforms.get(&transform) { + let transformer_func = (transformer.get_transformer)(); + + return transformer_func.call(TransformedToken { + name: "example_token".to_string(), + attributes: TokenAttrs { + _type: None, + category: None, + item: None, + subitem: None, + state: None, + }, + file_path: "path/to/file".to_string(), + is_source: true, + key: "example_key".to_string(), + original: serde_json::Value::Null, + path: vec![], + value: "example_value".to_string(), + }); + } + TransformedToken { + name: "".to_string(), + attributes: TokenAttrs { + _type: None, + category: None, + item: None, + subitem: None, + state: None, + }, + file_path: "".to_string(), + is_source: false, + key: "".to_string(), + original: serde_json::Value::Null, + path: vec![], + value: "".to_string(), + } + } +} diff --git a/crates/kernel/src/nephrit/transformers.rs b/crates/kernel/src/nephrit/transformers.rs new file mode 100644 index 0000000..21684fa --- /dev/null +++ b/crates/kernel/src/nephrit/transformers.rs @@ -0,0 +1,16 @@ +use bindings::token::TransformedToken; + +pub enum Kind { + Value, + Name, +} + +pub trait InternalTransformerCb { + fn call(&self, token: TransformedToken) -> TransformedToken; +} + +pub struct InternalTransformer { + pub name: String, + pub kind: Kind, + pub get_transformer: fn() -> Box, +} diff --git a/index.d.ts b/index.d.ts index e13f09f..ca60366 100644 --- a/index.d.ts +++ b/index.d.ts @@ -94,6 +94,7 @@ export declare class Nephrit { registerAction(action: Action): void registerFormat(format: Format): void } +export type JsNephrit = Nephrit export interface NephriteConfig { source: Array diff --git a/index.js b/index.js index 16c7b80..4ac4988 100644 --- a/index.js +++ b/index.js @@ -574,4 +574,5 @@ if (!nativeBinding) { module.exports = nativeBinding module.exports.TransformKind = nativeBinding.TransformKind module.exports.Nephrit = nativeBinding.Nephrit +module.exports.JsNephrit = nativeBinding.JsNephrit module.exports.NephritLogLevel = nativeBinding.NephritLogLevel diff --git a/lefthook.yml b/lefthook.yml index a3cd2e2..2efb8bf 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -7,7 +7,8 @@ pre-commit: parallel: true jobs: - run: pnpm exec biome check --write {staged_files} - glob: "*.{js,ts,jsx,tsx}" + glob: "*.{ts,jsx,tsx}" + include: ".releaserc.js" exclude: "*.d.ts" stage_fixed: true diff --git a/src/lib.rs b/src/lib.rs index 59e8ac5..7f36e54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,19 @@ #![deny(clippy::all)] mod log_level; use bindings::{ - action, parser, platform, transform, Actions, Format, Parsers, Platforms, RegisteredFormat, - RegisteredFormats, RegisteredTransforms, TransformGroups, + action, parser, platform, token::TransformedToken, transform, Actions, Format, Parsers, + Platforms, RegisteredFormat, RegisteredFormats, RegisteredTransforms, TransformGroups, }; -use kernel::{get_tokens_files, get_tokens_files_paths, Config, TokensBucket}; +use kernel::{get_tokens_files, get_tokens_files_paths, nephrit, Config, TokensBucket}; use log::Logger; use log_level::NephritLogLevel; use napi::bindgen_prelude::Env; use napi_derive::napi; use std::collections::HashMap; -#[napi] -pub struct Nephrit<'env> { - config: Config<'env>, +#[napi(js_name = "Nephrit")] +pub struct JsNephrit<'env> { + nephrit: nephrit::Nephrit<'env>, transforms: RegisteredTransforms, transform_groups: TransformGroups, parsers: Parsers, @@ -32,7 +32,7 @@ pub struct NephriteConfig<'platform> { } #[napi] -impl<'env> Nephrit<'env> { +impl<'env> JsNephrit<'env> { #[napi(constructor)] pub fn new(config: NephriteConfig<'env>) -> Self { Logger::init(NephritLogLevel::to_logger_log_level( @@ -46,11 +46,11 @@ impl<'env> Nephrit<'env> { } Self { - config: Config { - source: config.source, - cwd: config.cwd.map(std::path::PathBuf::from), - platforms: config.platforms, - }, + nephrit: nephrit::Nephrit::new(Config { + source: config.source.clone(), + cwd: config.cwd.as_ref().map(|p| std::path::PathBuf::from(p)), + platforms: config.platforms.clone(), + }), transforms: HashMap::new(), transform_groups: HashMap::new(), parsers: Vec::new(), @@ -113,19 +113,22 @@ impl<'env> Nephrit<'env> { collection, tokens_bucket, &self.formats, - &self.config, + &self.nephrit.get_config(), ); + // self + // .nephrit + // .build(self.transforms.keys().nth(0).unwrap().to_string()); } #[napi] - pub fn register_transform(&mut self, transform: transform::Transform) { + pub fn register_transform(&mut self, transform: transform::Transform, env: Env) { let name = transform.name.clone(); self.transforms.insert( transform.name.clone(), transform::RegisteredTransform { name: transform.name.clone(), kind: transform.kind.clone(), - transform: match transform.transform.create_ref() { + transform: match transform.clone().transform.create_ref() { Ok(transform) => transform, Err(e) => { Logger::error(&format!( @@ -148,6 +151,17 @@ impl<'env> Nephrit<'env> { }, ); + // let transform_for_closure = transform.clone(); + // self.nephrit.register_transform( + // transform.name.clone(), + // kernel::nephrit::InternalTransformer { + // name: transform.name.clone(), + // get_transformer: Box::new(move || { + // return func_ref.borrow_back(env); + // }), + // }, + // ); + Logger::debug(&format!("Registered transform: {}", name)); } @@ -214,12 +228,12 @@ impl<'env> Nephrit<'env> { } fn fetch_tokens_files(&self) -> Vec { - let cwd = match &self.config.cwd { + let cwd = match &self.nephrit.get_config().cwd { Some(path) => std::path::PathBuf::from(path), None => std::env::current_dir().unwrap(), }; - let path = get_tokens_files_paths(&cwd, self.config.source.clone()); + let path = get_tokens_files_paths(&cwd, self.nephrit.get_config().source.clone()); get_tokens_files(path) } } diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..bc4fc27 --- /dev/null +++ b/todo.md @@ -0,0 +1,40 @@ +## Internal transformers + +- [ ] asset/url +- [ ] attribute/color +- [ ] attribute/cti +- [ ] border/css/shorthand +- [ ] color/composeColor +- [ ] color/css +- [ ] color/hex +- [ ] color/hex8android +- [ ] color/hex8flutter +- [ ] color/UIColor +- [ ] color/UIColorSwift +- [ ] content/flutter/literal +- [ ] content/objC/literal +- [ ] content/swift/literal +- [ ] cubicBezier/css +- [ ] fontFamily/css +- [ ] globals +- [ ] html/icon +- [ ] name/camel +- [ ] name/human +- [x] name/kebab +- [ ] name/pascal +- [ ] name/snake +- [ ] shadow/css/shorthand +- [ ] size/compose/em +- [ ] size/compose/remToDp +- [ ] size/flutter/remToDouble +- [ ] size/object +- [ ] size/px +- [ ] size/rem +- [ ] size/remToDp +- [ ] size/remToPt +- [ ] size/remToSp +- [ ] size/swift/remToCGFloat +- [ ] strokeStyle/css/shorthand +- [ ] time/seconds +- [ ] transformer +- [ ] typography/css/shorthand"