cdk-common 2.1.33 → 2.1.34

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.
package/.jsii CHANGED
@@ -3943,7 +3943,7 @@
3943
3943
  "stability": "experimental"
3944
3944
  },
3945
3945
  "homepage": "https://github.com/neilkuan/cdk-common.git",
3946
- "jsiiVersion": "5.9.37 (build 5176c0d)",
3946
+ "jsiiVersion": "5.9.39 (build cdf85b4)",
3947
3947
  "keywords": [
3948
3948
  "aws",
3949
3949
  "aws-cdk",
@@ -12984,6 +12984,6 @@
12984
12984
  "symbolId": "src/main:LambdaArmFunctionProps"
12985
12985
  }
12986
12986
  },
12987
- "version": "2.1.33",
12988
- "fingerprint": "TZIlr4chMoocsv+OgvSlkzU61k1HDWVIPNW4uujRGqA="
12987
+ "version": "2.1.34",
12988
+ "fingerprint": "bxGvPWwwiFW3GKNhsAtpY0JPXV7h0YO7m5vqBPxFhvQ="
12989
12989
  }
package/lib/main.js CHANGED
@@ -38,5 +38,5 @@ class LambdaArmFunction extends constructs_1.Construct {
38
38
  }
39
39
  exports.LambdaArmFunction = LambdaArmFunction;
40
40
  _a = JSII_RTTI_SYMBOL_1;
41
- LambdaArmFunction[_a] = { fqn: "cdk-common.LambdaArmFunction", version: "2.1.33" };
41
+ LambdaArmFunction[_a] = { fqn: "cdk-common.LambdaArmFunction", version: "2.1.34" };
42
42
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQW1DO0FBQ25DLGlEQUFpRDtBQUNqRCwyQ0FBdUM7QUFLdkMsTUFBYSxpQkFBa0IsU0FBUSxzQkFBUztJQUU5QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTRCO1FBQ3BFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQXlCO1lBQ3RELENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsbUNBQW1DLENBQUM7WUFDakUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxtQ0FBbUMsQ0FBQztZQUNqRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLG1DQUFtQyxDQUFDO1lBQ2pFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsa0NBQWtDLENBQUM7WUFDaEUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxrQ0FBa0MsQ0FBQztZQUNoRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLGtDQUFrQyxDQUFDO1lBQ2hFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsa0NBQWtDLENBQUM7WUFDaEUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSw4QkFBOEIsQ0FBQztZQUN4RCxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLDhCQUE4QixDQUFDO1lBQ3hELENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsNkJBQTZCLENBQUM7WUFDeEQsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSwrQkFBK0IsQ0FBQztZQUMxRCxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLCtCQUErQixDQUFDO1NBQzNELENBQUMsQ0FBQztRQUVILE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25ELElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0MsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixLQUFLLENBQUMsT0FBTyx1R0FBdUcsQ0FBQyxDQUFDO1FBQzNKLENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDaEUsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNO1lBQzlELEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7O0FBL0JILDhDQWdDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmV4cG9ydCBpbnRlcmZhY2UgTGFtYmRhQXJtRnVuY3Rpb25Qcm9wcyBleHRlbmRzIGxhbWJkYS5GdW5jdGlvblByb3BzIHtcblxufVxuXG5leHBvcnQgY2xhc3MgTGFtYmRhQXJtRnVuY3Rpb24gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhRnVuY3Rpb246IGxhbWJkYS5GdW5jdGlvbjtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6TGFtYmRhQXJtRnVuY3Rpb25Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBydW50aW1lV2FybmluZ3MgPSBuZXcgTWFwPGxhbWJkYS5SdW50aW1lLCBzdHJpbmc+KFtcbiAgICAgIFtsYW1iZGEuUnVudGltZS5OT0RFSlNfMjJfWCwgJ1lvdSBhcmUgdXNpbmcgTm9kZS5qcyAyMi54IGF0IEFSTSddLFxuICAgICAgW2xhbWJkYS5SdW50aW1lLk5PREVKU18yMF9YLCAnWW91IGFyZSB1c2luZyBOb2RlLmpzIDIwLnggYXQgQVJNJ10sXG4gICAgICBbbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzE4X1gsICdZb3UgYXJlIHVzaW5nIE5vZGUuanMgMTgueCBhdCBBUk0nXSxcbiAgICAgIFtsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMywgJ1lvdSBhcmUgdXNpbmcgUHl0aG9uIDMuMTMgYXQgQVJNJ10sXG4gICAgICBbbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfMTIsICdZb3UgYXJlIHVzaW5nIFB5dGhvbiAzLjEyIGF0IEFSTSddLFxuICAgICAgW2xhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzExLCAnWW91IGFyZSB1c2luZyBQeXRob24gMy4xMSBhdCBBUk0nXSxcbiAgICAgIFtsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMCwgJ1lvdSBhcmUgdXNpbmcgUHl0aG9uIDMuMTAgYXQgQVJNJ10sXG4gICAgICBbbGFtYmRhLlJ1bnRpbWUuSkFWQV8yMSwgJ1lvdSBhcmUgdXNpbmcgSmF2YSAyMSBhdCBBUk0nXSxcbiAgICAgIFtsYW1iZGEuUnVudGltZS5KQVZBXzE3LCAnWW91IGFyZSB1c2luZyBKYXZhIDE3IGF0IEFSTSddLFxuICAgICAgW2xhbWJkYS5SdW50aW1lLkRPVE5FVF84LCAnWW91IGFyZSB1c2luZyAuTkVUIDggYXQgQVJNJ10sXG4gICAgICBbbGFtYmRhLlJ1bnRpbWUuUlVCWV8zXzQsICdZb3UgYXJlIHVzaW5nIFJ1YnkgMy40IGF0IEFSTSddLFxuICAgICAgW2xhbWJkYS5SdW50aW1lLlJVQllfM18zLCAnWW91IGFyZSB1c2luZyBSdWJ5IDMuMyBhdCBBUk0nXSxcbiAgICBdKTtcblxuICAgIGNvbnN0IHdhcm5pbmcgPSBydW50aW1lV2FybmluZ3MuZ2V0KHByb3BzLnJ1bnRpbWUpO1xuICAgIGlmICh3YXJuaW5nKSB7XG4gICAgICBjZGsuQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZyh3YXJuaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFJ1bnRpbWUgJHtwcm9wcy5ydW50aW1lfSBhdCBBUk0sIFNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9mb3VuZGF0aW9uLWFyY2guaHRtbD9pY21waWQ9ZG9jc19sYW1iZGFfcnNzYCk7XG4gICAgfVxuXG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgJ0xhbWJkYUZ1bmN0aW9uJywge1xuICAgICAgYXJjaGl0ZWN0dXJlOiBwcm9wcy5hcmNoaXRlY3R1cmUgPz8gbGFtYmRhLkFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -14,6 +14,11 @@ on:
14
14
  - 'docs/**'
