1use serde::Serialize;
9
10mod plugin_api;
11mod plugins;
12
13pub use plugin_api::*;
14pub use plugins::{built_in_omena_plugins, execute_built_in_omena_plugin};
15
16#[allow(deprecated)]
17pub use omena_bundler::{
18 BundleDependencyResolutionDisclosureV0, BundleResolutionAuthorityV0, EmissionOrderingPolicyV0,
19 InstanceReachabilityDerivationV0, LinkedEmissionArtifactV0,
20 LinkedEmissionItemMaterializationErrorV0, LinkedEmissionMaterializationErrorV0,
21 LinkedEmissionModuleRegionV0, LinkedEmissionOrderEntryRegionV0, LinkedStylesheetV0,
22 LinkedStylesheetWithEmissionItemsV0, TransformBundleAssetUrlRewriteSummaryV0,
23 TransformBundleDependencyResolutionV0, TransformBundleEdgeKind,
24 TransformBundleEmissionAdmissionV0, TransformBundleEmissionItemProjectionV0,
25 TransformBundleInstanceReachabilityInputV0, TransformBundleLinkErrorV0,
26 TransformBundleLinkOptionsV0, TransformBundleLinkProjectionSetV0,
27 TransformBundleLinkerProjectionV0, TransformBundleModuleInputV0,
28 TransformBundleParsedModuleInputV0, TransformBundleResolvedDependencyV0,
29 TransformBundleSemanticReachabilityInputV0, TransformBundleSourceSummaryV0,
30 TransformBundleTransformedModuleV0, bundle_edge_is_module_dependency,
31 evaluate_omena_transform_bundle_projection_emission_admission_with_resolved_dependencies_and_options,
32 link_legacy_path_inferred_bundle, link_omena_transform_bundle_modules,
33 link_omena_transform_bundle_modules_with_options,
34 link_omena_transform_bundle_modules_with_semantic_reachability,
35 link_omena_transform_bundle_modules_with_semantic_reachability_and_metadata,
36 link_omena_transform_bundle_projection_with_emission_items_and_resolved_dependencies_and_options,
37 link_omena_transform_bundle_projection_with_resolved_dependencies_and_options,
38 link_resolved_bundle, materialize_omena_transform_bundle_linked_stylesheet,
39 materialize_omena_transform_bundle_linked_stylesheet_with_emission_items,
40 normalize_omena_transform_bundle_path,
41 project_omena_transform_bundle_linker_and_emission_items,
42 project_omena_transform_bundle_linker_and_emission_items_from_parsed_modules,
43 project_omena_transform_bundle_linker_and_emission_items_from_parsed_modules_with_instance_reachability,
44 project_omena_transform_bundle_linker_inputs,
45 project_omena_transform_bundle_linker_inputs_from_parsed_modules,
46 rewrite_omena_transform_bundle_asset_urls_in_source,
47 summarize_omena_transform_bundle_from_source,
48};
49pub use omena_transform_cst::{
50 MinifyPassClassificationV0, MinifyPassProfileClassV0,
51 NATIVE_CSS_STATIC_EVAL_DIALECT_RESTRICTION_V0, NATIVE_CSS_STATIC_EVAL_OPT_IN_POLICY_V0,
52 NATIVE_CSS_STATIC_EVAL_SPEC_SNAPSHOT_V0, STRICT_VERIFICATION_BUILD_PROFILE_ID_V0,
53 TRANSFORM_PASS_CATALOG_LEN, TransformBuildProfileV0, TransformPassKind,
54 TransformStrictPolicyDescriptorV0, all_transform_pass_kinds, closed_world_minify_build_profile,
55 default_minify_build_profiles, default_minify_pass_classifications, safe_minify_build_profile,
56 semantic_minify_build_profile, strict_policy_descriptor_for_profile,
57 strict_verification_build_profile, transform_pass_requires_closed_world_bundle,
58 transform_pass_sort_ordinal, with_transform_pass_sort_ordinal_overrides_for_test,
59};
60pub use omena_transform_egg::{
61 EggRewriteSourceWitnessV0, TransformEggPlanV0, execute_egg_rewrite_witnesses_for_css_source,
62 plan_egg_rewrite_passes_for_source,
63};
64pub use omena_transform_passes::{
65 CssModuleTokenCollisionPathScopeV0, CssModuleTokenCollisionV0,
66 CssModuleTokenInterfaceMismatchV0, CssModuleTokenOwnershipCensusV0, CssModuleTokenOwnershipV0,
67 CustomPropertyLeastFixedPointSummaryV0, ExternalCssSemanticChangeClassificationV0,
68 ExternalCssSemanticChangeKindV0, ExternalCssSemanticChangeV0, ExternalCssSemanticDiffV0,
69 ExternalCssSemanticEntryV0, RollbackReceiptV0, RollbackScopeV0,
70 TransformCascadeEnvironmentDeclarationV0, TransformCascadeEnvironmentV0,
71 TransformClassNameRewriteV0, TransformCssModuleComposesResolutionV0,
72 TransformCssModuleValueResolutionV0, TransformDecision, TransformDesignTokenRouteV0,
73 TransformExecutionContextV0, TransformExecutionPolicyV0, TransformExecutionSummaryV0,
74 TransformImportInlineV0, TransformLessInlineLiteralPlaceholderV0,
75 TransformModuleCssModuleContextV0, TransformModuleEvaluationNativeEditV0,
76 TransformModuleEvaluationNativeReplacementV0, TransformModuleEvaluationOracleV0,
77 TransformModuleEvaluationV0, TransformModuleQualifiedExecutionErrorV0,
78 TransformModuleQualifiedShakeSummaryV0, TransformPassExecutionOutcomeV0, TransformPassPlanV0,
79 TransformSemanticGuaranteeTierV0, TransformSemanticPreservationDecisionV0,
80 TransformStrictPolicyEventV0, TransformStrictPolicyReasonV0, TransformStrictPolicySummaryV0,
81 TransformVendorPrefixPolicyV0, TransformWinnerEqualityAbsenceReasonV0,
82 TransformWinnerEqualityAbsenceV0, TransformWinnerEqualityAxisV0,
83 classify_transform_reachability_precision, compare_external_css_semantic_changes_v0,
84 compare_transform_css_semantics_v0,
85 execute_transform_passes_on_module_with_dialect_context_and_closed_world_bundle,
86 execute_transform_passes_on_module_with_dialect_context_policy_and_closed_world_bundle,
87 execute_transform_passes_on_module_with_dialect_context_policy_and_closed_world_bundle_and_retained_class_names,
88 execute_transform_passes_on_source_with_dialect_and_context,
89 execute_transform_passes_on_source_with_dialect_context_and_closed_world_bundle,
90 execute_transform_passes_on_source_with_dialect_context_and_policy,
91 execute_transform_passes_on_source_with_dialect_context_closed_world_bundle_and_precision,
92 execute_transform_passes_on_source_with_dialect_context_closed_world_bundle_precision_and_policy,
93 expand_css_nested_selector, external_css_semantic_diff_is_total_v0, inline_css_imports,
94 inline_css_imports_for_static_module_evaluation, parse_static_css_cascade_value,
95 plan_transform_passes, reduce_static_numeric_expression,
96 resolve_static_css_modules_local_value_resolutions_from_source,
97 restore_less_inline_literal_placeholders,
98 summarize_static_css_custom_property_fixed_point_from_source,
99};
100#[cfg(feature = "transform-catalog-trace")]
104#[allow(deprecated)]
105#[deprecated(
106 since = "0.4.0",
107 note = "use the TransformCatalog trace surface; removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
108)]
109pub use omena_transform_passes::{
110 LawvereDifferentialCommutativityWitnessV0, LawvereModelTraceV0, TransformPassParallelPlanV0,
111 evaluate_lawvere_reorderability_with_differential_corpus,
112 execute_transform_passes_on_source_with_lawvere_trace_and_dialect,
113 plan_transform_passes_parallel_lawvere_layers,
114};
115#[cfg(feature = "transform-catalog-trace")]
116pub use omena_transform_passes::{
117 ReorderabilityCertificateV0, TransformCatalogDifferentialCommutativityWitnessV0,
118 TransformCatalogModelTraceV0, TransformCatalogTransformPassParallelPlanV0,
119 evaluate_transform_catalog_reorderability_with_differential_corpus,
120 execute_transform_passes_on_source_with_transform_catalog_trace_and_dialect,
121 plan_transform_passes_parallel_transform_catalog_layers,
122};
123pub use omena_transform_print::{
124 PrettyFormatOptionsV0, StyleDialect, TransformPrintArtifactV0, TransformPrintMode,
125 TransformPrintOptionsV0, TransformSourceMapCompositionV0, TransformSourceMapPointV0,
126 TransformSourceMapSegmentV0, TransformSourceMapV3V0,
127 compose_transform_source_map_v3_with_upstream_map, default_print_options,
128 print_transform_cst_source_with_dialect_and_pretty_options,
129 print_transform_execution_artifact_with_dialect_and_source, serialize_transform_source_map_v3,
130 serialize_transform_source_map_v3_with_source_contents, transform_source_map_point,
131};
132pub use omena_transform_target::{
133 TargetFeatureSupportV0, TargetTransformOptionsV0, TransformTargetPlanV0,
134 TransformTargetQueryPlanV0, conservative_target_options, modern_feature_support,
135 plan_target_transforms, plan_target_transforms_from_query,
136};
137
138pub const OMENA_QUERY_TRANSFORM_RUNNER_COLLAPSED_CRATES_V0: [&str; 6] = [
139 "omena-bundler",
140 "omena-transform-cst",
141 "omena-transform-egg",
142 "omena-transform-passes",
143 "omena-transform-print",
144 "omena-transform-target",
145];
146
147pub fn materialize_transform_module_evaluation_native_edits(
148 input_css: &str,
149 native_edits: &[TransformModuleEvaluationNativeEditV0],
150) -> Option<String> {
151 if native_edits.is_empty() {
152 return None;
153 }
154
155 let mut edits = native_edits.to_vec();
156 edits.sort_by_key(|edit| edit.start);
157
158 let mut previous_end = 0usize;
159 for edit in &edits {
160 if edit.start < previous_end
161 || edit.start > edit.end
162 || edit.end > input_css.len()
163 || !input_css.is_char_boundary(edit.start)
164 || !input_css.is_char_boundary(edit.end)
165 {
166 return None;
167 }
168 previous_end = edit.end;
169 }
170
171 let mut output = input_css.to_string();
172 for edit in edits.iter().rev() {
173 output.replace_range(edit.start..edit.end, edit.replacement.as_str());
174 }
175 Some(output)
176}
177
178#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
179#[serde(rename_all = "camelCase")]
180pub struct OmenaQueryTransformRunnerBoundaryV0 {
181 pub schema_version: &'static str,
182 pub product: &'static str,
183 pub boundary_kind: &'static str,
184 pub collapsed_transform_crate_count: usize,
185 pub collapsed_transform_crates: Vec<&'static str>,
186 pub direct_query_dependency_replacement: &'static str,
187 pub ready_surfaces: Vec<&'static str>,
188}
189
190pub fn summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0()
191-> OmenaQueryTransformRunnerBoundaryV0 {
192 let ready_surfaces = vec![
193 "transformPlannerBoundary",
194 "transformExecutorBoundary",
195 "transformPrinterBoundary",
196 "transformSourceMapV3SerializerBoundary",
197 "transformTargetPlannerBoundary",
198 "transformEggWitnessBoundary",
199 ];
200 #[cfg(feature = "transform-catalog-trace")]
201 let mut ready_surfaces = ready_surfaces;
202 #[cfg(feature = "transform-catalog-trace")]
203 ready_surfaces.push("transformCatalogTraceBoundary");
204
205 OmenaQueryTransformRunnerBoundaryV0 {
206 schema_version: "0",
207 product: "omena-query-transform-runner.boundary",
208 boundary_kind: "query-transform-runner-split",
209 collapsed_transform_crate_count: OMENA_QUERY_TRANSFORM_RUNNER_COLLAPSED_CRATES_V0.len(),
210 collapsed_transform_crates: OMENA_QUERY_TRANSFORM_RUNNER_COLLAPSED_CRATES_V0.to_vec(),
211 direct_query_dependency_replacement: "omena-query-transform-runner",
212 ready_surfaces,
213 }
214}
215
216#[deprecated(
217 since = "0.4.0",
218 note = "use summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0; removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
219)]
220pub fn summarize_omena_query_transform_runner_boundary_v0() -> OmenaQueryTransformRunnerBoundaryV0 {
221 #[cfg(feature = "transform-catalog-trace")]
222 let mut summary = summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0();
223 #[cfg(not(feature = "transform-catalog-trace"))]
224 let summary = summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0();
225 #[cfg(feature = "transform-catalog-trace")]
226 if let Some(surface) = summary
227 .ready_surfaces
228 .iter_mut()
229 .find(|surface| **surface == "transformCatalogTraceBoundary")
230 {
231 *surface = "transformLawvereTraceBoundary";
232 }
233 summary
234}
235
236#[cfg(test)]
237mod tests {
238 use super::*;
239
240 #[cfg(feature = "transform-catalog-trace")]
245 #[deprecated(
246 since = "0.4.0",
247 note = "compatibility projection; removal is not before 1.0 and requires downstream migration plus zero audited non-compatibility uses"
248 )]
249 const COMPATIBILITY_TRANSFORM_RUNNER_BOUNDARY_JSON_V0: &str = r#"{"schemaVersion":"0","product":"omena-query-transform-runner.boundary","boundaryKind":"query-transform-runner-split","collapsedTransformCrateCount":6,"collapsedTransformCrates":["omena-bundler","omena-transform-cst","omena-transform-egg","omena-transform-passes","omena-transform-print","omena-transform-target"],"directQueryDependencyReplacement":"omena-query-transform-runner","readySurfaces":["transformPlannerBoundary","transformExecutorBoundary","transformPrinterBoundary","transformSourceMapV3SerializerBoundary","transformTargetPlannerBoundary","transformEggWitnessBoundary","transformLawvereTraceBoundary"]}"#;
250
251 #[test]
252 fn transform_runner_boundary_collapses_transform_family_for_query() {
253 let summary = summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0();
254
255 assert_eq!(summary.collapsed_transform_crate_count, 6);
256 assert_eq!(
257 summary.collapsed_transform_crates,
258 OMENA_QUERY_TRANSFORM_RUNNER_COLLAPSED_CRATES_V0
259 );
260 assert!(
261 summary
262 .ready_surfaces
263 .contains(&"transformExecutorBoundary")
264 );
265 assert!(
266 summary
267 .ready_surfaces
268 .contains(&"transformTargetPlannerBoundary")
269 );
270 }
271
272 #[cfg(feature = "transform-catalog-trace")]
273 #[test]
274 #[allow(deprecated)]
275 fn transform_runner_boundary_preserves_legacy_and_canonical_serialized_projections()
276 -> Result<(), serde_json::Error> {
277 let legacy = serde_json::to_string(&summarize_omena_query_transform_runner_boundary_v0())?;
278 let canonical = serde_json::to_string(
279 &summarize_omena_query_transform_runner_boundary_with_transform_catalog_v0(),
280 )?;
281
282 assert_eq!(legacy, COMPATIBILITY_TRANSFORM_RUNNER_BOUNDARY_JSON_V0);
283 assert_eq!(
284 canonical,
285 r#"{"schemaVersion":"0","product":"omena-query-transform-runner.boundary","boundaryKind":"query-transform-runner-split","collapsedTransformCrateCount":6,"collapsedTransformCrates":["omena-bundler","omena-transform-cst","omena-transform-egg","omena-transform-passes","omena-transform-print","omena-transform-target"],"directQueryDependencyReplacement":"omena-query-transform-runner","readySurfaces":["transformPlannerBoundary","transformExecutorBoundary","transformPrinterBoundary","transformSourceMapV3SerializerBoundary","transformTargetPlannerBoundary","transformEggWitnessBoundary","transformCatalogTraceBoundary"]}"#
286 );
287
288 Ok(())
289 }
290
291 #[test]
292 fn transform_runner_materializes_sorted_native_edits() {
293 let input_css = ".button { color: red; margin: 1px; }";
294 let color_start = input_css.find("red").unwrap_or(input_css.len());
295 let margin_start = input_css.find("1px").unwrap_or(input_css.len());
296
297 let output = materialize_transform_module_evaluation_native_edits(
298 input_css,
299 &[
300 TransformModuleEvaluationNativeEditV0 {
301 start: margin_start,
302 end: margin_start + "1px".len(),
303 replacement: "2px".to_string(),
304 edit_kind: "value".to_string(),
305 abstract_value: None,
306 abstract_value_kind: None,
307 },
308 TransformModuleEvaluationNativeEditV0 {
309 start: color_start,
310 end: color_start + "red".len(),
311 replacement: "blue".to_string(),
312 edit_kind: "value".to_string(),
313 abstract_value: None,
314 abstract_value_kind: None,
315 },
316 ],
317 );
318
319 assert_eq!(
320 output.as_deref(),
321 Some(".button { color: blue; margin: 2px; }")
322 );
323 }
324
325 #[test]
326 fn transform_runner_rejects_overlapping_native_edits() {
327 let output = materialize_transform_module_evaluation_native_edits(
328 "abcdef",
329 &[
330 TransformModuleEvaluationNativeEditV0 {
331 start: 1,
332 end: 4,
333 replacement: "x".to_string(),
334 edit_kind: "value".to_string(),
335 abstract_value: None,
336 abstract_value_kind: None,
337 },
338 TransformModuleEvaluationNativeEditV0 {
339 start: 3,
340 end: 5,
341 replacement: "y".to_string(),
342 edit_kind: "value".to_string(),
343 abstract_value: None,
344 abstract_value_kind: None,
345 },
346 ],
347 );
348
349 assert_eq!(output, None);
350 }
351}