cssupgrade 0.0.0-stage → 2026.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.claude-plugin/plugin.json +22 -0
  2. package/.editorconfig +27 -0
  3. package/.gitattributes +1 -0
  4. package/.github/agents/superjoe.agent.md +65 -0
  5. package/.github/copilot-instructions.md +32 -0
  6. package/.github/dependabot.yml +10 -0
  7. package/.github/workflows/ci.yml +35 -0
  8. package/.github/workflows/pr.yml +27 -0
  9. package/.github/workflows/release.yml +22 -0
  10. package/.idea/cssupgrade.iml +14 -0
  11. package/.idea/inspectionProfiles/Project_Default.xml +28 -0
  12. package/.idea/inspectionProfiles/profiles_settings.xml +6 -0
  13. package/.idea/misc.xml +4 -0
  14. package/.idea/modules.xml +8 -0
  15. package/.idea/vcs.xml +6 -0
  16. package/.oxfmtrc.json +3 -0
  17. package/.pre-commit-config.yaml +52 -0
  18. package/.pre-commit-hooks.yaml +8 -0
  19. package/AGENTS.md +54 -0
  20. package/CONTRIBUTING.md +40 -0
  21. package/LICENSE +24 -0
  22. package/README.md +173 -2
  23. package/bin/cssupgrade.js +320 -0
  24. package/images/logo-dark.svg +10 -0
  25. package/images/logo-light.svg +10 -0
  26. package/package.json +34 -4
  27. package/skills/cssupgrade/SKILL.md +16 -0
  28. package/src/index.js +53 -0
  29. package/src/newlyAvailable.js +1 -0
  30. package/src/parser.js +43 -0
  31. package/src/pool.js +165 -0
  32. package/src/prefilters.js +29 -0
  33. package/src/widelyAvailable/cssNesting.js +918 -0
  34. package/src/widelyAvailable.js +1 -0
  35. package/src/worker.js +31 -0
  36. package/tests/baseline.test.js +51 -0
  37. package/tests/cli.test.js +229 -0
  38. package/tests/css-nesting.test.js +838 -0
  39. package/tests/fixtures/silent-worker.js +5 -0
  40. package/tests/general.test.js +42 -0
  41. package/tests/parser.test.js +43 -0
  42. package/tests/pool.test.js +242 -0
  43. package/tests/prefilters.test.js +24 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "cssupgrade",