15
15
  - '*.md'
16
16
 
17
+ # This allows a subsequently queued workflow run to interrupt previous runs
18
+ concurrency:
19
+ group: "${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
20
+ cancel-in-progress: true
21
+
17
22
  permissions:
18
23
  contents: read
19
24
 
@@ -24,11 +29,11 @@ jobs:
24
29
  permissions:
25
30
  contents: read
26
31
  steps:
27
- - uses: actions/checkout@v4
32
+ - uses: actions/checkout@v6
28
33
  with:
29
34
  persist-credentials: false
30
35
 
31
- - uses: actions/setup-node@v4
36
+ - uses: actions/setup-node@v6
32
37
  with:
33
38
  node-version: '10'
34
39
  cache: 'npm'
@@ -66,11 +71,11 @@ jobs:
66
71
  permissions:
67
72
  contents: read
68
73
  steps:
69
- - uses: actions/checkout@v4
74
+ - uses: actions/checkout@v6
70
75
  with:
71
76
  persist-credentials: false
72
77
 
73
- - uses: actions/setup-node@v4
78
+ - uses: actions/setup-node@v6
74
79
  with:
75
80
  node-version: '24'
76
81
  cache: 'npm'
@@ -80,21 +85,21 @@ jobs:
80
85
  - name: Install dependencies
81
86
  run: |
82
87
  npm install --ignore-scripts
83
-
88
+
84
89
  - if: ${{ matrix.os == 'windows-latest' }}
85
90
  run: npx playwright install winldd
86
91
 
87
92
  - name: Run browser tests
88
93
  run: |
89
94
  npm run test:browser:${{ matrix.browser }}
90
-
95
+
91
96
  test:
92
97
  needs:
93
98
  - test-regression-check-node10
94
99
  permissions:
95
100
  contents: write
96
101
  pull-requests: write
97
- uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
102
+ uses: fastify/workflows/.github/workflows/plugins-ci.yml@v6
98
103
  with:
99
104
  license-check: true
100
105
  lint: true
