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