From 1af73c8f9d9bb39de9e60ed9ee4323468cf740de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:10:43 -0700 Subject: [PATCH 01/22] Bump tj-actions/changed-files from 44.0.0 to 44.0.1 (#3837) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44.0.0 to 44.0.1. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/2d756ea4c53f7f6b397767d8723b3a10a9f35bf2...635f118699dd888d737c15018cd30aff2e0274f8) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37e347bf..99453e7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - name: Find changed files in js-api-doc id: changed-files - uses: tj-actions/changed-files@2d756ea4c53f7f6b397767d8723b3a10a9f35bf2 + uses: tj-actions/changed-files@635f118699dd888d737c15018cd30aff2e0274f8 with: {files: js-api-doc} - name: Deploy From b7a34b2aa53aca5b9a83987e9f3d92137a4e6b3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:11:39 -0700 Subject: [PATCH 02/22] Bump bufbuild/buf-setup-action from 1.30.0 to 1.30.1 (#3829) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.30.0 to 1.30.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.30.0...v1.30.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99453e7f..c599567e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.30.0 + - uses: bufbuild/buf-setup-action@v1.30.1 with: {github_token: "${{ github.token }}"} - name: Generate protobuf code run: buf generate From 92c48d295f5f60207d1093bf4114891ab6c99f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Wed, 17 Apr 2024 14:33:07 -0700 Subject: [PATCH 03/22] Implement access tracking for containingUrl (#3835) --- EMBEDDED_PROTOCOL_CHANGELOG.md | 5 +++++ spec/EMBEDDED_PROTOCOL_VERSION | 2 +- spec/embedded_sass.proto | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/EMBEDDED_PROTOCOL_CHANGELOG.md b/EMBEDDED_PROTOCOL_CHANGELOG.md index 2db49005..30554f5b 100644 --- a/EMBEDDED_PROTOCOL_CHANGELOG.md +++ b/EMBEDDED_PROTOCOL_CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.7.0 + +* Add `containing_url_unused` field to `CanonicalizeResponse` and + `FileImportResponse`. + ## 2.6.0 * Add `fatal_deprecation`, `silence_deprecation`, and `future_deprecation` diff --git a/spec/EMBEDDED_PROTOCOL_VERSION b/spec/EMBEDDED_PROTOCOL_VERSION index e70b4523..24ba9a38 100644 --- a/spec/EMBEDDED_PROTOCOL_VERSION +++ b/spec/EMBEDDED_PROTOCOL_VERSION @@ -1 +1 @@ -2.6.0 +2.7.0 diff --git a/spec/embedded_sass.proto b/spec/embedded_sass.proto index 2710c039..0f4aa28d 100644 --- a/spec/embedded_sass.proto +++ b/spec/embedded_sass.proto @@ -192,6 +192,15 @@ message InboundMessage { // `null` instead. string error = 3; } + + // Whether `containing_url` in `CanonicalizeRequest` is unused. + // + // The compiler can cache the `CanonicalizeResponse` if the `containing_url` + // is unused. + // + // The default value is `false`, thus when the value is not set by the host, + // the `CanonicalizeResponse` will not be cached by the compiler. + bool containing_url_unused = 4; } // A response indicating the result of importing a canonical URL. @@ -257,6 +266,15 @@ message InboundMessage { // An error message explaining why the URL could not be loaded. string error = 3; } + + // Whether `containing_url` in `FileImportRequest` is unused. + // + // The compiler can cache the `FileImportResponse` if the `containing_url` + // is unused. + // + // The default value is `false`, thus when the value is not set by the host, + // the `FileImportResponse` will not be cached by the compiler. + bool containing_url_unused = 4; } // A response indicating the result of calling a custom Sass function defined From 90948b384a540616f55a1e200a7d71ecb65411eb Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 19 Apr 2024 16:17:11 -0700 Subject: [PATCH 04/22] Flush plain CSS nesting changes to the spec (#3841) Closes #3524 Co-authored-by: Carlos (Goodwine) <2022649+Goodwine@users.noreply.github.com> --- spec/selectors.md | 11 +++++++++++ spec/style-rules.md | 36 ++++++++++++++++++++++++++++-------- spec/syntax.md | 9 +++++++-- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/spec/selectors.md b/spec/selectors.md index 8000652f..361fd567 100644 --- a/spec/selectors.md +++ b/spec/selectors.md @@ -10,6 +10,8 @@ * [Bogus Selector](#bogus-selector) * [Syntax](#syntax) * [`ComplexSelector`](#complexselector) +* [Serialization](#serialization) + * [Parent Selector](#parent-selector) ## Definitions @@ -67,3 +69,12 @@ A selector list is *bogus* if any of its complex selectors are bogus. [\]: https://drafts.csswg.org/selectors-4/#typedef-combinator + +## Serialization + +### Parent Selector + +To serialize a parent selector, emit the character `&`. + +> A parent selector can only appear in a serialized selector if it was parsed +> from plain CSS, which doesn't allow it to have a suffix. diff --git a/spec/style-rules.md b/spec/style-rules.md index f03ca0e1..eb893d38 100644 --- a/spec/style-rules.md +++ b/spec/style-rules.md @@ -20,18 +20,30 @@ To execute a style rule `rule`: * Let `selector` be the result of evaluating all interpolation in `rule`'s selector and parsing the result as a selector list. -* If there is a [current style rule](#current-style-rule): +* Let `parent` be the [current style rule] or current at-rule if one exists, or + the innermost if both exist. - * If `selector` contains one or more parent selectors, replace them with the - current style rule's selector and set `selector` to the result. + [current style rule]: #current-style-rule + +* If `parent` is a style rule whose stylesheet wasn't [parsed as CSS]: + + [parsed as CSS]: syntax.md#parsing-text-as-css + + > Checking whether `rule`'s stylesheet is CSS ensures that the plain CSS + > behavior occurs even when plain CSS is evaluated in a Sass context, such as + > through a nested `@import` or a `meta.load-css()` call. + + * If `selector` contains one or more parent selectors and `rule`'s stylesheet + wasn't [parsed as CSS], replace those parent selectors with the current + style rule's selector and set `selector` to the result. * Otherwise, nest `selector` within the current style rule's selector using - the [descendant combinator][] and set `selector` to the result. + the [descendant combinator] and set `selector` to the result. [descendant combinator]: https://www.w3.org/TR/selectors-3/#descendant-combinators -* Otherwise, if `selector` contains one or more parent selectors, throw an - error. +* Otherwise, if `selector` contains one or more parent selectors and `rule`'s + stylesheet wasn't [parsed as CSS], throw an error. * Let `css` be a CSS style rule with selector `selector`. @@ -46,7 +58,15 @@ To execute a style rule `rule`: [complex selectors]: https://drafts.csswg.org/selectors-4/#complex -* Unless `css`'s selector is now empty, append `css` to [the current module][]'s - CSS. +* Unless `css`'s selector is now empty: + + * If `parent` is set and its stylesheet was [parsed as CSS], append `css` to + `parent` + + * Otherwise, if there is a current at-rule, append `css` to its children. + + > This was intended to be in the current spec, but was overlooked. + + * Otherwise, append `css` to [the current module]'s CSS. [the current module]: spec.md#current-module diff --git a/spec/syntax.md b/spec/syntax.md index 4c90a968..65778dc4 100644 --- a/spec/syntax.md +++ b/spec/syntax.md @@ -210,9 +210,9 @@ modifications. The following productions should produce errors: * A declaration followed by an open curly brace (that is, a nested declaration). -* A style rule appearing within another style rule. +* The parent selector `&` in a declaration value. -* The parent selector `&`, either in a selector or a declaration value. +* A style rule whose selector contains a trailing combinator. * Placeholder selectors. @@ -275,6 +275,11 @@ SCSS: adjacent `/`s in a [`SlashListExpression`] may have no whitespace between them, so `//` is parsed as two slash separators in a slash-separated list. +* A `ParentSelector` may appear anywhere in a `CompoundSelector`, rather than + just as the first `SimpleSelector`. + +* A `ParentSelector` may not have a `suffix`. + ### Consuming an Identifier This algorithm consumes input from a stream of [code points][] and returns a From ca95c8bb6fea6eece330b2971b253b7e2104e917 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:40:49 -0700 Subject: [PATCH 05/22] Bump tj-actions/changed-files from 44.0.1 to 44.3.0 (#3845) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44.0.1 to 44.3.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/635f118699dd888d737c15018cd30aff2e0274f8...0874344d6ebbaa00a27da73276ae7162fadcaf69) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c599567e..8e4a2eb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - name: Find changed files in js-api-doc id: changed-files - uses: tj-actions/changed-files@635f118699dd888d737c15018cd30aff2e0274f8 + uses: tj-actions/changed-files@0874344d6ebbaa00a27da73276ae7162fadcaf69 with: {files: js-api-doc} - name: Deploy From d47003033f6c82964882176996f9ea21bad1a6b1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 23 Apr 2024 16:41:03 -0700 Subject: [PATCH 06/22] Fix some bugs in the style rule and extend specs (#3847) * Adds style rules to the stylesheet when they're encountered rather than after all their children have run, so that nested rules appear after their parents. * Removes private placeholder selectors from style rules *after* they've been extended by local extensions. * Explicitly handle omitting placeholder-only selectors from the CSS generated by Resolving Extensions. * Allow the current selector to come from copies created by bubbling. * Properly handle keyframe blocks. --- spec/at-rules/extend.md | 24 ++++++++++++++-- spec/style-rules.md | 64 +++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/spec/at-rules/extend.md b/spec/at-rules/extend.md index 128c6d7d..24201916 100644 --- a/spec/at-rules/extend.md +++ b/spec/at-rules/extend.md @@ -160,7 +160,13 @@ that includes CSS for *all* modules transitively used or forwarded by * Let `selector` be `extend(rule's selector, domestic's extensions)`. - * Let `selector-lists` be an empty set of selector lists. + * Remove from `selector` any [complex selectors] containing a placeholder + selector that begins with `-` or `_` from `css`'s selector. + + * If `selector` is empty, move on to the next `rule`. + + * Let `selector-lists` be a set of selector lists containing only + `selector`. * For each module `foreign` in `downstream`: @@ -171,7 +177,7 @@ that includes CSS for *all* modules transitively used or forwarded by > means that `foreign`'s own extensions will already have been resolved > by the time we start working on modules upstream of it. - * Add `selector` to `selector-lists`. + * Add `extended-selector` to `selector-lists`. * Set `new-selectors[rule]` to a selector that matches the union of all elements matched by selectors in `selector-lists`. This selector must obey @@ -188,6 +194,12 @@ that includes CSS for *all* modules transitively used or forwarded by > `domestic`'s extensions don't count as "original", and may be optimized > away. + If none of the selectors in `selector-lists` match any elements, add + nothing to `new-selectors`. + + > This may occur if `selector-lists` contains placeholder selectors that + > haven't been extended. + * For every extension `extension` whose extender appears in `rule`'s selector: @@ -224,10 +236,16 @@ that includes CSS for *all* modules transitively used or forwarded by * Otherwise, add a copy of `statement` to the end of `css`, with any style rules' selectors replaced with the corresponding selectors in - `new-selectors`. + `new-selectors`. Omit any style rules that don't have corresponding + selectors in `new-selectors`. + + > This will omit style rules that contain un-extended placeholder + > selectors. * Return `css`. +[complex selectors]: https://drafts.csswg.org/selectors-4/#complex + ### Extending a Selector This algorithm takes a selector list `extendee`, a simple selector `target`, and diff --git a/spec/style-rules.md b/spec/style-rules.md index eb893d38..817e8553 100644 --- a/spec/style-rules.md +++ b/spec/style-rules.md @@ -4,6 +4,7 @@ * [Definitions](#definitions) * [Current Style Rule](#current-style-rule) + * [Current Keyframe Block](#current-keyframe-block) * [Semantics](#semantics) ## Definitions @@ -11,21 +12,42 @@ ### Current Style Rule The *current style rule* is the CSS style rule that was created by the innermost -[execution of a style rule](#semantics). +[execution of a style rule](#semantics), `@media` rule, `@supports` rule, or +unknown at-rule. + +### Current Keyframe Block + +The *current keyframe block* is the CSS keyframe block that was created by the +innermost [execution of a style rule](#semantics). ## Semantics To execute a style rule `rule`: -* Let `selector` be the result of evaluating all interpolation in `rule`'s - selector and parsing the result as a selector list. +* Let `selector-text` be the result of evaluating all interpolation in `rule`'s + selector. -* Let `parent` be the [current style rule] or current at-rule if one exists, or - the innermost if both exist. +* Let `parent` be the [current style rule], at-rule, or keyframe block if one + exists, or the innermost if multiple exist. [current style rule]: #current-style-rule -* If `parent` is a style rule whose stylesheet wasn't [parsed as CSS]: +* If `parent` is a keyframe block, throw an error. + +* Otherwise, if `parent` is an unknown at-rule whose name without vendor + prefixes is "keyframes": + + * Let `selector` be the result of parsing `selector-text` as a keyframe + selector. + + * Append a keyframe block with selector `selector` to `parent`. + + * Evaluate each child of `rule`. + + * Cease evaluating `rule`. + +* Otherwise, if `parent` is a style rule whose stylesheet wasn't [parsed as + CSS]: [parsed as CSS]: syntax.md#parsing-text-as-css @@ -47,26 +69,20 @@ To execute a style rule `rule`: * Let `css` be a CSS style rule with selector `selector`. -* Execute each child `child` of `rule`. +* If `parent` is set and its stylesheet was [parsed as CSS], append `css` to + `parent`. + +* Otherwise, if there is a current at-rule, append `css` to its children. + +* Otherwise, append `css` to [the current module]'s CSS. + + [the current module]: spec.md#current-module + +* Execute each child of `rule`. * If `css` contains any children and `selector` is [bogus], throw an error. [bogus]: selectors.md#bogus-selector -* Remove any [complex selectors][] containing a placeholder selector that - begins with `-` or `_` from `css`'s selector. - - [complex selectors]: https://drafts.csswg.org/selectors-4/#complex - -* Unless `css`'s selector is now empty: - - * If `parent` is set and its stylesheet was [parsed as CSS], append `css` to - `parent` - - * Otherwise, if there is a current at-rule, append `css` to its children. - - > This was intended to be in the current spec, but was overlooked. - - * Otherwise, append `css` to [the current module]'s CSS. - - [the current module]: spec.md#current-module +* Otherwise, if `css` contains no children, remove it from the current module's + CSS. From 5cceb6c1ffb8f4eea98145da3e4324548db37c6b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 22 Apr 2024 15:18:16 -0700 Subject: [PATCH 07/22] Specify the existing declaration behavior --- spec/declarations.md | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 spec/declarations.md diff --git a/spec/declarations.md b/spec/declarations.md new file mode 100644 index 00000000..17e66bc3 --- /dev/null +++ b/spec/declarations.md @@ -0,0 +1,79 @@ +## Declarations + +## Table of Contents + +* [Syntax](#syntax) +* [Definitions](#definitions) +* [Current Declaration Name](#current-declaration-name) +* [Semantics](#semantics) + +## Syntax + +
+**Declaration**         ::= StandardDeclaration | CustomDeclaration
+**StandardDeclaration** ::= [InterpolatedIdentifier]¹ ':' (Value | Value? '{' Statements '}')
+**CustomDeclaration**   ::= [InterpolatedIdentifier]² ':' InterpolatedDeclarationValue
+
+ +1. This may not begin with "--". +2. This *must* begin with "--". + +[InterpolatedIdentifier]: syntax.md#interpolatedidentifier + +## Definitions + +### Current Declaration Name + +The *current declaration name* is the innermost value declared as such when +[executing a declaration]. + +[executing a declaration]: #semantics + +### Semantics + +To execute a declaration `declaration`: + +* Let `parent-name` be the [current declaration name], if one exists. + + [current declaration name]: #current-declaration-name + +* If `name` is set and `declaration` is a [`CustomDeclaration`], throw an error. + + [`CustomDeclaration`]: #syntax + +* Let `name` be the result of evaluating the all interpolation in + `declaration`'s name. + +* If `parent-name` exists, set `name` to `parent-name + "-" + name`. + +* Declare `name` as the [current declaration name] for the duration of executing + `declaration`. + +* If `declaration` has a `Value`: + + * Let `value` be the result of evaluating that `Value`. + +* Otherwise, if `declaration` is a `CustomDeclaration`: + + * Let `value` be an unquoted string whose value is the result of evaluating + `declaration`'s `InterpolatedDeclarationValue`. + + * If `value` is empty, throw an error. + + > Note that `value` being only whitespace is allowed, including `--foo: ;`. + +* Let `parent` be the [current style rule], [keyframe block], or at-rule; or + the innermost if multiple exist. + + [current style rule]: style-rules.md#current-style-rule + [keyframe block]: style-rules.md#current-style-rule + + > Parsing guarantees that a declaration will have at least one parent. + +* If `value` is set, and it's neither null nor an empty unquoted string: + + * Let `css` be a CSS declaration with name `name` and value `value`. + + * Append `css` to `parent`. + +* Evaluate each child in `declaration`'s `Statements` if it exists. From bcbc5a51f97c1a621994cd98266bdd6676607491 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 22 Apr 2024 15:37:43 -0700 Subject: [PATCH 08/22] Add full semantics for unknown at-rules --- spec/at-rules/unknown.md | 64 +++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/spec/at-rules/unknown.md b/spec/at-rules/unknown.md index fec49976..faa5c97b 100644 --- a/spec/at-rules/unknown.md +++ b/spec/at-rules/unknown.md @@ -1,11 +1,13 @@ # Unknown At-Rules -In order to be flexible in its compatibility with future additions to CSS, Sass -supports *all* at-rule names with a default syntax that's highly liberal in the -structures it allows. It uses the following grammar: +## Syntax + +> In order to be flexible in its compatibility with future additions to CSS, Sass +> supports *all* at-rule names with a default syntax that's highly liberal in the +> structures it allows.
-**UnknownAtRule** ::= '@' [InterpolatedIdentifier][] InterpolatedValue?
+**UnknownAtRule** ::= '@' [InterpolatedIdentifier] InterpolatedValue?
                     ('{' Statements '}')?
 
@@ -14,11 +16,51 @@ structures it allows. It uses the following grammar: No whitespace is allowed after `@`. As with all statements, an `UnknownAtRule` without a block must be separated from other statements with a semicolon. -When an at-rule is executed, its name is evaluated to produce an unquoted string -which is used as the name of the generated at-rule. Then that generated name is -checked to see if it's an at-rule that has special runtime handling. +## Semantics -> Note that only `@keyframes` has special runtime handling that's triggered -> here. Other CSS at-rules that Sass handles specially, like `@media` or -> `@supports`, are detected at parse-time. This means that `@m#{ed}ia` will be -> treated as an unknown at-rule rather than a media rule. +To execute an unknown at-rule `rule`: + +* Let `name` be the result of evaluating `rule`'s `InterpolatedIdentifier`. + +* Let `value` be the result of evaluating `rule`'s `InterpolatedValue`, if it + exists. + +* Let `css` be a CSS unknown at-rule with name `name`, value `value`, and with + an empty list of children if `rule` has `Statements`. + +* Let `parent` be the [current style rule], [keyframe block], or at-rule if one + exists; or the innermost if multiple exist. + + [current style rule]: ../style-rules.md#current-style-rule + [keyframe block]: ../style-rules.md#current-style-rule + +* If `parent` is a keyframe block, throw an error. + +* If `rule` has `Statements`: + + * If `parent` isn't set, append `css` to [the current module]'s CSS. + + * Otherwise, if `parent` is a style rule: + + * If `rule`'s name is "font-face", or if its [unprefixed] name is + "keyframes", append `css` to [the current module]'s CSS. + + * Otherwise: + + * Let `copy` by a copy of `parent` without any children. + + * Append `copy` to `parent`'s parent. + + * Append `css` to `copy`. + + * Otherwise, append `css` to `parent`. + + * Evaluate each child in `rule`'s `Statement`s. + +* Otherwise: + + * Append `css` to `parent` if it's set, or to [the current module]'s CSS + otherwise. + +[the current module]: ../spec.md#current-module +[unprefixed]: ../syntax.md#vendor-prefix From 09c89ec6ca12a36b29d0ad18360ea5403c9c9d05 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 23 Apr 2024 18:02:12 -0700 Subject: [PATCH 09/22] [Ordered Comments] Flush to the spec (#3844) See #2848 --- spec/at-rules/extend.md | 20 ++++++++++++++------ spec/at-rules/import.md | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/spec/at-rules/extend.md b/spec/at-rules/extend.md index 24201916..dc0325d8 100644 --- a/spec/at-rules/extend.md +++ b/spec/at-rules/extend.md @@ -215,7 +215,13 @@ that includes CSS for *all* modules transitively used or forwarded by * If `domestic` has already been traversed, do nothing. - * Otherwise, traverse every module in `domestic`'s dependencies. + * For each module `upstream` in `domestic`'s dependencies: + + * For each unmarked comment in `domestic`'s CSS, if that comment originally + appeared before the `@use` or `@forward` rule that loaded `upstream`, add + a copy of that comment to `css` and then mark it. + + * Traverse `upstream`. > Because this traverses modules depth-first, it emits CSS in reverse > topological order. @@ -224,15 +230,17 @@ that includes CSS for *all* modules transitively used or forwarded by statements in `domestic`'s CSS tree that contains only comments and `@import` rules *and* that ends with an `@import` rule. - * Insert a copy of `initial-imports` in `css` after the last `@import` rule, or - at the beginning of `css` if it doesn't contain any `@import` rules. + * Insert a copy of `initial-imports` in `css` after the longest initial + subsequence of comments and `@import` rules in `css`. + + > If there are no comments or `@import` rules in `css`, this initial + > subsequence is empty and `initial-imports` is inserted at the beginning of + > `css`. * For each top-level statement `statement` in `domestic`'s CSS tree after `initial-imports`: - * If `statement` is an `@import` rule, insert a copy of `statement` in `css` - after the last `@import` rule, or at the beginning of `css` if it doesn't - contain any `@import` rules. + * If `statement` is a marked comment, ignore it. * Otherwise, add a copy of `statement` to the end of `css`, with any style rules' selectors replaced with the corresponding selectors in diff --git a/spec/at-rules/import.md b/spec/at-rules/import.md index f4d1bffb..755c9667 100644 --- a/spec/at-rules/import.md +++ b/spec/at-rules/import.md @@ -109,8 +109,8 @@ To execute an `@import` rule `rule`: > `ImportMedia` is a subset of the valid syntax of `MediaQueryList`, so > this will always work. - * Add an `@import` with the evaluated modifiers to [the current module]'s - CSS AST. + * Add an `@import` with the evaluated modifiers to [the current module]'s CSS + AST after the longest initial subsequence of comments and `@import` rules. * Otherwise, let `file` be the result of [loading the file][] with `argument`'s URL string. If this returns null, throw an error. From c5e1f9a55c98bbe164f01fdcc03ea3fc609761be Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 23 Apr 2024 18:11:40 -0700 Subject: [PATCH 10/22] Fix an at-rule semantics bug --- spec/at-rules/unknown.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/at-rules/unknown.md b/spec/at-rules/unknown.md index faa5c97b..c1c58bdd 100644 --- a/spec/at-rules/unknown.md +++ b/spec/at-rules/unknown.md @@ -47,11 +47,12 @@ To execute an unknown at-rule `rule`: * Otherwise: - * Let `copy` by a copy of `parent` without any children. + * Append `css` to `parent`'s parent. - * Append `copy` to `parent`'s parent. + * Append a copy of `parent` without any children to `css`. - * Append `css` to `copy`. + > This copy is now the [current style rule] until `rule` is done being + > executed. * Otherwise, append `css` to `parent`. From b888b3be25832a7184d3f4a2e56814ec8411a696 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 15 Mar 2024 17:02:41 -0700 Subject: [PATCH 11/22] Add a proposal to make room for plain-CSS functions and mixins See #3787 --- proposal/css-function-mixin-preparation.md | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 proposal/css-function-mixin-preparation.md diff --git a/proposal/css-function-mixin-preparation.md b/proposal/css-function-mixin-preparation.md new file mode 100644 index 00000000..b099d82a --- /dev/null +++ b/proposal/css-function-mixin-preparation.md @@ -0,0 +1,67 @@ +# Preparing for Plain CSS Functions and Mixins: Draft 1 + +*([Issue](https://github.com/sass/sass/issues/3787))* + +This proposal adds errors for existing Sass syntax which is likely to conflict +with upcoming plain CSS support for functions and mixins. + +## Table of Contents + +* [Background](#background) +* [Summary](#summary) +* [Semantics](#semantics) + * [`@mixin`](#mixin) + * [`@function`](#function) +* [Deprecation Process](#deprecation-process) + +## Background + +> This section is non-normative. + +In [this informal proposal] and [this issue], the CSS working group have begun +seriously discussing the possibility of introducing functions and mixins to CSS +itself. Although many specific details are still in flux, all syntaxes that have +been floated have two things in common: + +[this informal proposal]: https://css.oddbird.net/sasslike/mixins-functions/ +[this issue]: https://github.com/w3c/csswg-drafts/issues/9350 + +* They use at-rules named `@mixin` and `@function`, just as Sass does today. +* They require custom identifiers beginning with `--` after these at-rules. + +Sass currently allows functions and mixins whose names begin with `--`, but this +is a relatively painless thing to deprecate and would allow us full CSS +compatibility with whatever version of the proposal ends up getting implemented. + +## Summary + +> This section is non-normative. + +This proposal makes any mixin or function whose name begins with `--` an error. +This will be preceded by a deprecation period in which those mixins and +functions will just produce warnings. + +## Semantics + +### `@mixin` + +Update [the `@mixin` semantics] to add after the first line: + +[the `@mixin` semantics]: ../spec/at-rules/mixin.md + +* If `name` begins with `--`, throw an error. + +### `@function` + +Update [the `@function` semantics] to add after the first line: + +[the `@function` semantics]: ../spec/at-rules/function.md + +* If `name` begins with `--`, throw an error. + +## Deprecation Process + +During the deprecation period, instead of throwing errors as described in [the +semantics section] above, emit a deprecation warning named `css-function-mixin`. + +[the semantics section]: #semantics From d3ed8dfc729d39c5281e3fb62f89bb99b59a2c49 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 30 Apr 2024 14:19:57 -0700 Subject: [PATCH 12/22] [CSS Function/Mixin Prep] Mark as accepted and update spec (#3854) --- {proposal => accepted}/css-function-mixin-preparation.md | 0 js-api-doc/deprecations.d.ts | 7 +++++++ spec/at-rules/function.md | 2 ++ spec/at-rules/mixin.md | 2 ++ spec/js-api/deprecations.d.ts.md | 1 + 5 files changed, 12 insertions(+) rename {proposal => accepted}/css-function-mixin-preparation.md (100%) diff --git a/proposal/css-function-mixin-preparation.md b/accepted/css-function-mixin-preparation.md similarity index 100% rename from proposal/css-function-mixin-preparation.md rename to accepted/css-function-mixin-preparation.md diff --git a/js-api-doc/deprecations.d.ts b/js-api-doc/deprecations.d.ts index 5213f168..5f2f5053 100644 --- a/js-api-doc/deprecations.d.ts +++ b/js-api-doc/deprecations.d.ts @@ -106,6 +106,13 @@ export interface Deprecations { */ 'fs-importer-cwd': Deprecation<'fs-importer-cwd'>; + /** + * Deprecation for function and mixin names beginning with `--`. + * + * This deprecation became active in Dart Sass 1.76.0. + */ + 'css-function-mixin': Deprecation<'css-function-mixin'>; + /** * Deprecation for `@import` rules. * diff --git a/spec/at-rules/function.md b/spec/at-rules/function.md index c62189ed..14aa4ec2 100644 --- a/spec/at-rules/function.md +++ b/spec/at-rules/function.md @@ -22,6 +22,8 @@ To execute a `@function` rule `rule`: * Let `name` be the value of `rule`'s `Identifier`. +* If `name` begins with `--`, throw an error. + * If `name` is `calc`, `element`, `expression`, `url`, `and`, `or`, or `not`, or if `name` has a [vendor prefix] and the unprefixed identifier is one of those strings, throw an error. diff --git a/spec/at-rules/mixin.md b/spec/at-rules/mixin.md index d154d199..016608d0 100644 --- a/spec/at-rules/mixin.md +++ b/spec/at-rules/mixin.md @@ -31,6 +31,8 @@ To execute a `@mixin` rule `rule`: * Let `name` be the value of `rule`'s `Identifier`. +* If `name` begins with `--`, throw an error. + * Let `parent` be the [current scope]. [current scope]: ../spec.md#scope diff --git a/spec/js-api/deprecations.d.ts.md b/spec/js-api/deprecations.d.ts.md index adbe3a23..1017bc4a 100644 --- a/spec/js-api/deprecations.d.ts.md +++ b/spec/js-api/deprecations.d.ts.md @@ -44,6 +44,7 @@ export interface Deprecations { 'null-alpha': Deprecation<'null-alpha'>; 'abs-percent': Deprecation<'abs-percent'>; 'fs-importer-cwd': Deprecation<'fs-importer-cwd'>; + 'css-function-mixin': Deprecation<'css-function-mixin'>; import: Deprecation<'import'>; 'user-authored': Deprecation<'user-authored', 'user'>; } From 28b17d89de0d7e5c334b14efc21fe1671b196270 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 30 Apr 2024 14:35:23 -0700 Subject: [PATCH 13/22] [Interleaved Declarations] Add a proposal (#3848) See #3846 --- proposal/interleaved-declarations.md | 159 +++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 proposal/interleaved-declarations.md diff --git a/proposal/interleaved-declarations.md b/proposal/interleaved-declarations.md new file mode 100644 index 00000000..349b78a3 --- /dev/null +++ b/proposal/interleaved-declarations.md @@ -0,0 +1,159 @@ +# Interleaved Declarations: Draft 1 + +*([Issue](https://github.com/sass/sass/issues/3846))* + +## Table of Contents + +* [Background](#background) +* [Summary](#summary) +* [Definitions](#definitions) + * [Current Style Rule](#current-style-rule) + * [Current Style Rule](#current-style-rule-1) + * [Current Keyframe Block](#current-keyframe-block) +* [Declarations](#declarations) + * [Semantics](#semantics) +* [Unknown At-Rules](#unknown-at-rules) + * [Semantics](#semantics-1) +* [Deprecation Process](#deprecation-process) + +## Background + +> This section is non-normative. + +Historically, Sass has hoisted declarations that appear after nested rules into +the original style rule. Although this doesn't match the logical ordering of the +source document, it *does* avoid duplicating the style rule (and any other +nested rules) for each set of interleaved properties. + +Many years after this decision was made, the [CSS Nesting Module] was published +by the W3C, adding native support for nesting rules within style rules using +essentially the same syntax as Sass. Although initially its semantics for +interleaved declarations were the same as Sass's, [a later update] (four days +ago at time of writing) changed it to preserve the logical ordering of +interleaved declarations. + +[CSS Nesting Module]: https://drafts.csswg.org/css-nesting/ +[a later update]: https://github.com/w3c/csswg-drafts/commit/e5547b96f5de6fb5a68d050f42d562c448b99d0b + +## Summary + +> This section is non-normative. + +This proposal changes the behavior of declarations that appear after nested +rules. Instead of being hoisted to the beginning of the parent rule, they will +now be placed in their original logical order, duplicating the parent selector. + +That is, the following Sass: + +```scss +.a { + color: red; + @media screen {color: blue} + color: green; +} +``` + +will now compile to this CSS: + +```scss +.a { + color: red; +} + +@media screen { + .a { + color: blue; + } +} + +.a { + color: green; +} +``` + +## Definitions + +### Current Style Rule + +Change the definition of the [current style rule][old] to: + +[old]: ../spec/style-rules.md#current-style-rule + +> Differences are highlighted in bold. + +The *current style rule* is the CSS style rule that was created by the innermost +[execution of a style rule], `@media` rule, `@supports` rule, unknown at-rule. +**This may be overridden by the [execution of a declaration].** + +[execution of a style rule]: ../spec/style-rules.md#semantics +[execution of a declaration]: #semantics + +### Current Style Rule + +Change the definition of the [current style rule][old style] to: + +[old style]: ../spec/style-rules.md#current-style-rule + +> Differences are highlighted in bold. + +The *current style rule* is the CSS style rule that was created by the innermost +[execution of a style rule], `@media` rule, `@supports` rule, unknown at-rule. +**This may be overridden by the [execution of a declaration].** + +### Current Keyframe Block + +Change the definition of the [current keyframe block][old keyframe] to: + +[old keyframe]: ../spec/style-rules.md#current-keyframe-block + +> Differences are highlighted in bold. + +The *current keyframe block* is the CSS keyframe block that was created by the +innermost [execution of a style rule]. **This may be overridden by the +[execution of a declaration].** + +## Declarations + +### Semantics + +Add the following to the semantics for [executing a declaration] `declaration` +before "Append `css` to `parent`": + +[executing a declaration]: ../spec/declarations.md#semantics + +* If `parent` isn't the last statement in its parent: + + * Let `copy` by a copy of `parent` without any children. + + * Append `copy` to `parent`'s parent. + + * Set the [current style rule], [keyframe block], or at-rule (according to + `copy`'s type) to `copy`, for the remaining duration of its previous value. + + * Set `parent` to `copy`. + +[current style rule]: #current-style-rule +[keyframe block]: #current-keyframe-block + +## Unknown At-Rules + +### Semantics + +Add the following to the semantics for executing an unknown at-rule `rule` after +"If `rule`'s name is 'font-face', or if its unprefixed name is 'keyframes', +append `css` to the current module's CSS": + +* If `rule`'s name is case-insensitively equal to "nest", append `css` to + `parent`. + +## Deprecation Process + +This proposal's change to the semantics of interleaved declarations is +backwards-incompatible. Before changing to the new semantics, an implementation +should have a period of deprecation in which it emits a deprecation warning for +a declaration whose `parent` is not the last statement in [the current module]'s +CSS without changing the existing behavior. + +> Authors can move interleaved declarations before any nested rules to preserve +> existing behavior, or nest them in `& { ... }` style rules to anticipate the +> new behavior. From 3ef0ad476b20be8fc2dc965f860a159023c247d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 13:40:23 -0700 Subject: [PATCH 14/22] Bump bufbuild/buf-setup-action from 1.30.1 to 1.31.0 (#3855) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.30.1 to 1.31.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.30.1...v1.31.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e4a2eb1..e79cb6de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.30.1 + - uses: bufbuild/buf-setup-action@v1.31.0 with: {github_token: "${{ github.token }}"} - name: Generate protobuf code run: buf generate From 71df892b8c009a32c246acfb30dd836181a02be5 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Thu, 2 May 2024 22:26:34 +0200 Subject: [PATCH 15/22] Remove duplicate section in proposal (#3857) --- proposal/interleaved-declarations.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/proposal/interleaved-declarations.md b/proposal/interleaved-declarations.md index 349b78a3..f70d816e 100644 --- a/proposal/interleaved-declarations.md +++ b/proposal/interleaved-declarations.md @@ -8,7 +8,6 @@ * [Summary](#summary) * [Definitions](#definitions) * [Current Style Rule](#current-style-rule) - * [Current Style Rule](#current-style-rule-1) * [Current Keyframe Block](#current-keyframe-block) * [Declarations](#declarations) * [Semantics](#semantics) @@ -88,18 +87,6 @@ The *current style rule* is the CSS style rule that was created by the innermost [execution of a style rule]: ../spec/style-rules.md#semantics [execution of a declaration]: #semantics -### Current Style Rule - -Change the definition of the [current style rule][old style] to: - -[old style]: ../spec/style-rules.md#current-style-rule - -> Differences are highlighted in bold. - -The *current style rule* is the CSS style rule that was created by the innermost -[execution of a style rule], `@media` rule, `@supports` rule, unknown at-rule. -**This may be overridden by the [execution of a declaration].** - ### Current Keyframe Block Change the definition of the [current keyframe block][old keyframe] to: From fd872ff2b9d8606423355625adfab6b753af1f8a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 May 2024 14:48:26 -0700 Subject: [PATCH 16/22] Allow @-rules in `@keyframes` blocks (#3861) This is a fast-track proposal. Closes #3859 --- spec/at-rules/unknown.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/at-rules/unknown.md b/spec/at-rules/unknown.md index c1c58bdd..eff2d183 100644 --- a/spec/at-rules/unknown.md +++ b/spec/at-rules/unknown.md @@ -34,8 +34,6 @@ To execute an unknown at-rule `rule`: [current style rule]: ../style-rules.md#current-style-rule [keyframe block]: ../style-rules.md#current-style-rule -* If `parent` is a keyframe block, throw an error. - * If `rule` has `Statements`: * If `parent` isn't set, append `css` to [the current module]'s CSS. From bf3982b0f08b99ceb9d86357109ca7800bfad285 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 14:18:10 -0700 Subject: [PATCH 17/22] Bump tj-actions/changed-files from 44.3.0 to 44.4.0 (#3864) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44.3.0 to 44.4.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/0874344d6ebbaa00a27da73276ae7162fadcaf69...a29e8b565651ce417abb5db7164b4a2ad8b6155c) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e79cb6de..cb9b2bc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - name: Find changed files in js-api-doc id: changed-files - uses: tj-actions/changed-files@0874344d6ebbaa00a27da73276ae7162fadcaf69 + uses: tj-actions/changed-files@a29e8b565651ce417abb5db7164b4a2ad8b6155c with: {files: js-api-doc} - name: Deploy From a46939253b273eac1caed1c8541dbf33af82d8de Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 May 2024 15:04:07 -0700 Subject: [PATCH 18/22] Explicitly specify underscore-insensitivity for module member names (#3866) --- spec/js-api/options.d.ts.md | 6 ++++-- spec/modules.md | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/spec/js-api/options.d.ts.md b/spec/js-api/options.d.ts.md index 90e8b90e..97607147 100644 --- a/spec/js-api/options.d.ts.md +++ b/spec/js-api/options.d.ts.md @@ -156,8 +156,9 @@ Before beginning compilation: * Let `name` be `signature`'s . - * If there's already a global function whose name is underscore-insensitively - equal to `name`, continue to the next key/value pair. + * If there's already a global function whose name is + [underscore-insensitively] equal to `name`, continue to the next key/value + pair. * Otherwise, add a global function whose signature is `signature`. When this function is called: @@ -182,6 +183,7 @@ Before beginning compilation: replaced with the result of [simplifying] those calculations. []: https://drafts.csswg.org/css-syntax-3/#ident-token-diagram +[underscore-insensitively]: ../modules.md#underscore-insensitive [`SassFunction`]: value/function.d.ts.md [simplifying]: https://github.com/sass/sass/tree/main/spec/types/calculation.md#simplifying-a-calculation diff --git a/spec/modules.md b/spec/modules.md index d44bfa05..38899436 100644 --- a/spec/modules.md +++ b/spec/modules.md @@ -15,6 +15,7 @@ * [Package Importers](#package-importers) * [Node Package Importer](#node-package-importer) * [Global Importer List](#global-importer-list) + * [Underscore-Insensitive](#underscore-insensitive) * [Basename](#basename) * [Dirname](#dirname) * [Syntax](#syntax) @@ -70,7 +71,10 @@ A new *configuration* ID is unique unless otherwise specified. A *module* is a collection of various properties: * A set of [members](#member) that contains at most one member of any given type - and name. + and [underscore-insensitive] name. All lookups in this set are + underscore-insensitive unless explicitly specified otherwise. + + [underscore-insensitive]: #underscore-insensitive > For example, a module may not have two variables named `$name`, although it > may contain a function and a mixin with the same name or two functions with @@ -300,6 +304,16 @@ When the Node Package Importer is invoked with a string named `string`: The *global importer list* is a list of importers that's set for the entire duration of a Sass compilation. +### Underscore-Insensitive + +If a name comparison is *underscore-insensitive*, it considers the characters +U+002D HYPHEN-MINUS and U+005F LOW LINE to be equal to one another. + +> Long ago, Sass only supported underscores as separators for Sass identifiers. +> When support for hyphens was added to match CSS, they were made equivalent to +> underscores for backwards-compatibility. This insensitivity is generally only +> used for Sass member names, not any other identifiers. + ### Basename The *basename* of a URL is the final component of that URL's path. From 546881d38e4d0ee319d0db729462f0b7723995d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 13:50:34 -0700 Subject: [PATCH 19/22] Bump bufbuild/buf-setup-action from 1.31.0 to 1.32.0 (#3870) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.31.0 to 1.32.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.31.0...v1.32.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb9b2bc5..4ba3d814 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.31.0 + - uses: bufbuild/buf-setup-action@v1.32.0 with: {github_token: "${{ github.token }}"} - name: Generate protobuf code run: buf generate From 978fc206df992bccb000576de838eb10d099adc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 13:12:58 -0700 Subject: [PATCH 20/22] Bump tj-actions/changed-files from 44.4.0 to 44.5.1 (#3875) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44.4.0 to 44.5.1. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/a29e8b565651ce417abb5db7164b4a2ad8b6155c...03334d095e2739fa9ac4034ec16f66d5d01e9eba) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ba3d814..ac7bfb3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: - name: Find changed files in js-api-doc id: changed-files - uses: tj-actions/changed-files@a29e8b565651ce417abb5db7164b4a2ad8b6155c + uses: tj-actions/changed-files@03334d095e2739fa9ac4034ec16f66d5d01e9eba with: {files: js-api-doc} - name: Deploy From 1ff92c2da64b9302c2dad9080a3b8583e40ec2d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 13:14:19 -0700 Subject: [PATCH 21/22] Bump bufbuild/buf-setup-action from 1.32.0 to 1.32.1 (#3876) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.32.0 to 1.32.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.32.0...v1.32.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac7bfb3f..f515b292 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.32.0 + - uses: bufbuild/buf-setup-action@v1.32.1 with: {github_token: "${{ github.token }}"} - name: Generate protobuf code run: buf generate From 87699d79b2b514622ee877cde7d6e2c12f0dbc17 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Wed, 29 May 2024 14:23:18 -0700 Subject: [PATCH 22/22] Add deprecations.yaml as a single-source-of-truth (#3872) Instead of having the list of deprecations repeated in several different places across all of our repos, the new `spec/deprecations.yaml` file will be the only place we need to update it, with all other uses generating code based on it. --- js-api-doc/deprecations.d.ts | 38 ++++++----- package-lock.json | 107 ++++++++++++++++++++++++++--- package.json | 9 ++- spec/deprecations.yaml | 112 +++++++++++++++++++++++++++++++ spec/js-api/deprecations.d.ts.md | 3 + test/deprecations-check.ts | 22 ++++++ tool/sync-deprecations.ts | 100 +++++++++++++++++++++++++++ 7 files changed, 360 insertions(+), 31 deletions(-) create mode 100644 spec/deprecations.yaml create mode 100644 test/deprecations-check.ts create mode 100644 tool/sync-deprecations.ts diff --git a/js-api-doc/deprecations.d.ts b/js-api-doc/deprecations.d.ts index 5f2f5053..390f361d 100644 --- a/js-api-doc/deprecations.d.ts +++ b/js-api-doc/deprecations.d.ts @@ -5,22 +5,25 @@ * `fatalDeprecations`, `futureDeprecations`, or `silenceDeprecations`. */ export interface Deprecations { + // START AUTOGENERATED LIST + // Checksum: 22d9bdbe92eb39b3c0d6d64ebe1879a431c0037e + /** - * Deprecation for passing a string to `call` instead of using `get-function`. + * Deprecation for passing a string directly to meta.call(). * - * This deprecation has been active in all versions of Dart Sass. + * This deprecation was active in the first version of Dart Sass. */ 'call-string': Deprecation<'call-string'>; /** - * Deprecation for `@elseif`. + * Deprecation for @elseif. * * This deprecation became active in Dart Sass 1.3.2. */ elseif: Deprecation<'elseif'>; /** - * Deprecation for parsing `@-moz-document`. + * Deprecation for @-moz-document. * * This deprecation became active in Dart Sass 1.7.2. */ @@ -29,27 +32,26 @@ export interface Deprecations { /** * Deprecation for imports using relative canonical URLs. * - * This deprecation became active in Dart Sass 1.17.2. + * This deprecation became active in Dart Sass 1.14.2. */ 'relative-canonical': Deprecation<'relative-canonical'>; /** - * Deprecation for declaring new variables with `!global`. + * Deprecation for declaring new variables with !global. * * This deprecation became active in Dart Sass 1.17.2. */ 'new-global': Deprecation<'new-global'>; /** - * Deprecation for using color module functions in place of plain CSS - * functions. + * Deprecation for using color module functions in place of plain CSS functions. * * This deprecation became active in Dart Sass 1.23.0. */ 'color-module-compat': Deprecation<'color-module-compat'>; /** - * Deprecation for treating `/` as division. + * Deprecation for / operator for division. * * This deprecation became active in Dart Sass 1.33.0. */ @@ -63,22 +65,21 @@ export interface Deprecations { 'bogus-combinators': Deprecation<'bogus-combinators'>; /** - * Deprecation for ambiguous `+` and `-` operators. + * Deprecation for ambiguous + and - operators. * * This deprecation became active in Dart Sass 1.55.0. */ 'strict-unary': Deprecation<'strict-unary'>; /** - * Deprecation for passing invalid units to certain built-in functions. + * Deprecation for passing invalid units to built-in functions. * * This deprecation became active in Dart Sass 1.56.0. */ 'function-units': Deprecation<'function-units'>; /** - * Deprecation for using `!default` or `!global` multiple times for one - * variable. + * Deprecation for using !default or !global multiple times for one variable. * * This deprecation became active in Dart Sass 1.62.0. */ @@ -92,34 +93,35 @@ export interface Deprecations { 'null-alpha': Deprecation<'null-alpha'>; /** - * Deprecation for passing percentages to the Sass `abs()` function. + * Deprecation for passing percentages to the Sass abs() function. * * This deprecation became active in Dart Sass 1.65.0. */ 'abs-percent': Deprecation<'abs-percent'>; /** - * Deprecation for using the current working directory as an implicit load - * path. + * Deprecation for using the current working directory as an implicit load path. * * This deprecation became active in Dart Sass 1.73.0. */ 'fs-importer-cwd': Deprecation<'fs-importer-cwd'>; /** - * Deprecation for function and mixin names beginning with `--`. + * Deprecation for function and mixin names beginning with --. * * This deprecation became active in Dart Sass 1.76.0. */ 'css-function-mixin': Deprecation<'css-function-mixin'>; /** - * Deprecation for `@import` rules. + * Deprecation for @import rules. * * This deprecation is not yet active, but will be soon. */ import: Deprecation<'import'>; + // END AUTOGENERATED LIST + /** * Used for any user-emitted deprecation warnings. */ diff --git a/package-lock.json b/package-lock.json index a451fd82..e7edb87d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "dependencies": { "@types/diff": "^5.0.1", "@types/glob": "^7.1.4", + "@types/js-yaml": "^4.0.3", "@types/marked": "^4.0.8", "@types/node": "^14.11.2", "@types/prettier": "^2.4.1", @@ -17,6 +18,7 @@ "gts": "^3.1.0", "immutable": "^4.0.0", "indent-string": "^4.0.0", + "js-yaml": "^4.1.0", "markdown-link-check": "3.11.1", "markdown-toc": "^1.2.0", "markdownlint-cli2": "^0.8.1", @@ -171,6 +173,18 @@ "node": ">= 4" } }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", @@ -326,6 +340,11 @@ "@types/node": "*" } }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -1388,6 +1407,18 @@ "node": ">= 4" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -1814,6 +1845,18 @@ "node": ">=0.10.0" } }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/gts": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/gts/-/gts-3.1.1.tgz", @@ -2210,17 +2253,21 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4311,6 +4358,15 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -4435,6 +4491,11 @@ "@types/node": "*" } }, + "@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -5065,6 +5126,15 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -5473,6 +5543,17 @@ "extend-shallow": "^2.0.1", "js-yaml": "^3.8.1", "toml": "^2.3.2" + }, + "dependencies": { + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "gts": { @@ -5761,12 +5842,18 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + } } }, "json-parse-even-better-errors": { diff --git a/package.json b/package.json index dbdafeba..7a2e480e 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,14 @@ "toc-check": "npx ts-node test/toc-check.ts", "update-toc": "npx ts-node tool/update-toc.ts", "js-api-doc-check": "npm run tangle && npx ts-node test/js-api-doc-check.ts", + "deprecations-check": "npx ts-node test/deprecations-check.ts", "typedoc": "npm run tangle && npx typedoc --treatWarningsAsErrors js-api-doc/index.d.ts", "tangle": "npx ts-node tool/tangle.ts", "untangle": "npx ts-node tool/untangle.ts", + "sync-deprecations": "npx ts-node tool/sync-deprecations.ts", "markdownlint": "npx markdownlint-cli2 '**/*.md' '*.md' --ignore 'node_modules/**'", - "fix": "npm run update-toc && npm run markdownlint -- --fix && npm run tangle && gts fix && npm run untangle", - "test": "npm run tangle && gts lint && tsc --noEmit && npm run toc-check && npm run link-check && npm run js-api-doc-check && npm run typedoc" + "fix": "npm run sync-deprecations && npm run update-toc && npm run markdownlint -- --fix && npm run tangle && gts fix && npm run untangle", + "test": "npm run deprecations-check && npm run tangle && gts lint && tsc --noEmit && npm run toc-check && npm run link-check && npm run js-api-doc-check && npm run typedoc" }, "dependencies": { "@types/diff": "^5.0.1", @@ -41,6 +43,7 @@ "ts-dedent": "^2.2.0", "ts-node": "^10.2.1", "typedoc": "^0.24.7", - "typescript": "^5.0.4" + "typescript": "^5.0.4", + "yaml": "^2.2.1" } } diff --git a/spec/deprecations.yaml b/spec/deprecations.yaml new file mode 100644 index 00000000..38be698f --- /dev/null +++ b/spec/deprecations.yaml @@ -0,0 +1,112 @@ +# This file specifies the status of all of Sass's deprecations in a +# machine-readable way. After updating this file, run +# `npm run sync-deprecations` to update the JS API spec and docs in this repo. +# +# The Dart Sass compiler and the Node embedded host use this file to generate +# their lists of deprecations. Other embedded hosts should do the same if they +# expose the list of deprecations in their APIs. +# +# example-id: +# description: One-line description of this deprecation. +# dart-sass: +# # Status of this deprecation in Dart Sass +# status: future | active | obsolete +# # Dart Sass version that deprecated this feature. +# deprecated: 1.0.0 +# # Dart Sass version that obsoleted this deprecation. +# obsolete: 2.0.0 + +call-string: + description: Passing a string directly to meta.call(). + dart-sass: + status: active + deprecated: 0.0.0 + +elseif: + description: "@elseif." + dart-sass: + status: active + deprecated: 1.3.2 + +moz-document: + description: "@-moz-document." + dart-sass: + status: active + deprecated: 1.7.2 + +relative-canonical: + description: Imports using relative canonical URLs. + dart-sass: + status: active + deprecated: 1.14.2 + +new-global: + description: Declaring new variables with !global. + dart-sass: + status: active + deprecated: 1.17.2 + +color-module-compat: + description: Using color module functions in place of plain CSS functions. + dart-sass: + status: active + deprecated: 1.23.0 + +slash-div: + description: / operator for division. + dart-sass: + status: active + deprecated: 1.33.0 + +bogus-combinators: + description: Leading, trailing, and repeated combinators. + dart-sass: + status: active + deprecated: 1.54.0 + +strict-unary: + description: Ambiguous + and - operators. + dart-sass: + status: active + deprecated: 1.55.0 + +function-units: + description: Passing invalid units to built-in functions. + dart-sass: + status: active + deprecated: 1.56.0 + +duplicate-var-flags: + description: Using !default or !global multiple times for one variable. + dart-sass: + status: active + deprecated: 1.62.0 + +null-alpha: + description: Passing null as alpha in the $PLATFORM API. + dart-sass: + status: active + deprecated: 1.62.3 + +abs-percent: + description: Passing percentages to the Sass abs() function. + dart-sass: + status: active + deprecated: 1.65.0 + +fs-importer-cwd: + description: Using the current working directory as an implicit load path. + dart-sass: + status: active + deprecated: 1.73.0 + +css-function-mixin: + description: Function and mixin names beginning with --. + dart-sass: + status: active + deprecated: 1.76.0 + +import: + description: "@import rules." + dart-sass: + status: future diff --git a/spec/js-api/deprecations.d.ts.md b/spec/js-api/deprecations.d.ts.md index 1017bc4a..27c130f1 100644 --- a/spec/js-api/deprecations.d.ts.md +++ b/spec/js-api/deprecations.d.ts.md @@ -28,6 +28,8 @@ ### `Deprecations` + + ```ts export interface Deprecations { 'call-string': Deprecation<'call-string'>; @@ -49,6 +51,7 @@ export interface Deprecations { 'user-authored': Deprecation<'user-authored', 'user'>; } ``` + ### `DeprecationOrId` diff --git a/test/deprecations-check.ts b/test/deprecations-check.ts new file mode 100644 index 00000000..5b373a65 --- /dev/null +++ b/test/deprecations-check.ts @@ -0,0 +1,22 @@ +import * as crypto from 'crypto'; +import * as fs from 'fs'; + +const yamlFile = 'spec/deprecations.yaml'; +const specFile = 'spec/js-api/deprecations.d.ts.md'; +const docFile = 'js-api-doc/deprecations.d.ts'; + +(async () => { + const yamlText = fs.readFileSync(yamlFile, 'utf8'); + const specText = fs.readFileSync(specFile, 'utf8'); + const docText = fs.readFileSync(docFile, 'utf8'); + + const checksum = crypto.createHash('sha1').update(yamlText).digest('hex'); + + if ( + !specText.includes(``) || + !docText.includes(`// Checksum: ${checksum}`) + ) { + console.error('Deprecations out-of-sync. Run `npm run sync-deprecations`.'); + process.exitCode = 1; + } +})(); diff --git a/tool/sync-deprecations.ts b/tool/sync-deprecations.ts new file mode 100644 index 00000000..49861f9f --- /dev/null +++ b/tool/sync-deprecations.ts @@ -0,0 +1,100 @@ +// Updates the JS API spec and docs with the list of deprecations specified +// in spec/deprecations.yaml. + +import * as colors from 'colors/safe'; +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import {parse} from 'yaml'; + +interface YamlData { + [key: string]: { + description: string; + 'dart-sass': { + status: 'active' | 'future' | 'obsolete'; + deprecated?: string; + obsolete?: string; + }; + }; +} + +const yamlFile = 'spec/deprecations.yaml'; +const specFile = 'spec/js-api/deprecations.d.ts.md'; +const docFile = 'js-api-doc/deprecations.d.ts'; + +const specRegex = + /[\s\S]*?/m; +const docRegex = + /\/\/ START AUTOGENERATED LIST[\s\S]*?\/\/ END AUTOGENERATED LIST/m; + +(async () => { + const yamlText = fs.readFileSync(yamlFile, 'utf8'); + const oldSpecText = fs.readFileSync(specFile, 'utf8'); + const oldDocText = fs.readFileSync(docFile, 'utf8'); + + if (!specRegex.test(oldSpecText)) { + console.error( + `${colors.red(colors.bold('Error:'))} ` + + `Cannot find AUTOGENERATED LIST block in ${specFile}` + ); + process.exitCode = 1; + return; + } + if (!docRegex.test(oldDocText)) { + console.error( + `${colors.red(colors.bold('Error:'))} ` + + `Cannot find AUTOGENERATED LIST block in ${docFile}` + ); + process.exitCode = 1; + return; + } + + const deprecations = parse(yamlText) as YamlData; + let specList = ''; + let docList = ''; + for (const [id, deprecation] of Object.entries(deprecations)) { + const key = id.includes('-') ? `'${id}'` : id; + specList += ` ${key}: Deprecation<'${id}'>;\n`; + const lowercase = + deprecation.description.substring(0, 1).toLowerCase() + + deprecation.description.substring(1); + const dartSass = deprecation['dart-sass']; + const activeText = !dartSass.deprecated + ? 'This deprecation is not yet active, but will be soon.' + : dartSass.deprecated === '0.0.0' + ? 'This deprecation was active in the first version of Dart Sass.' + : `This deprecation became active in Dart Sass ${dartSass.deprecated}.`; + const obsoleteText = dartSass.obsolete + ? `\nIt became obsolete in Dart Sass ${dartSass.obsolete}.` + : ''; + docList += ` /** + * Deprecation for ${lowercase.replace(/\$PLATFORM/g, 'JS')} + * + * ${activeText}${obsoleteText} + */ + ${key}: Deprecation<'${id}'>;\n\n`; + } + const checksum = crypto.createHash('sha1').update(yamlText).digest('hex'); + + const newSpecText = oldSpecText.replace( + /[\s\S]*?/m, + ` + +\`\`\`ts +export interface Deprecations { +${specList} 'user-authored': Deprecation<'user-authored', 'user'>; +} +\`\`\` +` + ); + + const newDocText = oldDocText.replace( + /\/\/ START AUTOGENERATED LIST[\s\S]*?\/\/ END AUTOGENERATED LIST/m, + `// START AUTOGENERATED LIST + // Checksum: ${checksum} + +${docList} // END AUTOGENERATED LIST` + ); + + fs.writeFileSync(specFile, newSpecText); + fs.writeFileSync(docFile, newDocText); +})();