From 794971eb2c0b87992630b5224681c5635b41caa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:22:13 -0300 Subject: [PATCH 1/6] fix: return original source when no inline styles are found When a .ts file has no inline `styles`, `node.root().nodes` is empty and the forEach loop never calls `builder`, producing an empty string. Stylelint then writes that empty string back to disk, erasing the file. The VS Code stylelint extension is particularly affected because it replaces the full document content unconditionally, whereas the CLI accidentally skips the write when `result.code` is falsy. Fix: when there are no nodes, call `builder` with the original source so the file is preserved unchanged. Closes #6 --- src/stringifier.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/stringifier.ts b/src/stringifier.ts index ecf5518..98e3fee 100644 --- a/src/stringifier.ts +++ b/src/stringifier.ts @@ -5,7 +5,16 @@ export const stringify = (node: AnyNode, builder) => { logger.info(`Stringify called.`); try { - node.root().nodes.forEach((node) => { + const nodes = node.root().nodes; + + if (nodes.length === 0) { + // No inline styles — return original source unchanged to prevent + // stylelint's fix mode from writing an empty string back to disk. + builder(node.source?.input?.css ?? ""); + return; + } + + nodes.forEach((node) => { builder(node.raws.angularCodeBefore, node); postcssStringify(node, builder); builder(node.raws.angularCodeAfter, node); From 491bd0283ab1c2a791ae51dcb082c5ebe16b65d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:26:53 -0300 Subject: [PATCH 2/6] fix: build dist/stringifier.js with the empty-nodes fix --- dist/stringifier.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dist/stringifier.js b/dist/stringifier.js index eae7383..18f8cb8 100644 --- a/dist/stringifier.js +++ b/dist/stringifier.js @@ -6,7 +6,14 @@ const logger_1 = require("./logger"); const stringify = (node, builder) => { logger_1.logger.info(`Stringify called.`); try { - node.root().nodes.forEach((node) => { + const nodes = node.root().nodes; + if (nodes.length === 0) { + // No inline styles — return original source unchanged to prevent + // stylelint's fix mode from writing an empty string back to disk. + builder(node.source?.input?.css ?? ""); + return; + } + nodes.forEach((node) => { builder(node.raws.angularCodeBefore, node); (0, postcss_1.stringify)(node, builder); builder(node.raws.angularCodeAfter, node); From 4b564b68d42778e23fe5dc8c8db843cf97a2e86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:37:47 -0300 Subject: [PATCH 3/6] fix(parser): store original source in raws.angularSource The Root document is created by parsing an empty string, so root.source.input.css is always "". The original TypeScript source was never stored on the PostCSS tree, making it impossible for the stringifier to return it unchanged when no inline styles are present. Store it in document.raws.angularSource so the stringifier can use it. --- src/parser.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/parser.ts b/src/parser.ts index 55887f1..fed0801 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,4 +1,4 @@ -import { ProcessOptions, Root, parse as postcssParse, Document } from "postcss"; +import { ProcessOptions, Root, parse as postcssParse } from "postcss"; import { getComponentStyles } from "./get-component-metadata"; import { logger } from "./logger"; @@ -10,6 +10,10 @@ export const parse = (source: string, opts: ProcessOptions): Root => { const document = postcssParse("", { from }); + // Store the original TypeScript source so the stringifier can return it + // unchanged when there are no inline styles to process. + document.raws.angularSource = sourceString; + try { const allStyles = getComponentStyles(sourceString, from); From 957a68b1f70edc323b11e82f670392cdcf5f8d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:37:55 -0300 Subject: [PATCH 4/6] fix(stringifier): use raws.angularSource when no inline styles found Previously the fallback used node.source?.input?.css which is always "" because the Root is created by parsing an empty string in the parser. Now reads root.raws.angularSource (set by the parser) to return the original TypeScript file content unchanged. --- src/stringifier.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/stringifier.ts b/src/stringifier.ts index 98e3fee..4e5c1b5 100644 --- a/src/stringifier.ts +++ b/src/stringifier.ts @@ -5,12 +5,13 @@ export const stringify = (node: AnyNode, builder) => { logger.info(`Stringify called.`); try { - const nodes = node.root().nodes; + const root = node.root(); + const nodes = root.nodes; if (nodes.length === 0) { - // No inline styles — return original source unchanged to prevent - // stylelint's fix mode from writing an empty string back to disk. - builder(node.source?.input?.css ?? ""); + // No inline styles — return the original TypeScript source unchanged to + // prevent stylelint's fix mode from writing an empty string back to disk. + builder(root.raws.angularSource ?? ""); return; } From 266bf6c5835f3e0a8caef8c67c09ceb05d63535c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:38:11 -0300 Subject: [PATCH 5/6] fix(dist/stringifier): use raws.angularSource when no inline styles found --- dist/stringifier.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/stringifier.js b/dist/stringifier.js index 18f8cb8..5aff570 100644 --- a/dist/stringifier.js +++ b/dist/stringifier.js @@ -6,11 +6,13 @@ const logger_1 = require("./logger"); const stringify = (node, builder) => { logger_1.logger.info(`Stringify called.`); try { - const nodes = node.root().nodes; + const root = node.root(); + const nodes = root.nodes; if (nodes.length === 0) { - // No inline styles — return original source unchanged to prevent - // stylelint's fix mode from writing an empty string back to disk. - builder(node.source?.input?.css ?? ""); + // No inline styles — return the original TypeScript source unchanged + // to prevent stylelint's fix mode from writing an empty string back + // to disk. + builder(root.raws.angularSource ?? ""); return; } nodes.forEach((node) => { From a4174fcee27954d2f9d9a46628d51a72a3898b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Masserano?= Date: Sun, 15 Mar 2026 20:38:40 -0300 Subject: [PATCH 6/6] fix(dist/parser): store original source in raws.angularSource --- dist/parser.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/parser.js b/dist/parser.js index 8814556..f11520d 100644 --- a/dist/parser.js +++ b/dist/parser.js @@ -9,6 +9,9 @@ const parse = (source, opts) => { const { from } = opts; logger_1.logger.info(`Parsing ${from}`); const document = (0, postcss_1.parse)("", { from }); + // Store the original TypeScript source so the stringifier can return it + // unchanged when there are no inline styles to process. + document.raws.angularSource = sourceString; try { const allStyles = (0, get_component_metadata_1.getComponentStyles)(sourceString, from); logger_1.logger.info(`Located ${allStyles.length} inline styles.`);