@@ -0,0 +1,19 @@
1
+ name: Lock Threads
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 1 * *'
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: lock
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ lock-threads:
16
+ permissions:
17
+ issues: write
18
+ pull-requests: write
19
+ uses: fastify/workflows/.github/workflows/lock-threads.yml@v6
@@ -21,4 +21,4 @@ jobs:
21
21
  test:
22
22
  permissions:
23
23
  contents: read
24
- uses: fastify/workflows/.github/workflows/plugins-ci-package-manager.yml@v5
24
+ uses: fastify/workflows/.github/workflows/plugins-ci-package-manager.yml@v6
@@ -1,9 +1,7 @@
1
1
  Copyright (c) 2011-2021, Gary Court until https://github.com/garycourt/uri-js/commit/a1acf730b4bba3f1097c9f52e7d9d3aba8cdcaae
2
- Copyright (c) 2021-present The Fastify team
2
+ Copyright (c) 2021-present The Fastify team <https://github.com/fastify/fastify#team>
3
3
  All rights reserved.
4
4
 
5
- The Fastify team members are listed at https://github.com/fastify/fastify#team.
6
-
7
5
  Redistribution and use in source and binary forms, with or without
8
6
  modification, are permitted provided that the following conditions are met:
9
7
  * Redistributions of source code must retain the above copyright
@@ -1,13 +1,9 @@
1
1
  # fast-uri
2
2
 
3
- <div align="center">
4
-
5
3
  [![NPM version](https://img.shields.io/npm/v/fast-uri.svg?style=flat)](https://www.npmjs.com/package/fast-uri)
6
4
  [![CI](https://github.com/fastify/fast-uri/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fast-uri/actions/workflows/ci.yml)
7
5
  [![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)
8
6
 
9
- </div>
10
-
11
7
  Dependency-free RFC 3986 URI toolbox.
12
8
 
13
9
  ## Usage
@@ -70,6 +66,17 @@ uri.resolve("uri://a/b/c/d?q", "../../g")
70
66
  "uri://a/g"
71
67
  ```
72
68
 
69
+ ### Normalize
70
+
71
+ ```js
72
+ const uri = require('fast-uri')
73
+ uri.normalize('http://example.com/a%2Fb')
74
+ // Output
75
+ "http://example.com/a%2Fb"
76
+ ```
77
+
78
+ Reserved path escapes such as `%2F` and `%2E` are preserved as path data during normalization and comparison.
79
+
73
80
  ### Equal
74
81
 
75
82
  ```js
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require('./lib/utils')
3
+ const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, isIPv4, nonSimpleDomain } = require('./lib/utils')
4
4
  const { SCHEMES, getSchemeHandler } = require('./lib/schemes')
5
5
 
6
6
  /**
@@ -107,17 +107,15 @@ function resolveComponent (base, relative, options, skipNormalization) {
107
107
  */
108
108
  function equal (uriA, uriB, options) {
109
109
  if (typeof uriA === 'string') {
110
- uriA = unescape(uriA)
111
- uriA = serialize(normalizeComponentEncoding(parse(uriA, options), true), { ...options, skipEscape: true })
110
+ uriA = serialize(parse(uriA, options), options)
112
111
  } else if (typeof uriA === 'object') {
113
- uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true })
112
+ uriA = serialize(uriA, options)
114
113
  }
115
114
 
116
115
  if (typeof uriB === 'string') {
117
- uriB = unescape(uriB)
118
- uriB = serialize(normalizeComponentEncoding(parse(uriB, options), true), { ...options, skipEscape: true })
116
+ uriB = serialize(parse(uriB, options), options)
119
117
  } else if (typeof uriB === 'object') {
120
- uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true })
118
+ uriB = serialize(uriB, options)
121
119
  }
122
120
 
123
121
  return uriA.toLowerCase() === uriB.toLowerCase()
@@ -156,13 +154,13 @@ function serialize (cmpts, opts) {
156
154
 
157
155
  if (component.path !== undefined) {
158
156
  if (!options.skipEscape) {
159
- component.path = escape(component.path)
157
+ component.path = escapePreservingEscapes(component.path)
160
158
 
161
159
  if (component.scheme !== undefined) {
162
160
  component.path = component.path.split('%3A').join(':')
163
161
  }
164
162
  } else {
165
- component.path = unescape(component.path)
163
+ component.path = normalizePercentEncoding(component.path)
166
164
  }
167
165
  }
168
166
 
@@ -308,7 +306,7 @@ function parse (uri, opts) {
308
306
  }
309
307
  }
310
308
  if (parsed.path) {
311
- parsed.path = escape(unescape(parsed.path))
309
+ parsed.path = normalizePathEncoding(parsed.path)
312
310
  }
313
311
  if (parsed.fragment) {
314
312
  parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment))