3
+ "displayName": "CSSupgrade",
4
+ "description": "Auto-upgrade CSS syntax to new features based on browser support.",
5
+ "version": "0.1.0",
6
+ "author": {
7
+ "name": "Johannes Maron",
8
+ "email": "security@codingjoe.dev"
9
+ },
10
+ "homepage": "https://github.com/codingjoe/cssupgrade",
11
+ "repository": "https://github.com/codingjoe/cssupgrade",
12
+ "license": "BSD-2-Clause",
13
+ "keywords": [
14
+ "css",
15
+ "modernize",
16
+ "upgrade",
17
+ "codemod",
18
+ "ast",
19
+ "transform",
20
+ "nesting"
21
+ ]
22
+ }
package/.editorconfig ADDED
@@ -0,0 +1,27 @@
1
+ # http://editorconfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ indent_style = space
7
+ indent_size = 4
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+ charset = utf-8
11
+ end_of_line = lf
12
+ max_line_length = 88
13
+
14
+ [*.{json,yml,yaml,mjs,js,jsx,vue,toml}]
15
+ indent_size = 2
16
+ ij_javascript_force_semicolon_style = false
17
+
18
+ [*.{html,htm,svg,xml}]
19
+ indent_size = 2
20
+ max_line_length = 120
21
+
22
+ [LICENSE]
23
+ insert_final_newline = false
24
+
25
+ [*.{md,markdown}]
26
+ indent_size = 2
27
+ max_line_length = 80
package/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ package-lock.json linguist-generated
@@ -0,0 +1,65 @@
1
+ ---
2
+ # For format details, see: https://gh.io/customagents/config
3
+
4
+ name: SuperJoe
5
+ description: CodingJoe's digital clone following his coding guidelines and best practices.
6
+ ---
7
+
8
+ # SuperJoe
9
+
10
+ ## Planning
11
+
12
+ You MUST ALWAYS follow the `naming-things` guidelines. Use the following command to access the guidelines:
13
+
14
+ ```console
15
+ curl -sSL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md | head -n 500
16
+ ```
17
+
18
+ You MUST ALWAYS read the `CONTRIBUTING.md` file before planning or writing any code.
19
+ You MUST ALWAYS search the documentation and amend or update it as necessary.
20
+ You MUST ALWAYS check for pre-commit hooks and run them before committing code.
21
+ You MUST ALWAYS ensure that all new code is fully tested with 100% coverage. Unreachable code branches MUST be removed.
22
+
23
+ ## Writing Code
24
+
25
+ Less code is more! Use the latest language features and libraries to achieve more with less code.
26
+
27
+ Do not add new dependencies, but if you do, they must be widely adopted and well-maintained in the open-source community.
28
+
29
+ You are a strong FOSS advocate with a preference for permissive licenses like BSD or MIT.
30
+
31
+ Use generators instead of adding items to lists or arrays.
32
+
33
+ Use class syntax for all object-oriented code.
34
+ Use named functions instead of anonymous functions whenever possible.
35
+ Avoid overly complex functions. Break them into smaller functions if necessary.
36
+ Docstrings should be written in present tense imperative mood.
37
+ They must start with a capital letter and end with a period.
38
+ Docstrings must describe the external behavior of the function, class, or method.
39
+ Docstrings should avoid redundant phrases like "This function" or "This method".
40
+ Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
41
+ Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
42
+ Avoid loops in favor of recursive functions or generator functions.
43
+ Avoid functions or other code inside functions.
44
+ Avoid if-statements in favor of switch/match-statements or polymorphism.
45
+ Do not assign names to objects which are returned in the next line.
46
+
47
+ ## Python
48
+
49
+ Follow PEP 8 guidelines for code style.
50
+ EAFP (Easier to Ask Forgiveness than Permission) is preferred over LBYL (Look Before You Leap).
51
+ Use type hints for all public functions, classes, and methods.
52
+ Use dataclasses for simple data structures.
53
+ Use context managers for resource management.
54
+ Use list/set/dict comprehensions instead of loops for creating collections.
55
+ Use generators for large data sets to save memory.
56
+ Use the walrus operator (`:=`) for inline assignments when it improves readability.
57
+
58
+ ### JavaScript
59
+
60
+ Use `#` for private methods.
61
+ Write docstrings with jsdoc type annotations for all functions, classes, and methods.
62
+
63
+ ### TypeScript
64
+
65
+ Use `#` for private methods.
@@ -0,0 +1,32 @@
1
+ YOUR PRIORITY IS TO ENSURE THE SAFETY OF ALL TRANSFORMATIONS.
2
+
3
+ When writing code, you MUST ALWAYS follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
4
+
5
+ Usage:
6
+
7
+ ```console
8
+ curl -sL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md | head -n 500
9
+ ```
10
+
11
+ All code must be fully tested with a 100% coverage. Unreachable code must be removed.
12
+ Follow the [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines for testing and linting.
13
+
14
+ All transformers must be documented in the README.md.
15
+
16
+ Use class syntax for all object-oriented code.
17
+ Use named functions instead of anonymous functions whenever possible.
18
+ Use `#` for private methods.
19
+
20
+ Avoid overly complex functions. Break them into smaller functions if necessary.
21
+
22
+ Write docstrings with jsdoc type annotations for all functions, classes, and methods.
23
+ Docstrings should be written in present tense imperative mood.
24
+ They must start with a capital letter and end with a period.
25
+ Docstrings must describe the external behavior of the function, class, or method.
26
+ Docstrings should avoid redundant phrases like "This function" or "This method".
27
+ Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
28
+ Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
29
+ Avoid loops in favor of recursive functions or generator functions.
30
+ Avoid functions or other code inside functions.
31
+ Avoid if-statements in favor of switch-statements or polymorphism.
32
+ Do not assign names to objects which are returned in the next line.
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: npm
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ - package-ecosystem: github-actions
8
+ directory: "/"
9
+ schedule:
10
+ interval: daily
@@ -0,0 +1,35 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ pull_request:
7
+ jobs:
8
+ readme:
9
+ name: "Word Weasel / README.md"
10
+ runs-on: ubuntu-latest
11
+ timeout-minutes: 1
12
+ steps:
13
+ - uses: actions/checkout@v7
14
+ - id: read_readme
15
+ run: |
16
+ echo "::set-output name=content::$(cat README.md)"
17
+ - uses: codingjoe/word-weasel@v1
18
+ with:
19
+ text: ${{ steps.read_readme.outputs.content }}
20
+ node-test:
21
+ name: Test
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ - name: Set up Node.js
26
+ uses: actions/setup-node@v7
27
+ with:
28
+ node-version-file: package.json
29
+ - run: npm ci
30
+ - run: npm test
31
+ - uses: codecov/codecov-action@v7
32
+ with:
33
+ token: ${{ secrets.CODECOV_TOKEN }}
34
+ flags: css
35
+ files: lcov.info
@@ -0,0 +1,27 @@
1
+ # Write better PRs and commit messages
2
+ name: "Word Weasel"
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - opened
7
+ - edited
8
+ - reopened
9
+ jobs:
10
+ pr-title:
11
+ name: "PR Title"
12
+ runs-on: ubuntu-latest
13
+ timeout-minutes: 1
14
+ if: ${{ github.actor != 'dependabot[bot]' }}
15
+ steps:
16
+ - uses: codingjoe/word-weasel@v1
17
+ with:
18
+ text: ${{ github.event.pull_request.title }}
19
+ pr-body:
20
+ name: "PR Body"
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 1
23
+ if: ${{ github.actor != 'dependabot[bot]' }}
24
+ steps:
25
+ - uses: codingjoe/word-weasel@v1
26
+ with:
27
+ text: ${{ github.event.pull_request.body }}
@@ -0,0 +1,22 @@
1
+ name: Release
2
+ on:
3
+ release:
4
+ types: [published]
5
+ permissions:
6
+ id-token: write
7
+ contents: read
8
+ jobs:
9
+ npmjs:
10
+ name: npmjs.org
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v7
14
+ - uses: actions/setup-node@v7
15
+ with:
16
+ node-version-file: package.json
17
+ registry-url: 'https://registry.npmjs.org'
18
+ - run: npm install -g npm@latest
19
+ - run: npm ci
20
+ - run: npm config set git-tag-version=false
21
+ - run: npm version ${{ github.event.release.tag_name }}
22
+ - run: npm publish
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
6
+ </content>
7
+ <orderEntry type="inheritedJdk" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+ <component name="PackageRequirementsSettings" />
11
+ <component name="PyDocumentationSettings" />
12
+ <component name="ReSTService" />
13
+ <component name="TestRunnerService" />
14
+ </module>
@@ -0,0 +1,28 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="DjangoUnresolvedUrlInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
5
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
6
+ <inspection_tool class="JsonSchemaCompliance" enabled="false" level="WARNING" enabled_by_default="false" />
7
+ <inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
8
+ <option name="ourVersions">
9
+ <value>
10
+ <list size="2">
11
+ <item index="0" class="java.lang.String" itemvalue="3.14" />
12
+ <item index="1" class="java.lang.String" itemvalue="3.15" />
13
+ </list>
14
+ </value>
15
+ </option>
16
+ </inspection_tool>
17
+ <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
18
+ <option name="ignoredIdentifiers">
19
+ <list>
20
+ <option value="ssdp.lexers.content_callback" />
21
+ </list>
22
+ </option>
23
+ </inspection_tool>
24
+ <inspection_tool class="StandardJS" enabled="true" level="ERROR" enabled_by_default="true" />
25
+ <inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
26
+ <inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
27
+ </profile>
28
+ </component>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
package/.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="KubernetesApiProvider">{}</component>
4
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/cssupgrade.iml" filepath="$PROJECT_DIR$/.idea/cssupgrade.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/.oxfmtrc.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "semi": false
3
+ }
@@ -0,0 +1,52 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: check-merge-conflict
7
+ - id: check-json
8
+ - id: check-yaml
9
+ - id: destroyed-symlinks
10
+ - id: check-executables-have-shebangs
11
+ - id: end-of-file-fixer
12
+ - id: no-commit-to-branch
13
+ args: [--branch, main]
14
+ - id: detect-private-key
15
+ - repo: https://github.com/hukkin/mdformat
16
+ rev: 1.0.0
17
+ hooks:
18
+ - id: mdformat
19
+ additional_dependencies:
20
+ - mdformat-config
21
+ - mdformat-footnote
22
+ - mdformat-gfm
23
+ - mdformat-gfm-alerts
24
+ - mdformat-frontmatter
25
+ args: [--number]
26
+ - repo: https://github.com/google/yamlfmt
27
+ rev: v0.21.0
28
+ hooks:
29
+ - id: yamlfmt
30
+ - repo: https://github.com/btford/write-good
31
+ rev: v1.0.8
32
+ hooks:
33
+ - id: write-good
34
+ args: [--no-passive]
35
+ - repo: https://github.com/oxc-project/mirrors-oxlint
36
+ rev: v1.60.0
37
+ hooks:
38
+ - id: oxlint
39
+ - repo: https://github.com/oxc-project/mirrors-oxfmt
40
+ rev: v0.78.0
41
+ hooks:
42
+ - id: oxfmt
43
+ - repo: https://github.com/codingjoe/esupgrade
44
+ rev: 2026.1.2 # Use the latest release
45
+ hooks:
46
+ - id: esupgrade
47
+ ci:
48
+ autoupdate_schedule: weekly
49
+ skip:
50
+ - no-commit-to-branch
51
+ - write-good
52
+ - esupgrade
@@ -0,0 +1,8 @@
1
+ - id: cssupgrade
2
+ name: CSSupgrade
3
+ description: 'Upgrade your CSS syntax to Baseline.'
4
+ entry: cssupgrade
5
+ args: [--check, --write]
6
+ language: node
7
+ types_or: [css]
8
+ require_serial: true
package/AGENTS.md ADDED
@@ -0,0 +1,54 @@
1
+ # CSSupgrade
2
+
3
+ The package includes transformers for upgrading CSS syntax.
4
+
5
+ ## Categories
6
+
7
+ - [Widely Available](./src/widelyAvailable/): Transformers for features available in all major browsers for at least 30 months.
8
+ - [Newly Available](./src/newlyAvailable/): Transformers for features available in all major browsers for 0-30 months.
9
+
10
+ For a full list of transformations, see [README.md](./README.md).
11
+
12
+ ## Package Structure
13
+
14
+ - [bin/](./bin/): Command-line interface script.
15
+ - [src/](./src/): Source code and transformers.
16
+ - [tests/](./tests/): Test suite.
17
+
18
+ For contributing guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).
19
+
20
+ ## Instructions
21
+
22
+ Use EOF syntax to run node scripts directly from the command line. For example:
23
+
24
+ ```bash
25
+ node --input-type=module <<'EOF'
26
+ import { transform } from './src/index.js';
27
+
28
+ const sample = '.a { color: red } .a .b { color: blue }';
29
+ const res = transform(sample);
30
+ console.log('modified:', res.modified);
31
+ console.log('code:\n' + res.code);
32
+ EOF
33
+ ```
34
+
35
+ ## Writing Transformers
36
+
37
+ The pipeline parses CSS with `parseCss` from `src/parser.js`, which returns the
38
+ css-tree syntax tree and the ranges of all comments.
39
+
40
+ Every transformer declares a pre-filter in `src/prefilters.js`, so files that
41
+ cannot contain the pattern skip the parse. See [CONTRIBUTING.md](./CONTRIBUTING.md).
42
+
43
+ ## Writing Docs
44
+
45
+ ### README.md
46
+
47
+ We add one new section per transformation:
48
+
49
+ 1. Headline + MDN link
50
+ 2. One diff-based example.
51
+ 3. Notable exception, which are not transformed.
52
+
53
+ We MUST NOT add any comments about "what it does".
54
+ The functionality documentation is fully covered by the diff-based example.
@@ -0,0 +1,40 @@
1
+ # Contributing
2
+
3
+ To run tests locally, follow these steps:
4
+
5
+ ```console
6
+ npm ci
7
+ npm test
8
+ ```
9
+
10
+ We use pre-commit hooks to lint and format code before committing.
11
+
12
+ To install the pre-commit hooks, run:
13
+
14
+ ```console
15
+ uvx pre-commit install
16
+ ```
17
+
18
+ Or instead run the linters once with:
19
+
20
+ ```console
21
+ uvx pre-commit run --all-files
22
+ ```
23
+
24
+ ## Naming conventions
25
+
26
+ When writing code, please follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
27
+
28
+ ## Baseline release dates
29
+
30
+ The baseline date can be found on
31
+ https://github.com/web-platform-dx/web-features named `baseline_low_date`.
32
+
33
+ ## Pre-filters
34
+
35
+ Every transformer needs a pre-filter in `src/prefilters.js` and a sample in
36
+ `tests/prefilters.test.js`. A pre-filter lists conditions on the source text,
37
+ and each condition must be necessary: when the source text misses a condition,
38
+ the transformer cannot change the tree. The test suite transforms every sample
39
+ with and without pre-filters and compares the results, so an unsound condition
40
+ fails the tests.
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2025, Johannes Maron
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.