@depup/postcss 8.5.8-depup.0 → 8.5.21-depup.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.
@@ -1,5 +1,21 @@
1
1
  'use strict'
2
2
 
3
+ // Escapes sequences that could break out of an HTML <style> context.
4
+ // Uses CSS unicode escaping (\3c = '<') which is valid CSS and parsed
5
+ // correctly by all compliant CSS consumers.
6
+ const STYLE_TAG = /(<)(\/?style\b)/gi
7
+ const COMMENT_OPEN = /(<)(!--)/g
8
+
9
+ // Characters that end an at-rule name, mirroring RE_AT_END in the tokenizer.
10
+ // Params starting with anything else need a space to stay separate tokens.
11
+ const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/
12
+
13
+ function escapeHTMLInCSS(str) {
14
+ if (typeof str !== 'string') return str
15
+ if (!str.includes('<')) return str
16
+ return str.replace(STYLE_TAG, '\\3c $2').replace(COMMENT_OPEN, '\\3c $2')
17
+ }
18
+
3
19
  const DEFAULT_RAW = {
4
20
  after: '\n',
5
21
  beforeClose: '\n',
@@ -19,26 +35,88 @@ function capitalize(str) {
19
35
  return str[0].toUpperCase() + str.slice(1)
20
36
  }
21
37
 
38
+ function atruleStart(str, node) {
39
+ let name = '@' + node.name
40
+ let params = node.params ? str.rawValue(node, 'params') : ''
41
+ let afterName = node.raws.afterName
42
+
43
+ if (typeof afterName === 'undefined') {
44
+ afterName = params ? ' ' : ''
45
+ } else if (afterName === '' && params && !AT_NAME_END.test(params[0])) {
46
+ afterName = ' '
47
+ }
48
+
49
+ return name + afterName + params
50
+ }
51
+
52
+ function pushBody(str, stack, node) {
53
+ let nodes = node.nodes
54
+ let last = nodes.length - 1
55
+ while (last > 0) {
56
+ if (nodes[last].type !== 'comment') break
57
+ last -= 1
58
+ }
59
+
60
+ let semicolon = str.raw(node, 'semicolon')
61
+ let isDocument = node.type === 'document'
62
+ for (let i = nodes.length - 1; i >= 0; i--) {
63
+ let child = nodes[i]
64
+ let childSemicolon = last !== i || semicolon
65
+ // A childless at-rule that still has following siblings must be
66
+ // terminated. Without the semicolon those trailing comments are folded
67
+ // into the at-rule's prelude and disappear when the output is re-parsed.
68
+ if (
69
+ !childSemicolon &&
70
+ i < nodes.length - 1 &&
71
+ child.type === 'atrule' &&
72
+ !child.nodes
73
+ ) {
74
+ childSemicolon = true
75
+ }
76
+ stack.push({
77
+ document: isDocument,
78
+ node: child,
79
+ semicolon: childSemicolon
80
+ })
81
+ }
82
+ }
83
+
84
+ function pushBlock(str, stack, node, start) {
85
+ let between = str.raw(node, 'between', 'beforeOpen')
86
+ str.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')
87
+
88
+ let hasNodes = node.nodes && node.nodes.length
89
+ let close = () => {
90
+ let after = hasNodes
91
+ ? str.raw(node, 'after')
92
+ : str.raw(node, 'after', 'emptyBody')
93
+ if (after) str.builder(escapeHTMLInCSS(after))
94
+ str.builder('}', node, 'end')
95
+ if (node.type === 'rule' && node.raws.ownSemicolon) {
96
+ str.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')
97
+ }
98
+ }
99
+
100
+ if (hasNodes) {
101
+ stack.push(close)
102
+ pushBody(str, stack, node)
103
+ } else {
104
+ close()
105
+ }
106
+ }
107
+
22
108
  class Stringifier {
23
109
  constructor(builder) {
24
110
  this.builder = builder
25
111
  }
26
112
 
27
113
  atrule(node, semicolon) {
28
- let name = '@' + node.name
29
- let params = node.params ? this.rawValue(node, 'params') : ''
30
-
31
- if (typeof node.raws.afterName !== 'undefined') {
32
- name += node.raws.afterName
33
- } else if (params) {
34
- name += ' '
35
- }
36
-
114
+ let start = atruleStart(this, node)
37
115
  if (node.nodes) {
38
- this.block(node, name + params)
116
+ this.block(node, start)
39
117
  } else {
40
118
  let end = (node.raws.between || '') + (semicolon ? ';' : '')
41
- this.builder(name + params + end, node)
119
+ this.builder(escapeHTMLInCSS(start + end), node)
42
120
  }
43
121
  }
44
122
 
@@ -73,7 +151,7 @@ class Stringifier {
73
151
 
74
152
  block(node, start) {
75
153
  let between = this.raw(node, 'between', 'beforeOpen')
76
- this.builder(start + between + '{', node, 'start')
154
+ this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')
77
155
 
78
156
  let after
79
157
  if (node.nodes && node.nodes.length) {
@@ -83,42 +161,64 @@ class Stringifier {
83
161
  after = this.raw(node, 'after', 'emptyBody')
84
162
  }
85
163
 
86
- if (after) this.builder(after)
164
+ if (after) this.builder(escapeHTMLInCSS(after))
87
165
  this.builder('}', node, 'end')
88
166
  }
89
167
 
90
168
  body(node) {
91
- let last = node.nodes.length - 1
92
- while (last > 0) {
93
- if (node.nodes[last].type !== 'comment') break
94
- last -= 1
95
- }
169
+ // Rules and at-rules are expanded into an explicit stack instead of
170
+ // recursive `stringify()` calls to survive deeply nested trees.
171
+ // If a subclass changes the traversal methods, its children go
172
+ // through `stringify()` to keep the override in charge.
173
+ let proto = Stringifier.prototype
174
+ let expandable = ['atrule', 'block', 'body', 'rule', 'stringify'].every(
175
+ method => this[method] === proto[method]
176
+ )
177
+
178
+ let stack = []
179
+ pushBody(this, stack, node)
180
+
181
+ while (stack.length > 0) {
182
+ let entry = stack.pop()
183
+ if (typeof entry === 'function') {
184
+ entry()
185
+ continue
186
+ }
96
187
 
97
- let semicolon = this.raw(node, 'semicolon')
98
- for (let i = 0; i < node.nodes.length; i++) {
99
- let child = node.nodes[i]
188
+ let child = entry.node
100
189
  let before = this.raw(child, 'before')
101
- if (before) this.builder(before)
102
- this.stringify(child, last !== i || semicolon)
190
+ if (before) {
191
+ this.builder(entry.document ? before : escapeHTMLInCSS(before))
192
+ }
193
+
194
+ if (expandable && child.type === 'rule') {
195
+ pushBlock(this, stack, child, this.rawValue(child, 'selector'))
196
+ } else if (expandable && child.type === 'atrule' && child.nodes) {
197
+ pushBlock(this, stack, child, atruleStart(this, child))
198
+ } else {
199
+ this.stringify(child, entry.semicolon)
200
+ }
103
201
  }
104
202
  }
105
203
 
106
204
  comment(node) {
107
205
  let left = this.raw(node, 'left', 'commentLeft')
108
206
  let right = this.raw(node, 'right', 'commentRight')
109
- this.builder('/*' + left + node.text + right + '*/', node)
207
+ this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node)
110
208
  }
111
209
 
112
210
  decl(node, semicolon) {
211
+ let raws = node.raws
113
212
  let between = this.raw(node, 'between', 'colon')
213
+
114
214
  let string = node.prop + between + this.rawValue(node, 'value')
115
215
 
116
216
  if (node.important) {
117
- string += node.raws.important || ' !important'
217
+ string += raws.important || ' !important'
118
218
  }
119
219
 
120
220
  if (semicolon) string += ';'
121
- this.builder(string, node)
221
+ this.builder(escapeHTMLInCSS(string), node)
122
222
  }
123
223
 
124
224
  document(node) {
@@ -154,9 +254,9 @@ class Stringifier {
154
254
 
155
255
  // Detect style by other nodes
156
256
  let root = node.root()
157
- if (!root.rawCache) root.rawCache = {}
158
- if (typeof root.rawCache[detect] !== 'undefined') {
159
- return root.rawCache[detect]
257
+ let cache = root.rawCache || (root.rawCache = {})
258
+ if (typeof cache[detect] !== 'undefined') {
259
+ return cache[detect]
160
260
  }
161
261
 
162
262
  if (detect === 'before' || detect === 'after') {
@@ -175,7 +275,7 @@ class Stringifier {
175
275
 
176
276
  if (typeof value === 'undefined') value = DEFAULT_RAW[detect]
177
277
 
178
- root.rawCache[detect] = value
278
+ cache[detect] = value
179
279
  return value
180
280
  }
181
281
 
@@ -324,13 +424,17 @@ class Stringifier {
324
424
 
325
425
  root(node) {
326
426
  this.body(node)
327
- if (node.raws.after) this.builder(node.raws.after)
427
+ if (node.raws.after) {
428
+ let after = node.raws.after
429
+ let isDocument = node.parent && node.parent.type === 'document'
430
+ this.builder(isDocument ? after : escapeHTMLInCSS(after))
431
+ }
328
432
  }
329
433
 
330
434
  rule(node) {
331
435
  this.block(node, this.rawValue(node, 'selector'))
332
436
  if (node.raws.ownSemicolon) {
333
- this.builder(node.raws.ownSemicolon, node, 'end')
437
+ this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')
334
438
  }
335
439
  }
336
440
 
@@ -4,6 +4,6 @@ interface Stringify extends Stringifier {
4
4
  default: Stringify
5
5
  }
6
6
 
7
- declare const stringify: Stringify
7
+ declare let stringify: Stringify
8
8
 
9
9
  export = stringify
package/lib/tokenize.js CHANGED
@@ -36,6 +36,7 @@ module.exports = function tokenizer(input, options = {}) {
36
36
  let pos = 0
37
37
  let buffer = []
38
38
  let returned = []
39
+ let lastBadParen = -1
39
40
 
40
41
  function position() {
41
42
  return pos
@@ -127,11 +128,14 @@ module.exports = function tokenizer(input, options = {}) {
127
128
  currentToken = ['brackets', css.slice(pos, next + 1), pos, next]
128
129
 
129
130
  pos = next
131
+ } else if (pos <= lastBadParen) {
132
+ currentToken = ['(', '(', pos]
130
133
  } else {
131
134
  next = css.indexOf(')', pos + 1)
132
135
  content = css.slice(pos, next + 1)
133
136
 
134
137
  if (next === -1 || RE_BAD_BRACKET.test(content)) {
138
+ lastBadParen = next === -1 ? length : next
135
139
  currentToken = ['(', '(', pos]
136
140
  } else {
137
141
  currentToken = ['brackets', content, pos, next]
package/lib/warning.d.ts CHANGED
@@ -40,7 +40,6 @@ declare namespace Warning {
40
40
  word?: string
41
41
  }
42
42
 
43
-
44
43
  export { Warning_ as default }
45
44
  }
46
45
 
package/lib/warning.js CHANGED
@@ -1,11 +1,21 @@
1
1
  'use strict'
2
2
 
3
+ let Container = require('./container')
4
+ let { my } = require('./symbols')
5
+
3
6
  class Warning {
4
7
  constructor(text, opts = {}) {
5
8
  this.type = 'warning'
6
9
  this.text = text
7
10
 
8
11
  if (opts.node && opts.node.source) {
12
+ if (!opts.node[my]) {
13
+ // The node comes from another PostCSS copy in node_modules, so it does
14
+ // not have this copy’s methods. Container#normalize() rebuilds such
15
+ // nodes on insert, but a node passed straight to Result#warn() never
16
+ // goes through it.
17
+ Container.rebuild(opts.node)
18
+ }
9
19
  let range = opts.node.rangeBy(opts)
10
20
  this.line = range.start.line
11
21
  this.column = range.start.column
package/package.json CHANGED
@@ -1,10 +1,53 @@
1
1
  {
2
2
  "name": "@depup/postcss",
3
- "version": "8.5.8-depup.0",
4
- "description": "[DepUp] Tool for transforming styles with JS plugins",
5
- "engines": {
6
- "node": "^10 || ^12 || >=14"
3
+ "version": "8.5.21-depup.0",
4
+ "description": "Tool for transforming styles with JS plugins (with updated dependencies)",
5
+ "keywords": [
6
+ "postcss",
7
+ "depup",
8
+ "updated-dependencies",
9
+ "security",
10
+ "latest",
11
+ "patched",
12
+ "css",
13
+ "manipulation",
14
+ "parser",
15
+ "preprocessor",
16
+ "rework",
17
+ "source map",
18
+ "transform",
19
+ "transpiler"
20
+ ],
21
+ "homepage": "https://postcss.org/",
22
+ "bugs": {
23
+ "url": "https://github.com/postcss/postcss/issues"
24
+ },
25
+ "license": "MIT",
26
+ "author": "Andrey Sitnik <andrey@sitnik.es>",
27
+ "repository": "postcss/postcss",
28
+ "funding": [
29
+ {
30
+ "type": "opencollective",
31
+ "url": "https://opencollective.com/postcss/"
32
+ },
33
+ {
34
+ "type": "tidelift",
35
+ "url": "https://tidelift.com/funding/github/npm/postcss"
36
+ },
37
+ {
38
+ "type": "github",
39
+ "url": "https://github.com/sponsors/ai"
40
+ }
41
+ ],
42
+ "main": "./lib/postcss.js",
43
+ "browser": {
44
+ "./lib/terminal-highlight": false,
45
+ "source-map-js": false,
46
+ "path": false,
47
+ "url": false,
48
+ "fs": false
7
49
  },
50
+ "types": "./lib/postcss.d.ts",
8
51
  "exports": {
9
52
  ".": {
10
53
  "import": "./lib/postcss.mjs",
@@ -39,66 +82,25 @@
39
82
  "./lib/warning": "./lib/warning.js",
40
83
  "./package.json": "./package.json"
41
84
  },
42
- "main": "./lib/postcss.js",
43
- "types": "./lib/postcss.d.ts",
44
- "keywords": [
45
- "depup",
46
- "dependency-bumped",
47
- "updated-deps",
48
- "postcss",
49
- "css",
50
- "rework",
51
- "preprocessor",
52
- "parser",
53
- "source map",
54
- "transform",
55
- "manipulation",
56
- "transpiler"
57
- ],
58
- "funding": [
59
- {
60
- "type": "opencollective",
61
- "url": "https://opencollective.com/postcss/"
62
- },
63
- {
64
- "type": "tidelift",
65
- "url": "https://tidelift.com/funding/github/npm/postcss"
66
- },
67
- {
68
- "type": "github",
69
- "url": "https://github.com/sponsors/ai"
70
- }
71
- ],
72
- "author": "Andrey Sitnik <andrey@sitnik.ru>",
73
- "license": "MIT",
74
- "homepage": "https://postcss.org/",
75
- "repository": "postcss/postcss",
76
- "bugs": {
77
- "url": "https://github.com/postcss/postcss/issues"
78
- },
79
85
  "dependencies": {
80
- "nanoid": "^5.1.6",
86
+ "nanoid": "^6.0.0",
81
87
  "picocolors": "^1.1.1",
82
88
  "source-map-js": "^1.2.1"
83
89
  },
84
- "browser": {
85
- "./lib/terminal-highlight": false,
86
- "source-map-js": false,
87
- "path": false,
88
- "url": false,
89
- "fs": false
90
+ "engines": {
91
+ "node": "^10 || ^12 || >=14"
90
92
  },
91
93
  "depup": {
92
94
  "changes": {
93
95
  "nanoid": {
94
- "from": "^3.3.11",
95
- "to": "^5.1.6"
96
+ "from": "^3.3.16",
97
+ "to": "^6.0.0"
96
98
  }
97
99
  },
98
100
  "depsUpdated": 1,
99
101
  "originalPackage": "postcss",
100
- "originalVersion": "8.5.8",
101
- "processedAt": "2026-03-09T04:19:08.351Z",
102
+ "originalVersion": "8.5.21",
103
+ "processedAt": "2026-07-21T17:29:18.301Z",
102
104
  "smokeTest": "passed"
103
105
  }
104
106
  }