@@ -6,6 +6,15 @@ const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\d
6
6
  /** @type {(value: string) => boolean} */
7
7
  const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u)
8
8
 
9
+ /** @type {(value: string) => boolean} */
10
+ const isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu)
11
+
12
+ /** @type {(value: string) => boolean} */
13
+ const isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu)
14
+
15
+ /** @type {(value: string) => boolean} */
16
+ const isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu)
17
+
9
18
  /**
10
19
  * @param {Array<string>} input
11
20
  * @returns {string}
@@ -264,31 +273,106 @@ function removeDotSegments (path) {
264
273
  }
265
274
 
266
275
  /**
267
- * @param {import('../types/index').URIComponent} component
268
- * @param {boolean} esc
269
- * @returns {import('../types/index').URIComponent}
276
+ * Normalizes percent escapes and optionally decodes only unreserved ASCII bytes.
277
+ * Reserved delimiters such as `%2F` and `%2E` stay escaped.
278
+ *
279
+ * @param {string} input
280
+ * @param {boolean} [decodeUnreserved=false]
281
+ * @returns {string}
270
282
  */
271
- function normalizeComponentEncoding (component, esc) {
272
- const func = esc !== true ? escape : unescape
273
- if (component.scheme !== undefined) {
274
- component.scheme = func(component.scheme)
275
- }
276
- if (component.userinfo !== undefined) {
277
- component.userinfo = func(component.userinfo)
283
+ function normalizePercentEncoding (input, decodeUnreserved = false) {
284
+ if (input.indexOf('%') === -1) {
285
+ return input
278
286
  }
279
- if (component.host !== undefined) {
280
- component.host = func(component.host)
281
- }
282
- if (component.path !== undefined) {
283
- component.path = func(component.path)
287
+
288
+ let output = ''
289
+
290
+ for (let i = 0; i < input.length; i++) {
291
+ if (input[i] === '%' && i + 2 < input.length) {
292
+ const hex = input.slice(i + 1, i + 3)
293
+ if (isHexPair(hex)) {
294
+ const normalizedHex = hex.toUpperCase()
295
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16))
296
+
297
+ if (decodeUnreserved && isUnreserved(decoded)) {
298
+ output += decoded
299
+ } else {
300
+ output += '%' + normalizedHex
301
+ }
302
+
303
+ i += 2
304
+ continue
305
+ }
306
+ }
307
+
308
+ output += input[i]
284
309
  }
285
- if (component.query !== undefined) {
286
- component.query = func(component.query)
310
+
311
+ return output
312
+ }
313
+
314
+ /**
315
+ * Normalizes path data without turning reserved escapes into live path syntax.
316
+ * Valid escapes are uppercased, raw unsafe characters are escaped, and only
317
+ * unreserved bytes that are not `.` are decoded.
318
+ *
319
+ * @param {string} input
320
+ * @returns {string}
321
+ */
322
+ function normalizePathEncoding (input) {
323
+ let output = ''
324
+
325
+ for (let i = 0; i < input.length; i++) {
326
+ if (input[i] === '%' && i + 2 < input.length) {
327
+ const hex = input.slice(i + 1, i + 3)
328
+ if (isHexPair(hex)) {
329
+ const normalizedHex = hex.toUpperCase()
330
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16))
331
+
332
+ if (decoded !== '.' && isUnreserved(decoded)) {
333
+ output += decoded
334
+ } else {
335
+ output += '%' + normalizedHex
336
+ }
337
+
338
+ i += 2
339
+ continue
340
+ }
341
+ }
342
+
343
+ if (isPathCharacter(input[i])) {
344
+ output += input[i]
345
+ } else {
346
+ output += escape(input[i])
347
+ }
287
348
  }
288
- if (component.fragment !== undefined) {
289
- component.fragment = func(component.fragment)
349
+
350
+ return output
351
+ }
352
+
353
+ /**
354
+ * Escapes a component while preserving existing valid percent escapes.
355
+ *
356
+ * @param {string} input
357
+ * @returns {string}
358
+ */
359
+ function escapePreservingEscapes (input) {
360
+ let output = ''
361
+
362
+ for (let i = 0; i < input.length; i++) {
363
+ if (input[i] === '%' && i + 2 < input.length) {
364
+ const hex = input.slice(i + 1, i + 3)
365
+ if (isHexPair(hex)) {
366
+ output += '%' + hex.toUpperCase()
367
+ i += 2
368
+ continue
369
+ }
370
+ }
371
+
372
+ output += escape(input[i])
290
373
  }
291
- return component
374
+
375
+ return output
292
376
  }
293
377
 
294
378
  /**
@@ -327,7 +411,9 @@ function recomposeAuthority (component) {
327
411
  module.exports = {
328
412
  nonSimpleDomain,
329
413
  recomposeAuthority,
330
- normalizeComponentEncoding,
414
+ normalizePercentEncoding,
415
+ normalizePathEncoding,
416
+ escapePreservingEscapes,
331
417
  removeDotSegments,
332
418
  isIPv4,
333
419
  isUUID,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fast-uri",
3
3
  "description": "Dependency-free RFC 3986 URI toolbox",
4
- "version": "3.1.0",
4
+ "version": "3.1.1",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "types": "types/index.d.ts",
@@ -58,12 +58,11 @@
58
58
  "test:typescript": "tsd"
59
59
  },
60
60
  "devDependencies": {
61
- "@fastify/pre-commit": "^2.1.0",
62
61
  "ajv": "^8.16.0",
63
62
  "eslint": "^9.17.0",
64
- "neostandard": "^0.12.0",
63
+ "neostandard": "^0.13.0",
65
64
  "playwright-test": "^14.1.12",
66
65
  "tape": "^5.8.1",
67
- "tsd": "^0.32.0"
66
+ "tsd": "^0.33.0"
68
67
  }
69
68
  }
@@ -0,0 +1,39 @@
1
+ 'use strict'
2
+
3
+ const test = require('tape')
4
+ const fastURI = require('..')
5
+
6
+ test('parse preserves reserved path escapes as data', (t) => {
7
+ const components = fastURI.parse('http://example.com/a%2Fb/public/%2e%2e/admin')
8
+
9
+ t.equal(components.path, '/a%2Fb/public/%2E%2E/admin')
10
+ t.end()
11
+ })
12
+
13
+ test('normalize preserves percent-encoded path separators and dot segments', (t) => {
14
+ t.equal(
15
+ fastURI.normalize('http://example.com/public/%2e%2e/admin'),
16
+ 'http://example.com/public/%2E%2E/admin'
17
+ )
18
+
19
+ t.equal(
20
+ fastURI.normalize('http://example.com/a%2Fb'),
21
+ 'http://example.com/a%2Fb'
22
+ )
23
+
24
+ t.end()
25
+ })
26
+
27
+ test('equal does not treat reserved path escapes as live path syntax', (t) => {
28
+ t.equal(
29
+ fastURI.equal('http://example.com/public/%2e%2e/admin', 'http://example.com/admin', {}),
30
+ false
31
+ )
32
+
33
+ t.equal(
34
+ fastURI.equal('http://example.com/a%2Fb', 'http://example.com/a/b', {}),
35
+ false
36
+ )
37
+
38
+ t.end()
39
+ })
package/package.json CHANGED
@@ -88,7 +88,7 @@
88
88
  "access": "public",
89
89
  "provenance": true
90
90
  },
91
- "version": "2.1.33",
91
+ "version": "2.1.34",
92
92
  "jest": {
93
93
  "coverageProvider": "v8",
94
94
  "testMatch": [
@@ -1,21 +0,0 @@
1
- # Number of days of inactivity before an issue becomes stale
2
- daysUntilStale: 15
3
- # Number of days of inactivity before a stale issue is closed
4
- daysUntilClose: 7
5
- # Issues with these labels will never be considered stale
6
- exemptLabels:
7
- - "discussion"
8
- - "feature request"
9
- - "bug"
10
- - "help wanted"
11
- - "plugin suggestion"
12
- - "good first issue"
13
- # Label to use when marking an issue as stale
14
- staleLabel: stale
15
- # Comment to post when marking an issue as stale. Set to `false` to disable
16
- markComment: >
17
- This issue has been automatically marked as stale because it has not had
18
- recent activity. It will be closed if no further activity occurs. Thank you
19
- for your contributions.
20
- # Comment to post when closing a stale issue. Set to `false` to disable
21
- closeComment: false
@@ -1,8 +0,0 @@
1
- comment: |
2
- Hello! Thank you for contributing!
3
- It appears that you have changed the code, but the tests that verify your change are missing. Could you please add them?
4
- fileExtensions:
5
- - '.ts'
6
- - '.js'
7
-
8
- testDir: 'test'