@astral/ui 4.71.0 → 4.71.1

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,9 +1,14 @@
1
1
  import { MimeTypeRegistry } from '../../services/MimeTypeRegistry';
2
2
  import { FILE_TYPE_ERROR_INFO, INCONSISTENCY_EXTENSION_AND_MIME_TYPE_ERROR_INFO, } from './constants';
3
3
  import { getFileMeta } from './utils';
4
- const getAcceptMimeTypes = (acceptMeta) => acceptMeta.mimeTypes.concat(...acceptMeta.extensions
5
- .map((extension) => MimeTypeRegistry.getInstance().getMimeTypeByExtension(extension))
6
- .filter((value) => typeof value === 'string'));
4
+ const getAcceptMimeTypes = (acceptMeta) => {
5
+ return [
6
+ ...new Set([
7
+ ...acceptMeta.mimeTypes,
8
+ ...acceptMeta.extensions.flatMap((extension) => MimeTypeRegistry.getInstance().getMimeTypesByExtension(extension)),
9
+ ]),
10
+ ];
11
+ };
7
12
  const checkEmptyAccept = (acceptMeta) => !acceptMeta.extensions.length &&
8
13
  !acceptMeta.mimeTypes.length &&
9
14
  !acceptMeta.generalMimeTypes.length;
@@ -20,9 +25,7 @@ export const restrictFileType = (acceptMeta) => (file) => {
20
25
  }
21
26
  return undefined;
22
27
  }
23
- const isInconsistencyExtensionAndMimeType = !MimeTypeRegistry.getInstance()
24
- .getExtensionsByMimeType(fileMeta.mimeType)
25
- ?.includes(fileMeta.extension);
28
+ const isInconsistencyExtensionAndMimeType = !MimeTypeRegistry.getInstance().isExtensionValidForMimeType(fileMeta.mimeType, fileMeta.extension);
26
29
  if (isInconsistencyExtensionAndMimeType) {
27
30
  return INCONSISTENCY_EXTENSION_AND_MIME_TYPE_ERROR_INFO;
28
31
  }
@@ -5,5 +5,13 @@ export declare class MimeTypeRegistry {
5
5
  private constructor();
6
6
  getMimeTypeByExtension(extension: string): string | null;
7
7
  getExtensionsByMimeType(mimeType: string): string[] | null;
8
+ /**
9
+ * Проверяет, что расширение файла допустимо для указанного MIME-типа.
10
+ * Учитывает wildcard-расширения из mime-db (например, `*xml` для `text/xml`).
11
+ */
12
+ isExtensionValidForMimeType(mimeType: string, extension: string): boolean;
13
+ getMimeTypesByExtension(extension: string): string[];
14
+ private normalizeExtension;
15
+ private matchExtension;
8
16
  static getInstance(): MimeTypeRegistry;
9
17
  }
@@ -10,11 +10,45 @@ export class MimeTypeRegistry {
10
10
  }
11
11
  }
12
12
  getMimeTypeByExtension(extension) {
13
- return (this.extensionsMap.get(extension.toLowerCase().replace('.', '')) || null);
13
+ return this.extensionsMap.get(this.normalizeExtension(extension)) || null;
14
14
  }
15
15
  getExtensionsByMimeType(mimeType) {
16
16
  return this.mimeTypesMap[mimeType] || null;
17
17
  }
18
+ /**
19
+ * Проверяет, что расширение файла допустимо для указанного MIME-типа.
20
+ * Учитывает wildcard-расширения из mime-db (например, `*xml` для `text/xml`).
21
+ */
22
+ isExtensionValidForMimeType(mimeType, extension) {
23
+ const extensions = this.getExtensionsByMimeType(mimeType);
24
+ if (!extensions) {
25
+ return false;
26
+ }
27
+ return extensions.some((registeredExtension) => this.matchExtension(registeredExtension, extension));
28
+ }
29
+ getMimeTypesByExtension(extension) {
30
+ const normalizedExtension = this.normalizeExtension(extension);
31
+ const mimeTypes = [];
32
+ for (const [mimeType, extensions] of Object.entries(this.mimeTypesMap)) {
33
+ if (extensions.some((registeredExtension) => this.matchExtension(registeredExtension, normalizedExtension))) {
34
+ mimeTypes.push(mimeType);
35
+ }
36
+ }
37
+ return mimeTypes;
38
+ }
39
+ normalizeExtension(extension) {
40
+ return extension.toLowerCase().replace(/^\./, '');
41
+ }
42
+ matchExtension(registeredExtension, fileExtension) {
43
+ const normalizedFile = this.normalizeExtension(fileExtension);
44
+ const normalizedRegistered = registeredExtension.toLowerCase();
45
+ // Отдельная обработка для wildcard mime types, например xml === *xml
46
+ if (normalizedRegistered.startsWith('*')) {
47
+ const suffix = normalizedRegistered.slice(1);
48
+ return normalizedFile === suffix || normalizedFile.endsWith(suffix);
49
+ }
50
+ return normalizedRegistered === normalizedFile;
51
+ }
18
52
  static getInstance() {
19
53
  const instance = this.instanceRef?.deref();
20
54
  if (instance) {
@@ -4,9 +4,14 @@ exports.restrictFileType = void 0;
4
4
  const MimeTypeRegistry_1 = require("../../services/MimeTypeRegistry");
5
5
  const constants_1 = require("./constants");
6
6
  const utils_1 = require("./utils");
7
- const getAcceptMimeTypes = (acceptMeta) => acceptMeta.mimeTypes.concat(...acceptMeta.extensions
8
- .map((extension) => MimeTypeRegistry_1.MimeTypeRegistry.getInstance().getMimeTypeByExtension(extension))
9
- .filter((value) => typeof value === 'string'));
7
+ const getAcceptMimeTypes = (acceptMeta) => {
8
+ return [
9
+ ...new Set([
10
+ ...acceptMeta.mimeTypes,
11
+ ...acceptMeta.extensions.flatMap((extension) => MimeTypeRegistry_1.MimeTypeRegistry.getInstance().getMimeTypesByExtension(extension)),
12
+ ]),
13
+ ];
14
+ };
10
15
  const checkEmptyAccept = (acceptMeta) => !acceptMeta.extensions.length &&
11
16
  !acceptMeta.mimeTypes.length &&
12
17
  !acceptMeta.generalMimeTypes.length;
@@ -23,9 +28,7 @@ const restrictFileType = (acceptMeta) => (file) => {
23
28
  }
24
29
  return undefined;
25
30
  }
26
- const isInconsistencyExtensionAndMimeType = !MimeTypeRegistry_1.MimeTypeRegistry.getInstance()
27
- .getExtensionsByMimeType(fileMeta.mimeType)
28
- ?.includes(fileMeta.extension);
31
+ const isInconsistencyExtensionAndMimeType = !MimeTypeRegistry_1.MimeTypeRegistry.getInstance().isExtensionValidForMimeType(fileMeta.mimeType, fileMeta.extension);
29
32
  if (isInconsistencyExtensionAndMimeType) {
30
33
  return constants_1.INCONSISTENCY_EXTENSION_AND_MIME_TYPE_ERROR_INFO;
31
34
  }
@@ -5,5 +5,13 @@ export declare class MimeTypeRegistry {
5
5
  private constructor();
6
6
  getMimeTypeByExtension(extension: string): string | null;
7
7
  getExtensionsByMimeType(mimeType: string): string[] | null;
8
+ /**
9
+ * Проверяет, что расширение файла допустимо для указанного MIME-типа.
10
+ * Учитывает wildcard-расширения из mime-db (например, `*xml` для `text/xml`).
11
+ */
12
+ isExtensionValidForMimeType(mimeType: string, extension: string): boolean;
13
+ getMimeTypesByExtension(extension: string): string[];
14
+ private normalizeExtension;
15
+ private matchExtension;
8
16
  static getInstance(): MimeTypeRegistry;
9
17
  }
@@ -13,11 +13,45 @@ class MimeTypeRegistry {
13
13
  }
14
14
  }
15
15
  getMimeTypeByExtension(extension) {
16
- return (this.extensionsMap.get(extension.toLowerCase().replace('.', '')) || null);
16
+ return this.extensionsMap.get(this.normalizeExtension(extension)) || null;
17
17
  }
18
18
  getExtensionsByMimeType(mimeType) {
19
19
  return this.mimeTypesMap[mimeType] || null;
20
20
  }
21
+ /**
22
+ * Проверяет, что расширение файла допустимо для указанного MIME-типа.
23
+ * Учитывает wildcard-расширения из mime-db (например, `*xml` для `text/xml`).
24
+ */
25
+ isExtensionValidForMimeType(mimeType, extension) {
26
+ const extensions = this.getExtensionsByMimeType(mimeType);
27
+ if (!extensions) {
28
+ return false;
29
+ }
30
+ return extensions.some((registeredExtension) => this.matchExtension(registeredExtension, extension));
31
+ }
32
+ getMimeTypesByExtension(extension) {
33
+ const normalizedExtension = this.normalizeExtension(extension);
34
+ const mimeTypes = [];
35
+ for (const [mimeType, extensions] of Object.entries(this.mimeTypesMap)) {
36
+ if (extensions.some((registeredExtension) => this.matchExtension(registeredExtension, normalizedExtension))) {
37
+ mimeTypes.push(mimeType);
38
+ }
39
+ }
40
+ return mimeTypes;
41
+ }
42
+ normalizeExtension(extension) {
43
+ return extension.toLowerCase().replace(/^\./, '');
44
+ }
45
+ matchExtension(registeredExtension, fileExtension) {
46
+ const normalizedFile = this.normalizeExtension(fileExtension);
47
+ const normalizedRegistered = registeredExtension.toLowerCase();
48
+ // Отдельная обработка для wildcard mime types, например xml === *xml
49
+ if (normalizedRegistered.startsWith('*')) {
50
+ const suffix = normalizedRegistered.slice(1);
51
+ return normalizedFile === suffix || normalizedFile.endsWith(suffix);
52
+ }
53
+ return normalizedRegistered === normalizedFile;
54
+ }
21
55
  static getInstance() {
22
56
  const instance = this.instanceRef?.deref();
23
57
  if (instance) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astral/ui",
3
- "version": "4.71.0",
3
+ "version": "4.71.1",
4
4
  "browser": "./index.js",
5
5
  "main": "./node/index.js",
6
6
  "dependencies": {