@acorex/core 21.0.3-next.16 → 21.0.3-next.17

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.
@@ -102,27 +102,6 @@ function resolveFileCopyText(result) {
102
102
  return trimmed && trimmed.length > 0 ? trimmed : null;
103
103
  }
104
104
 
105
- /** Runs {@link AXFileType.open} in the caller's injection context. */
106
- function runFileTypeOpen(fileType, ctx, payload) {
107
- const open = fileType.open;
108
- if (!open) {
109
- return false;
110
- }
111
- return runInInjectionContext(ctx.injector, () => open(ctx, payload));
112
- }
113
-
114
- /** Contributes {@link AXFileType} entries (multi provider). */
115
- class AXFileTypeInfoProvider {
116
- }
117
- const AX_FILE_TYPE_INFO_PROVIDER = new InjectionToken('AX_FILE_TYPE_INFO_PROVIDER');
118
- function provideFileTypeInfoProvider(provider) {
119
- return {
120
- provide: AX_FILE_TYPE_INFO_PROVIDER,
121
- useClass: provider,
122
- multi: true,
123
- };
124
- }
125
-
126
105
  /** Merges type-level validations with extension overrides (extension wins per field). */
127
106
  function mergeFileValidations(base, override) {
128
107
  if (!override) {
@@ -135,7 +114,7 @@ function mergeFileValidations(base, override) {
135
114
  rules: override.rules ?? base.rules,
136
115
  };
137
116
  }
138
- /** Resolved validations for a type + optional extension. */
117
+ /** Resolved validations for a type + optional extension entry. */
139
118
  function resolveFileValidations(type, extension) {
140
119
  return mergeFileValidations(type.validations ?? {}, extension?.validations);
141
120
  }
@@ -161,13 +140,125 @@ function getFileExtension(fileName) {
161
140
  const parts = fileName.trim().split('.');
162
141
  return parts.length > 1 ? (parts.pop()?.toLowerCase() ?? '') : '';
163
142
  }
143
+
144
+ /** Matches a MIME type against a catalog pattern (`image/*`, exact type, …). */
145
+ function matchesFileMime(mime, pattern) {
146
+ const normalizedMime = mime.trim().toLowerCase();
147
+ const normalizedPattern = pattern.trim().toLowerCase();
148
+ if (!normalizedPattern || normalizedPattern === '*/*' || normalizedPattern === '*') {
149
+ return true;
150
+ }
151
+ if (normalizedPattern.endsWith('/*')) {
152
+ const category = normalizedPattern.slice(0, -2);
153
+ return normalizedMime.startsWith(`${category}/`) || (normalizedMime === '' && category === 'application');
154
+ }
155
+ return normalizedMime === normalizedPattern;
156
+ }
157
+ /** Finds an extension entry by its `name` (without dot). */
158
+ function findFileTypeExtensionByName(type, extensionName) {
159
+ const ext = extensionName.replace(/^\./, '').trim().toLowerCase();
160
+ if (!ext || !type.extensions?.length) {
161
+ return undefined;
162
+ }
163
+ return type.extensions.find((entry) => entry.name.toLowerCase() === ext);
164
+ }
165
+ /** Finds an extension entry whose validations include the given MIME type. */
166
+ function findFileTypeExtensionForMime(type, mimeType) {
167
+ const mime = mimeType.trim().toLowerCase();
168
+ if (!mime || !type.extensions?.length) {
169
+ return undefined;
170
+ }
171
+ return type.extensions.find((entry) => entry.validations?.mimeTypes?.some((pattern) => matchesFileMime(mime, pattern)));
172
+ }
164
173
  /** Matching extension entry for a file within a type, if any. */
165
174
  function findFileTypeExtension(file, type) {
166
- const ext = getFileExtension(file.name);
167
- if (!ext || !type.extensions?.length) {
175
+ return resolveFileTypeExtension(type, { file });
176
+ }
177
+ /** Resolves the best-matching extension entry for a file or hint. */
178
+ function resolveFileTypeExtension(type, hint) {
179
+ if (!hint) {
168
180
  return undefined;
169
181
  }
170
- return type.extensions.find((e) => e.name.toLowerCase() === ext);
182
+ if (hint.file) {
183
+ const byFileName = findFileTypeExtensionByName(type, getFileExtension(hint.file.name));
184
+ if (byFileName) {
185
+ return byFileName;
186
+ }
187
+ if (hint.file.type) {
188
+ const byFileMime = findFileTypeExtensionForMime(type, hint.file.type);
189
+ if (byFileMime) {
190
+ return byFileMime;
191
+ }
192
+ }
193
+ }
194
+ if (hint.extensionName) {
195
+ const byName = findFileTypeExtensionByName(type, hint.extensionName);
196
+ if (byName) {
197
+ return byName;
198
+ }
199
+ }
200
+ if (hint.mimeType) {
201
+ return findFileTypeExtensionForMime(type, hint.mimeType);
202
+ }
203
+ return undefined;
204
+ }
205
+ function resolveFileTypeCopy(type, extension) {
206
+ return extension?.copy ?? type.copy;
207
+ }
208
+ function resolveFileTypeOpen(type, extension) {
209
+ return extension?.open ?? type.open;
210
+ }
211
+ function resolveFileTypePaste(type, extension) {
212
+ return extension?.paste ?? type.paste;
213
+ }
214
+ function resolveFileTypeUtility(type, extension, name) {
215
+ const fromExtension = extension?.utilities?.[name];
216
+ if (fromExtension) {
217
+ return fromExtension;
218
+ }
219
+ return type.utilities?.[name];
220
+ }
221
+ /** Runs `copy` from extension first, then parent type. */
222
+ async function runFileTypeCopy(type, payload, extension) {
223
+ const copy = resolveFileTypeCopy(type, extension);
224
+ if (!copy) {
225
+ return undefined;
226
+ }
227
+ return copy(payload);
228
+ }
229
+ /** Runs a utility from extension first, then parent type. */
230
+ function runFileTypeUtility(type, ctx, extension, name, ...args) {
231
+ const utility = resolveFileTypeUtility(type, extension, name);
232
+ if (!utility) {
233
+ return undefined;
234
+ }
235
+ return utility(ctx, ...args);
236
+ }
237
+ /** Runs a catalog utility with optional file-based extension resolution. */
238
+ function runFileTypeUtilityForFile(type, ctx, file, name, ...args) {
239
+ const extension = file ? findFileTypeExtension(file, type) : undefined;
240
+ return runFileTypeUtility(type, ctx, extension, name, ...args);
241
+ }
242
+
243
+ /** Runs `open` from extension first, then parent type, in the caller's injection context. */
244
+ function runFileTypeOpen(type, ctx, payload, extension) {
245
+ const open = resolveFileTypeOpen(type, extension);
246
+ if (!open) {
247
+ return false;
248
+ }
249
+ return runInInjectionContext(ctx.injector, () => open(ctx, payload));
250
+ }
251
+
252
+ /** Contributes {@link AXFileType} entries (multi provider). */
253
+ class AXFileTypeInfoProvider {
254
+ }
255
+ const AX_FILE_TYPE_INFO_PROVIDER = new InjectionToken('AX_FILE_TYPE_INFO_PROVIDER');
256
+ function provideFileTypeInfoProvider(provider) {
257
+ return {
258
+ provide: AX_FILE_TYPE_INFO_PROVIDER,
259
+ useClass: provider,
260
+ multi: true,
261
+ };
171
262
  }
172
263
 
173
264
  /** Maps {@link AXFileValidations} to executable validation entries. */
@@ -306,7 +397,7 @@ class AXFileTypeRegistryService {
306
397
  if (!patterns.length) {
307
398
  return false;
308
399
  }
309
- return patterns.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));
400
+ return patterns.some((pattern) => matchesFileMime(mime, pattern));
310
401
  });
311
402
  }
312
403
  async validate(file, typeName) {
@@ -350,16 +441,6 @@ class AXFileTypeRegistryService {
350
441
  }
351
442
  return { accepted, rejected };
352
443
  }
353
- matchesMime(mime, pattern) {
354
- if (!pattern || pattern === '*/*' || pattern === '*') {
355
- return true;
356
- }
357
- if (pattern.endsWith('/*')) {
358
- const category = pattern.slice(0, -2);
359
- return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');
360
- }
361
- return mime === pattern;
362
- }
363
444
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXFileTypeRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
364
445
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXFileTypeRegistryService, providedIn: 'root' }); }
365
446
  }
@@ -783,5 +864,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
783
864
  * Generated bundle index. Do not edit.
784
865
  */
785
866
 
786
- export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileValidationRules, resolveFileCopyText, resolveFileValidations, runFileTypeOpen, validateFileAgainstType, validateFileWithValidations };
867
+ export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, findFileTypeExtensionByName, findFileTypeExtensionForMime, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, matchesFileMime, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileValidationRules, resolveFileCopyText, resolveFileTypeCopy, resolveFileTypeExtension, resolveFileTypeOpen, resolveFileTypePaste, resolveFileTypeUtility, resolveFileValidations, runFileTypeCopy, runFileTypeOpen, runFileTypeUtility, runFileTypeUtilityForFile, validateFileAgainstType, validateFileWithValidations };
787
868
  //# sourceMappingURL=acorex-core-file.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"acorex-core-file.mjs","sources":["../../../../packages/core/file/src/lib/file-size-formatter.ts","../../../../packages/core/file/src/lib/format-file-size.ts","../../../../packages/core/file/src/lib/file-type/file-type.models.ts","../../../../packages/core/file/src/lib/file-type/file-type.metadata.ts","../../../../packages/core/file/src/lib/file-type/file-type.copy.ts","../../../../packages/core/file/src/lib/file-type/file-type.open.ts","../../../../packages/core/file/src/lib/file-type/file-type-info-provider.ts","../../../../packages/core/file/src/lib/file-type/file-type.merge.ts","../../../../packages/core/file/src/lib/file-type/file-type.validate.ts","../../../../packages/core/file/src/lib/file-type/file-type-registry.service.ts","../../../../packages/core/file/src/lib/file-type/types.providers/audio-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/document-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/file-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/image-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/video-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/index.ts","../../../../packages/core/file/src/lib/file-type/rules/file-mime-type.rule.ts","../../../../packages/core/file/src/lib/file-type/rules/file-min-size.rule.ts","../../../../packages/core/file/src/lib/file-type/rules/file-max-size.rule.ts","../../../../packages/core/file/src/lib/file-type/index.ts","../../../../packages/core/file/src/lib/file.module.ts","../../../../packages/core/file/src/lib/file.service.ts","../../../../packages/core/file/src/acorex-core-file.ts"],"sourcesContent":["import { AXFormatOptions, AXFormatter } from '@acorex/core/format';\nimport { Injectable } from '@angular/core';\n\nexport interface AXFileSizeFormatterOptions extends AXFormatOptions {\n format: string;\n}\n\ndeclare module '@acorex/core/format' {\n interface AXFormatOptionsMap {\n filesize: AXFileSizeFormatterOptions;\n }\n}\n\n@Injectable()\nexport class AXFileSizeFormatter implements AXFormatter {\n /**\n * Gets the name of the formatter.\n *\n * @returns string - The formatter name 'filesize'\n */\n\n get name(): string {\n return 'filesize';\n }\n\n /**\n * Formats a file size value to human-readable format.\n *\n * @param value - The file size in bytes\n * @returns string - The formatted file size string (e.g., '1.5 MB')\n */\n\n format(value: number): string {\n const size = Number(value);\n\n if (size === 0) return '0 Bytes';\n if (Number.isNaN(size)) return 'Unknown';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n const i = Math.floor(Math.log(size) / Math.log(k));\n\n return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n}\n","/** Human-readable file size (binary units, e.g. `41.5 MB`). */\nexport function formatFileSizeBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) {\n return '0 B';\n }\n if (bytes === 0) {\n return '0 B';\n }\n\n const k = 1024;\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), units.length - 1);\n const value = bytes / Math.pow(k, i);\n\n if (i === 0) {\n return `${bytes} B`;\n }\n\n const digits = value >= 100 ? 0 : value >= 10 ? 1 : 2;\n return `${value.toFixed(digits)} ${units[i]}`;\n}\n","import type { AXValidationRuleOptions } from '@acorex/core/validation';\nimport type { AXFileTypeContext, AXFileTypeOpenContext } from './file-type.context';\nimport type { AXFileCopyResult } from './file-type.copy';\nimport type { AXFileOpenResult } from './file-type.open';\n\n/** Metadata key for catalog usage context. */\nexport const AX_FILE_TYPE_METADATA_PURPOSE = 'purpose' as const;\n\n/** Catalog metadata bag; `purpose` lists usage contexts (e.g. `['system']`). */\nexport type AXFileTypeMetadata = Record<string, unknown> & {\n [AX_FILE_TYPE_METADATA_PURPOSE]?: string[];\n};\n\n/** Filter catalog entries by {@link AX_FILE_TYPE_METADATA_PURPOSE}. */\nexport interface AXFileTypeQuery {\n purpose?: string | string[];\n}\n\n/** Generic rule executed via {@link AXValidationService}. */\nexport interface AXFileValidationRule {\n rule: string;\n options?: AXValidationRuleOptions;\n}\n\n/**\n * Common file constraints shared by {@link AXFileType} and {@link AXFileTypeExtension}.\n * Extension `validations` are partial and override the parent type field-by-field.\n */\nexport interface AXFileValidations {\n mimeTypes?: string[];\n minSize?: number;\n maxSize?: number;\n rules?: AXFileValidationRule[];\n}\n\n/** Extension entry; `validations` override the parent {@link AXFileType.validations}. */\nexport interface AXFileTypeExtension {\n name: string;\n title?: string;\n icon?: string;\n validations?: Partial<AXFileValidations>;\n}\n\n/**\n * Logical file category (image, video, …).\n *\n * - With type `validations` set: any file matching those rules is allowed; `extensions` only override when matched.\n * - With empty / omitted `validations` and `extensions` listed: only those extensions are allowed.\n */\nexport interface AXFileType<\n T = Record<\n string,\n (ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown\n >,\n> {\n name: string;\n title?: string;\n icon?: string;\n metadata?: AXFileTypeMetadata;\n validations?: AXFileValidations;\n extensions?: AXFileTypeExtension[];\n /** Dynamic utility functions available for this file type. */\n utilities?: T;\n paste?: () => Promise<unknown>;\n /**\n * Produce copyable content from a payload (does not write to the clipboard).\n * Returns a plain string or {@link AXFileCopyData} with `text` and optional `meta`.\n */\n copy?: (payload: unknown) => Promise<AXFileCopyResult> | AXFileCopyResult;\n /**\n * Open or preview a payload (e.g. navigate, show a dialog).\n * Invoke via {@link runFileTypeOpen} so `inject()` works in the caller's context.\n */\n open?: (\n ctx: AXFileTypeOpenContext,\n payload: unknown,\n ) => Promise<AXFileOpenResult> | AXFileOpenResult;\n}\n","import type { AXFileType } from './file-type.models';\nimport { AX_FILE_TYPE_METADATA_PURPOSE } from './file-type.models';\n\nexport { AX_FILE_TYPE_METADATA_PURPOSE } from './file-type.models';\n\nconst CONVERSATION_NAME_PREFIX = 'conversation-';\n\nexport function getFileTypePurposes(type: AXFileType): string[] {\n const raw = type.metadata?.[AX_FILE_TYPE_METADATA_PURPOSE];\n if (Array.isArray(raw)) {\n const values = raw.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0);\n if (values.length) {\n return values;\n }\n }\n if (type.name.startsWith(CONVERSATION_NAME_PREFIX)) {\n return ['conversation'];\n }\n return ['system'];\n}\n\nexport function fileTypeMatchesPurpose(type: AXFileType, purpose: string | string[]): boolean {\n const allowed = Array.isArray(purpose) ? purpose : [purpose];\n return getFileTypePurposes(type).some((entry) => allowed.includes(entry));\n}\n\nexport function filterFileTypesByPurpose(types: AXFileType[], purpose?: string | string[]): AXFileType[] {\n if (!purpose) {\n return types;\n }\n return types.filter((type) => fileTypeMatchesPurpose(type, purpose));\n}\n\nexport function createFileTypeMetadata(purpose: string | string[]): NonNullable<AXFileType['metadata']> {\n const values = (Array.isArray(purpose) ? purpose : [purpose]).filter(\n (entry): entry is string => typeof entry === 'string' && entry.trim().length > 0,\n );\n return { [AX_FILE_TYPE_METADATA_PURPOSE]: values };\n}\n","/** Structured copy payload from {@link AXFileType.copy}. */\nexport interface AXFileCopyData {\n /** Primary plain-text value for clipboard or previews. */\n text: string;\n /** Optional type-specific metadata for consumers (URLs, names, mime types, …). */\n meta?: Record<string, unknown>;\n}\n\n/** Return value of {@link AXFileType.copy} — shorthand string or structured data. */\nexport type AXFileCopyResult = string | AXFileCopyData | null | undefined;\n\n/** Resolves clipboard/plain text from a copy result. */\nexport function resolveFileCopyText(result: AXFileCopyResult): string | null {\n if (result == null) {\n return null;\n }\n if (typeof result === 'string') {\n const trimmed = result.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n const trimmed = result.text?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : null;\n}\n","import { runInInjectionContext } from '@angular/core';\n\nimport type { AXFileTypeOpenContext } from './file-type.context';\nimport type { AXFileType } from './file-type.models';\n\n/** Result of {@link AXFileType.open}; `false` means the payload was not opened. */\nexport type AXFileOpenResult = void | boolean | null | undefined;\n\n/** Runs {@link AXFileType.open} in the caller's injection context. */\nexport function runFileTypeOpen(\n fileType: Pick<AXFileType, 'open'>,\n ctx: AXFileTypeOpenContext,\n payload: unknown,\n): Promise<AXFileOpenResult> | AXFileOpenResult {\n const open = fileType.open;\n if (!open) {\n return false;\n }\n return runInInjectionContext(ctx.injector, () => open(ctx, payload));\n}\n","import { InjectionToken, Provider, Type } from '@angular/core';\nimport type { AXFileType } from './file-type.models';\n\n/** Contributes {@link AXFileType} entries (multi provider). */\nexport abstract class AXFileTypeInfoProvider {\n abstract items(): Promise<AXFileType[]>;\n}\n\nexport const AX_FILE_TYPE_INFO_PROVIDER = new InjectionToken<AXFileTypeInfoProvider[]>('AX_FILE_TYPE_INFO_PROVIDER');\n\nexport function provideFileTypeInfoProvider(provider: Type<AXFileTypeInfoProvider>): Provider {\n return {\n provide: AX_FILE_TYPE_INFO_PROVIDER,\n useClass: provider,\n multi: true,\n };\n}\n","import type { AXFileType, AXFileTypeExtension, AXFileValidations } from './file-type.models';\n\n/** Merges type-level validations with extension overrides (extension wins per field). */\nexport function mergeFileValidations(\n base: AXFileValidations,\n override?: Partial<AXFileValidations>,\n): AXFileValidations {\n if (!override) {\n return { ...base };\n }\n\n return {\n mimeTypes: override.mimeTypes ?? base.mimeTypes,\n minSize: override.minSize ?? base.minSize,\n maxSize: override.maxSize ?? base.maxSize,\n rules: override.rules ?? base.rules,\n };\n}\n\n/** Resolved validations for a type + optional extension. */\nexport function resolveFileValidations(type: AXFileType, extension?: AXFileTypeExtension): AXFileValidations {\n return mergeFileValidations(type.validations ?? {}, extension?.validations);\n}\n\n/** True when no mime/size/rules are defined on the type. */\nexport function isEmptyFileValidations(validations?: AXFileValidations): boolean {\n if (!validations) {\n return true;\n }\n return (\n (validations.mimeTypes?.length ?? 0) === 0 &&\n validations.minSize == null &&\n validations.maxSize == null &&\n (validations.rules?.length ?? 0) === 0\n );\n}\n\n/**\n * Extension-only mode: empty type `validations` and a non-empty `extensions` list.\n * Files must match a listed extension; rules come from that extension entry.\n */\nexport function isExtensionsOnlyType(type: AXFileType): boolean {\n return isEmptyFileValidations(type.validations) && (type.extensions?.length ?? 0) > 0;\n}\n\n/** File extension from name (lowercase, no dot). */\nexport function getFileExtension(fileName: string): string {\n const parts = fileName.trim().split('.');\n return parts.length > 1 ? (parts.pop()?.toLowerCase() ?? '') : '';\n}\n\n/** Matching extension entry for a file within a type, if any. */\nexport function findFileTypeExtension(file: File, type: AXFileType): AXFileTypeExtension | undefined {\n const ext = getFileExtension(file.name);\n if (!ext || !type.extensions?.length) {\n return undefined;\n }\n return type.extensions.find((e) => e.name.toLowerCase() === ext);\n}\n","import { AXValidationService, type AXValidationRuleResult } from '@acorex/core/validation';\nimport {\n findFileTypeExtension,\n getFileExtension,\n isExtensionsOnlyType,\n resolveFileValidations,\n} from './file-type.merge';\nimport type { AXFileType, AXFileTypeExtension, AXFileValidationRule, AXFileValidations } from './file-type.models';\n\n/** Maps {@link AXFileValidations} to executable validation entries. */\nexport function fileValidationsToRules(validations: AXFileValidations): AXFileValidationRule[] {\n const rules: AXFileValidationRule[] = [];\n\n if (validations.mimeTypes?.length) {\n rules.push({\n rule: 'fileMimeType',\n options: { allowed: validations.mimeTypes },\n });\n }\n\n if (validations.minSize != null) {\n rules.push({\n rule: 'fileMinSize',\n options: { minSize: validations.minSize },\n });\n }\n\n if (validations.maxSize != null) {\n rules.push({\n rule: 'fileMaxSize',\n options: { maxSize: validations.maxSize },\n });\n }\n\n if (validations.rules?.length) {\n rules.push(...validations.rules);\n }\n\n return rules;\n}\n\n/** Failed validation results; empty array means the file is valid. */\nexport async function validateFileWithValidations(\n validation: AXValidationService,\n file: File,\n validations: AXFileValidations,\n): Promise<AXValidationRuleResult[]> {\n const entries = fileValidationsToRules(validations);\n const errors: AXValidationRuleResult[] = [];\n\n for (const { rule, options } of entries) {\n const result = await validation.validate(rule, file, options);\n if (!result.result) {\n errors.push(result);\n }\n }\n\n return errors;\n}\n\n/** Validates a file against a type; extension rules override when the file name matches. */\nexport async function validateFileAgainstType(\n validation: AXValidationService,\n file: File,\n type: AXFileType,\n extension?: AXFileTypeExtension,\n): Promise<AXValidationRuleResult[]> {\n const matchedExtension = extension ?? findFileTypeExtension(file, type);\n\n if (isExtensionsOnlyType(type) && !matchedExtension) {\n const ext = getFileExtension(file.name);\n return [\n {\n rule: 'fileExtension',\n result: false,\n message: ext ? `Extension \".${ext}\" is not allowed.` : 'File must have an allowed extension.',\n value: ext,\n },\n ];\n }\n\n const resolved = resolveFileValidations(type, matchedExtension);\n return validateFileWithValidations(validation, file, resolved);\n}\n","import type { AXValidationRuleResult } from '@acorex/core/validation';\n\nimport { AXValidationService } from '@acorex/core/validation';\n\nimport { Injectable, inject } from '@angular/core';\n\nimport { AX_FILE_TYPE_INFO_PROVIDER } from './file-type-info-provider';\n\nimport { findFileTypeExtension } from './file-type.merge';\n\nimport type { AXFileType, AXFileTypeQuery } from './file-type.models';\n\nimport { filterFileTypesByPurpose } from './file-type.metadata';\n\nimport { validateFileAgainstType } from './file-type.validate';\n\n@Injectable({ providedIn: 'root' })\nexport class AXFileTypeRegistryService {\n private readonly validation = inject(AXValidationService);\n\n private readonly providers = inject(AX_FILE_TYPE_INFO_PROVIDER, { optional: true }) ?? [];\n\n private readonly registeredTypes: AXFileType[] = [];\n\n private cache: AXFileType[] | null = null;\n\n /** Registers or replaces catalog entries (e.g. from feature bootstrap). */\n\n registerTypes(types: AXFileType[]): void {\n for (const type of types) {\n const index = this.registeredTypes.findIndex((t) => t.name === type.name);\n\n if (index >= 0) {\n this.registeredTypes[index] = type;\n } else {\n this.registeredTypes.push(type);\n }\n }\n\n this.invalidateCache();\n }\n\n invalidateCache(): void {\n this.cache = null;\n }\n\n private async resolveTypes(): Promise<AXFileType[]> {\n if (this.cache) {\n return this.cache;\n }\n\n const byName = new Map<string, AXFileType>();\n\n if (this.providers.length) {\n const batches = await Promise.all(this.providers.map((p) => p.items()));\n\n for (const batch of batches) {\n for (const type of batch) {\n if (!byName.has(type.name)) {\n byName.set(type.name, type);\n }\n }\n }\n }\n\n for (const type of this.registeredTypes) {\n byName.set(type.name, type);\n }\n\n this.cache = [...byName.values()];\n\n return this.cache;\n }\n\n async getTypes(query?: AXFileTypeQuery): Promise<AXFileType[]> {\n const types = await this.resolveTypes();\n return filterFileTypesByPurpose(types, query?.purpose);\n }\n\n async get(name: string): Promise<AXFileType | undefined> {\n const types = await this.resolveTypes();\n\n return types.find((t) => t.name === name);\n }\n\n async accept(typeNames?: string | string[]): Promise<string> {\n const names = typeNames ? (Array.isArray(typeNames) ? typeNames : [typeNames]) : undefined;\n\n const types = await this.resolveTypes();\n\n const selected = names?.length ? types.filter((t) => names.includes(t.name)) : types;\n\n if (names?.length && selected.length === 0) {\n return '';\n }\n\n const parts = new Set<string>();\n\n for (const type of selected) {\n type.validations?.mimeTypes?.forEach((m) => parts.add(m));\n\n type.extensions?.forEach((ext) => {\n ext.validations?.mimeTypes?.forEach((m) => parts.add(m));\n\n parts.add(`.${ext.name.replace(/^\\./, '')}`);\n });\n }\n\n return [...parts].join(',');\n }\n\n async matchType(file: File): Promise<AXFileType | undefined> {\n const types = await this.resolveTypes();\n\n const mime = file.type.trim().toLowerCase();\n\n return types.find((type) => {\n const patterns = [\n ...(type.validations?.mimeTypes ?? []),\n\n ...(type.extensions?.flatMap((e) => e.validations?.mimeTypes ?? []) ?? []),\n ];\n\n if (!patterns.length) {\n return false;\n }\n\n return patterns.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));\n });\n }\n\n async validate(file: File, typeName: string): Promise<AXValidationRuleResult[]> {\n const type = await this.get(typeName);\n\n if (!type) {\n return [\n {\n rule: 'fileType',\n\n result: false,\n\n message: `Unknown file type: ${typeName}`,\n\n value: typeName,\n },\n ];\n }\n\n const extension = findFileTypeExtension(file, type);\n\n return validateFileAgainstType(this.validation, file, type, extension);\n }\n\n async validateAgainstTypes(\n file: File,\n\n typeNames: string | string[],\n ): Promise<AXValidationRuleResult[]> {\n const names = Array.isArray(typeNames) ? typeNames : [typeNames];\n\n let lastErrors: AXValidationRuleResult[] = [];\n\n for (const name of names) {\n const errors = await this.validate(file, name);\n\n if (errors.length === 0) {\n return [];\n }\n\n lastErrors = errors;\n }\n\n return lastErrors;\n }\n\n async validateMany(\n files: File[],\n\n typeNames: string | string[],\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n const accepted: File[] = [];\n\n const rejected: { file: File; errors: AXValidationRuleResult[] }[] = [];\n\n for (const file of files) {\n const errors = await this.validateAgainstTypes(file, typeNames);\n\n if (errors.length === 0) {\n accepted.push(file);\n } else {\n rejected.push({ file, errors });\n }\n }\n\n return { accepted, rejected };\n }\n\n private matchesMime(mime: string, pattern: string): boolean {\n if (!pattern || pattern === '*/*' || pattern === '*') {\n return true;\n }\n\n if (pattern.endsWith('/*')) {\n const category = pattern.slice(0, -2);\n\n return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');\n }\n\n return mime === pattern;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_AUDIO_FILE_TYPE: AXFileType = {\n name: 'audio',\n metadata: createFileTypeMetadata('system'),\n title: 'Audio',\n icon: 'fa-light fa-music ax-text-amber-500',\n validations: {\n mimeTypes: ['audio/*'],\n minSize: 1,\n maxSize: 50 * MB,\n },\n extensions: [\n { name: 'mp3', title: 'MP3' },\n { name: 'wav', title: 'WAV', validations: { maxSize: 30 * MB } },\n { name: 'ogg', title: 'OGG' },\n { name: 'm4a', title: 'M4A' },\n ],\n};\n\n@Injectable()\nexport class AXAudioFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_AUDIO_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\n/** Extension-only: no type `validations` — only listed extensions are allowed. */\nexport const AX_DOCUMENT_FILE_TYPE: AXFileType = {\n name: 'document',\n metadata: createFileTypeMetadata('system'),\n title: 'Document',\n icon: 'fa-light fa-file-lines ax-text-red-500',\n extensions: [{ name: 'pdf', title: 'PDF', validations: { mimeTypes: ['application/pdf'], maxSize: 5 * MB } }],\n};\n\n@Injectable()\nexport class AXDocumentFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_DOCUMENT_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_FILE_FILE_TYPE: AXFileType = {\n name: 'file',\n metadata: createFileTypeMetadata('system'),\n title: 'File',\n icon: 'fa-light fa-file ax-text-neutral-500',\n validations: {\n mimeTypes: ['application/*', 'text/*'],\n minSize: 1,\n maxSize: 100 * MB,\n },\n extensions: [\n { name: 'pdf', title: 'PDF', validations: { mimeTypes: ['application/pdf'], maxSize: 25 * MB } },\n { name: 'doc', title: 'Word' },\n { name: 'docx', title: 'Word' },\n { name: 'txt', title: 'Text', validations: { mimeTypes: ['text/plain'], maxSize: 5 * MB } },\n { name: 'zip', title: 'ZIP', validations: { maxSize: 50 * MB } },\n ],\n};\n\n@Injectable()\nexport class AXFileFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_FILE_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_IMAGE_FILE_TYPE: AXFileType = {\n name: 'image',\n metadata: createFileTypeMetadata('system'),\n title: 'Image',\n icon: 'fa-light fa-image ax-text-purple-500',\n validations: {\n mimeTypes: ['image/*'],\n minSize: 1,\n maxSize: 100 * MB,\n },\n extensions: [\n { name: 'jpg', title: 'JPEG' },\n { name: 'jpeg', title: 'JPEG', validations: { maxSize: 5 * MB } },\n { name: 'png', title: 'PNG' },\n { name: 'gif', title: 'GIF' },\n { name: 'webp', title: 'WebP' },\n { name: 'svg', title: 'SVG', validations: { maxSize: 2 * MB } },\n ],\n};\n\n@Injectable()\nexport class AXImageFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_IMAGE_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_VIDEO_FILE_TYPE: AXFileType = {\n name: 'video',\n metadata: createFileTypeMetadata('system'),\n title: 'Video',\n icon: 'fa-light fa-video ax-text-blue-500',\n validations: {\n mimeTypes: ['video/*'],\n minSize: 1,\n maxSize: 500 * MB,\n },\n extensions: [\n { name: 'mp4', title: 'MP4' },\n { name: 'webm', title: 'WebM', validations: { maxSize: 200 * MB } },\n { name: 'ogg', title: 'OGG' },\n ],\n};\n\n@Injectable()\nexport class AXVideoFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_VIDEO_FILE_TYPE]);\n }\n}\n","import { Provider, Type } from '@angular/core';\nimport { provideFileTypeInfoProvider, AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { AXAudioFileTypeProvider } from './audio-file-type.provider';\nimport { AXDocumentFileTypeProvider } from './document-file-type.provider';\nimport { AXFileFileTypeProvider } from './file-file-type.provider';\nimport { AXImageFileTypeProvider } from './image-file-type.provider';\nimport { AXVideoFileTypeProvider } from './video-file-type.provider';\n\nexport * from './image-file-type.provider';\nexport * from './video-file-type.provider';\nexport * from './audio-file-type.provider';\nexport * from './file-file-type.provider';\nexport * from './document-file-type.provider';\n\n/** Built-in file type provider classes (one logical type per provider). */\nexport const AX_BUILTIN_FILE_TYPE_PROVIDERS = [\n AXImageFileTypeProvider,\n AXVideoFileTypeProvider,\n AXAudioFileTypeProvider,\n AXFileFileTypeProvider,\n AXDocumentFileTypeProvider,\n] as const satisfies readonly Type<AXFileTypeInfoProvider>[];\n\n/** Registers all built-in file type providers (image, video, audio, file, document). */\nexport function provideBuiltinFileTypeProviders(): Provider[] {\n return AX_BUILTIN_FILE_TYPE_PROVIDERS.map((provider) => provideFileTypeInfoProvider(provider));\n}\n\n/** @deprecated Use {@link provideBuiltinFileTypeProviders}. */\nexport const provideDefaultFileTypeProviders = provideBuiltinFileTypeProviders;\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\n\nexport interface AXFileMimeTypeValidationRuleOptions extends AXValidationRuleOptions {\n /** MIME patterns, e.g. `image/*`, `image/png`. */\n allowed: string[];\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMimeType: AXFileMimeTypeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMimeTypeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMimeType';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMimeTypeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const mime = (value instanceof File || value instanceof Blob ? value.type : '').trim().toLowerCase();\n const allowed = options.allowed ?? [];\n const valid =\n allowed.length === 0 ||\n allowed.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));\n\n return {\n rule: this.name,\n result: valid,\n message: valid ? '' : (options.message ?? 'File type is not allowed.'),\n value: mime,\n };\n }\n\n private matchesMime(mime: string, pattern: string): boolean {\n if (!pattern || pattern === '*/*' || pattern === '*') {\n return true;\n }\n if (pattern.endsWith('/*')) {\n const category = pattern.slice(0, -2);\n return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');\n }\n return mime === pattern;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\nimport { formatFileSizeBytes } from '../../format-file-size';\n\nexport interface AXFileMinSizeValidationRuleOptions extends AXValidationRuleOptions {\n /** Minimum size in bytes. */\n minSize: number;\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMinSize: AXFileMinSizeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMinSizeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMinSize';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMinSizeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const size = value instanceof File || value instanceof Blob ? value.size : 0;\n const valid = size >= options.minSize;\n const limitLabel = formatFileSizeBytes(options.minSize);\n\n return {\n rule: this.name,\n result: valid,\n message: valid\n ? ''\n : (options.message ?? `File is too small. Minimum size is ${limitLabel}.`),\n value: size,\n minSize: options.minSize,\n };\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\nimport { formatFileSizeBytes } from '../../format-file-size';\n\nexport interface AXFileMaxSizeValidationRuleOptions extends AXValidationRuleOptions {\n /** Maximum size in bytes. */\n maxSize: number;\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMaxSize: AXFileMaxSizeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMaxSizeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMaxSize';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMaxSizeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const size = value instanceof File || value instanceof Blob ? value.size : 0;\n const valid = size <= options.maxSize;\n const limitLabel = formatFileSizeBytes(options.maxSize);\n\n return {\n rule: this.name,\n result: valid,\n message: valid\n ? ''\n : (options.message ??\n `File is too large. Maximum size is ${limitLabel}.`),\n value: size,\n maxSize: options.maxSize,\n };\n }\n}\n","export * from './file-type.metadata';\nexport * from './file-type.models';\nexport * from './file-type.context';\nexport * from './file-type.copy';\nexport * from './file-type.open';\nexport * from './file-type-info-provider';\nexport * from './file-type-registry.service';\nexport * from './file-type.merge';\nexport * from './file-type.validate';\nexport * from './types.providers';\nexport * from './rules/file-mime-type.rule';\nexport * from './rules/file-min-size.rule';\nexport * from './rules/file-max-size.rule';\n\nimport { Provider } from '@angular/core';\nimport { AXValidationRegistryService } from '@acorex/core/validation';\nimport { provideBuiltinFileTypeProviders } from './types.providers';\nimport { AXFileMaxSizeValidationRule } from './rules/file-max-size.rule';\nimport { AXFileMimeTypeValidationRule } from './rules/file-mime-type.rule';\nimport { AXFileMinSizeValidationRule } from './rules/file-min-size.rule';\n\n/** Validation rule classes to register with {@link AXValidationModule}. */\nexport const AX_FILE_VALIDATION_RULES = [\n AXFileMimeTypeValidationRule,\n AXFileMinSizeValidationRule,\n AXFileMaxSizeValidationRule,\n] as const;\n\n/** Registers file validation rules with {@link AXValidationRegistryService}. */\nexport function provideFileValidationRules(): Provider {\n return {\n provide: 'AXValidationModuleFactory',\n useFactory: (registry: AXValidationRegistryService) => () => {\n registry.register(...AX_FILE_VALIDATION_RULES);\n },\n deps: [AXValidationRegistryService],\n multi: true,\n };\n}\n\n/** Registers built-in image / video / audio / file / document type providers. */\nexport { provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders } from './types.providers';\n\n/**\n * Registers validation rules and optional built-in file type providers.\n * {@link AXFileTypeRegistryService} and {@link AXFileService} are `providedIn: 'root'`.\n */\nexport function provideFileTypeSystem(): Provider[] {\n return [provideFileValidationRules(), ...provideBuiltinFileTypeProviders()];\n}\n","import { AXFormatModule } from '@acorex/core/format';\nimport { AXValidationModule } from '@acorex/core/validation';\nimport { ModuleWithProviders, NgModule, Provider } from '@angular/core';\nimport { AXFileSizeFormatter } from './file-size-formatter';\nimport {\n AX_FILE_VALIDATION_RULES,\n provideDefaultFileTypeProviders,\n provideFileValidationRules,\n} from './file-type';\n\nexport interface AXFileModuleConfig {\n fileTypeProviders?: Provider[];\n includeDefaultFileTypes?: boolean;\n}\n\n@NgModule({\n imports: [\n AXFormatModule.forChild({ formatters: [AXFileSizeFormatter] }),\n AXValidationModule.forChild({ rules: [...AX_FILE_VALIDATION_RULES] }),\n ],\n providers: [AXFileSizeFormatter],\n})\nexport class AXFileModule {\n static forRoot(config?: AXFileModuleConfig): ModuleWithProviders<AXFileModule> {\n const includeDefaults = config?.includeDefaultFileTypes !== false;\n\n return {\n ngModule: AXFileModule,\n providers: [\n provideFileValidationRules(),\n ...(includeDefaults ? provideDefaultFileTypeProviders() : []),\n ...(config?.fileTypeProviders ?? []),\n ],\n };\n }\n\n static forChild(config?: AXFileModuleConfig): ModuleWithProviders<AXFileModule> {\n return AXFileModule.forRoot(config);\n }\n}\n","import type { AXValidationRuleResult } from '@acorex/core/validation';\nimport { DOCUMENT, inject, Injectable, isDevMode } from '@angular/core';\nimport { AXFileTypeRegistryService } from './file-type/file-type-registry.service';\nimport type { AXFileType } from './file-type/file-type.models';\n\nexport interface AXFileChooseOptions {\n /** Logical type name(s) from {@link AXFileTypeRegistryService}. When set, files are validated against the catalog. */\n fileType?: string | string[];\n accept?: string;\n multiple?: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AXFileService {\n private readonly document = inject(DOCUMENT);\n private readonly fileTypes = inject(AXFileTypeRegistryService);\n\n async getFileTypes(): Promise<AXFileType[]> {\n return this.fileTypes.getTypes();\n }\n\n async getFileType(name: string): Promise<AXFileType | undefined> {\n return this.fileTypes.get(name);\n }\n\n async getAcceptAttribute(fileType?: string | string[]): Promise<string> {\n return this.fileTypes.accept(fileType);\n }\n\n async matchFileType(file: File): Promise<AXFileType | undefined> {\n return this.fileTypes.matchType(file);\n }\n\n validate(file: File, fileType: string | string[]): Promise<AXValidationRuleResult[]> {\n return this.fileTypes.validateAgainstTypes(file, fileType);\n }\n\n validateMany(\n files: File[],\n fileType: string | string[],\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n return this.fileTypes.validateMany(files, fileType);\n }\n\n /**\n * Opens a file selection dialog.\n * With `fileType`, returns files that pass catalog validation (`accept` defaults from the catalog).\n * Without `fileType`, returns all selected files (legacy `accept` / `multiple` only).\n */\n async chooseValidated(\n options: AXFileChooseOptions,\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n const resolved = await this.resolveChooseOptions(options);\n const files = await this.openFileDialog(resolved);\n\n if (files.length === 0) {\n return { accepted: [], rejected: [] };\n }\n\n if (options.fileType) {\n return this.validateMany(files, options.fileType);\n }\n\n return { accepted: files, rejected: [] };\n }\n\n async choose(options: AXFileChooseOptions): Promise<File[]> {\n const { accepted } = await this.chooseValidated(options);\n return accepted;\n }\n\n blobToBase64(blob: Blob): Promise<string> {\n if (!(blob instanceof Blob)) {\n return Promise.reject(new Error('input is not blob'));\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error);\n reader.onload = () => resolve(reader.result as string);\n reader.readAsDataURL(blob);\n });\n }\n\n getSize(file: File | Blob | string): number | false {\n if (this.isBase64(file as string)) {\n return this.getBase64Size(file as string);\n }\n return false;\n }\n\n isBase64(base64: string): boolean {\n const regx = /[^:]\\w+\\/[\\w-+\\d.]+(?=;|,)/;\n return regx.test(base64);\n }\n\n getBase64Size(base64: string): number {\n return atob(base64.substring(base64.indexOf(',') + 1)).length;\n }\n\n private async resolveChooseOptions(\n options: AXFileChooseOptions,\n ): Promise<{ accept: string; multiple: boolean }> {\n const multiple = options.multiple ?? false;\n\n if (options.fileType) {\n const accept = options.accept ?? (await this.getAcceptAttribute(options.fileType));\n\n if (isDevMode() && !accept) {\n const name = Array.isArray(options.fileType) ? options.fileType.join(', ') : options.fileType;\n console.warn(\n `[AXFileService] No accept filter for file type \"${name}\". ` +\n 'Register a file type provider (e.g. provideConversationFileCatalog).',\n );\n }\n\n return { accept, multiple };\n }\n\n return { accept: options.accept ?? '', multiple };\n }\n\n private openFileDialog(options: { accept: string; multiple: boolean }): Promise<File[]> {\n return new Promise<File[]>((resolve, reject) => {\n const input: HTMLInputElement = this.document.createElement('input');\n input.style.display = 'none';\n this.document.body.appendChild(input);\n input.type = 'file';\n input.accept = options.accept;\n input.multiple = options.multiple;\n\n const cleanup = () => {\n input.removeEventListener('change', onChange);\n input.removeEventListener('error', onError);\n if (input.parentNode) {\n this.document.body.removeChild(input);\n }\n input.remove();\n };\n\n const onError = (e: Event) => {\n cleanup();\n reject(e);\n };\n\n const onChange = () => {\n const files = Array.from(input.files ?? []);\n cleanup();\n resolve(files);\n };\n\n input.addEventListener('change', onChange);\n input.addEventListener('error', onError);\n input.click();\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["MB"],"mappings":"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"}
1
+ {"version":3,"file":"acorex-core-file.mjs","sources":["../../../../packages/core/file/src/lib/file-size-formatter.ts","../../../../packages/core/file/src/lib/format-file-size.ts","../../../../packages/core/file/src/lib/file-type/file-type.models.ts","../../../../packages/core/file/src/lib/file-type/file-type.metadata.ts","../../../../packages/core/file/src/lib/file-type/file-type.copy.ts","../../../../packages/core/file/src/lib/file-type/file-type.merge.ts","../../../../packages/core/file/src/lib/file-type/file-type.resolve.ts","../../../../packages/core/file/src/lib/file-type/file-type.open.ts","../../../../packages/core/file/src/lib/file-type/file-type-info-provider.ts","../../../../packages/core/file/src/lib/file-type/file-type.validate.ts","../../../../packages/core/file/src/lib/file-type/file-type-registry.service.ts","../../../../packages/core/file/src/lib/file-type/types.providers/audio-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/document-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/file-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/image-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/video-file-type.provider.ts","../../../../packages/core/file/src/lib/file-type/types.providers/index.ts","../../../../packages/core/file/src/lib/file-type/rules/file-mime-type.rule.ts","../../../../packages/core/file/src/lib/file-type/rules/file-min-size.rule.ts","../../../../packages/core/file/src/lib/file-type/rules/file-max-size.rule.ts","../../../../packages/core/file/src/lib/file-type/index.ts","../../../../packages/core/file/src/lib/file.module.ts","../../../../packages/core/file/src/lib/file.service.ts","../../../../packages/core/file/src/acorex-core-file.ts"],"sourcesContent":["import { AXFormatOptions, AXFormatter } from '@acorex/core/format';\nimport { Injectable } from '@angular/core';\n\nexport interface AXFileSizeFormatterOptions extends AXFormatOptions {\n format: string;\n}\n\ndeclare module '@acorex/core/format' {\n interface AXFormatOptionsMap {\n filesize: AXFileSizeFormatterOptions;\n }\n}\n\n@Injectable()\nexport class AXFileSizeFormatter implements AXFormatter {\n /**\n * Gets the name of the formatter.\n *\n * @returns string - The formatter name 'filesize'\n */\n\n get name(): string {\n return 'filesize';\n }\n\n /**\n * Formats a file size value to human-readable format.\n *\n * @param value - The file size in bytes\n * @returns string - The formatted file size string (e.g., '1.5 MB')\n */\n\n format(value: number): string {\n const size = Number(value);\n\n if (size === 0) return '0 Bytes';\n if (Number.isNaN(size)) return 'Unknown';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n const i = Math.floor(Math.log(size) / Math.log(k));\n\n return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n}\n","/** Human-readable file size (binary units, e.g. `41.5 MB`). */\nexport function formatFileSizeBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) {\n return '0 B';\n }\n if (bytes === 0) {\n return '0 B';\n }\n\n const k = 1024;\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), units.length - 1);\n const value = bytes / Math.pow(k, i);\n\n if (i === 0) {\n return `${bytes} B`;\n }\n\n const digits = value >= 100 ? 0 : value >= 10 ? 1 : 2;\n return `${value.toFixed(digits)} ${units[i]}`;\n}\n","import type { AXValidationRuleOptions } from '@acorex/core/validation';\nimport type { AXFileTypeContext, AXFileTypeOpenContext } from './file-type.context';\nimport type { AXFileCopyResult } from './file-type.copy';\nimport type { AXFileOpenResult } from './file-type.open';\n\n/** Metadata key for catalog usage context. */\nexport const AX_FILE_TYPE_METADATA_PURPOSE = 'purpose' as const;\n\n/** Catalog metadata bag; `purpose` lists usage contexts (e.g. `['system']`). */\nexport type AXFileTypeMetadata = Record<string, unknown> & {\n [AX_FILE_TYPE_METADATA_PURPOSE]?: string[];\n};\n\n/** Filter catalog entries by {@link AX_FILE_TYPE_METADATA_PURPOSE}. */\nexport interface AXFileTypeQuery {\n purpose?: string | string[];\n}\n\n/** Generic rule executed via {@link AXValidationService}. */\nexport interface AXFileValidationRule {\n rule: string;\n options?: AXValidationRuleOptions;\n}\n\n/**\n * Common file constraints shared by {@link AXFileType} and {@link AXFileTypeExtension}.\n * Extension `validations` override the parent type field-by-field when merged.\n */\nexport interface AXFileValidations {\n mimeTypes?: string[];\n minSize?: number;\n maxSize?: number;\n rules?: AXFileValidationRule[];\n}\n\ntype AXFileTypeUtilities = Record<\n string,\n (ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown\n>;\n\n/**\n * Logical file category (image, video, …).\n *\n * - With type `validations` set: any file matching those rules is allowed; `extensions` only override when matched.\n * - With empty / omitted `validations` and `extensions` listed: only those extensions are allowed.\n */\nexport interface AXFileType<T extends AXFileTypeUtilities = AXFileTypeUtilities> {\n name: string;\n title?: string;\n icon?: string;\n metadata?: AXFileTypeMetadata;\n validations?: AXFileValidations;\n extensions?: AXFileTypeExtension<T>[];\n /** Dynamic utility functions available for this file type. */\n utilities?: T;\n paste?: () => Promise<unknown>;\n /**\n * Produce copyable content from a payload (does not write to the clipboard).\n * Returns a plain string or {@link AXFileCopyData} with `text` and optional `meta`.\n */\n copy?: (payload: unknown) => Promise<AXFileCopyResult> | AXFileCopyResult;\n /**\n * Open or preview a payload (e.g. navigate, show a dialog).\n * Invoke via {@link runFileTypeOpen} so `inject()` works in the caller's context.\n */\n open?: (\n ctx: AXFileTypeOpenContext,\n payload: unknown,\n ) => Promise<AXFileOpenResult> | AXFileOpenResult;\n}\n\n/** Extension entry — {@link AXFileType} without nested `extensions`. */\nexport type AXFileTypeExtension<T extends AXFileTypeUtilities = AXFileTypeUtilities> = Omit<\n AXFileType<T>,\n 'extensions'\n>;\n","import type { AXFileType } from './file-type.models';\nimport { AX_FILE_TYPE_METADATA_PURPOSE } from './file-type.models';\n\nexport { AX_FILE_TYPE_METADATA_PURPOSE } from './file-type.models';\n\nconst CONVERSATION_NAME_PREFIX = 'conversation-';\n\nexport function getFileTypePurposes(type: AXFileType): string[] {\n const raw = type.metadata?.[AX_FILE_TYPE_METADATA_PURPOSE];\n if (Array.isArray(raw)) {\n const values = raw.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0);\n if (values.length) {\n return values;\n }\n }\n if (type.name.startsWith(CONVERSATION_NAME_PREFIX)) {\n return ['conversation'];\n }\n return ['system'];\n}\n\nexport function fileTypeMatchesPurpose(type: AXFileType, purpose: string | string[]): boolean {\n const allowed = Array.isArray(purpose) ? purpose : [purpose];\n return getFileTypePurposes(type).some((entry) => allowed.includes(entry));\n}\n\nexport function filterFileTypesByPurpose(types: AXFileType[], purpose?: string | string[]): AXFileType[] {\n if (!purpose) {\n return types;\n }\n return types.filter((type) => fileTypeMatchesPurpose(type, purpose));\n}\n\nexport function createFileTypeMetadata(purpose: string | string[]): NonNullable<AXFileType['metadata']> {\n const values = (Array.isArray(purpose) ? purpose : [purpose]).filter(\n (entry): entry is string => typeof entry === 'string' && entry.trim().length > 0,\n );\n return { [AX_FILE_TYPE_METADATA_PURPOSE]: values };\n}\n","/** Structured copy payload from {@link AXFileType.copy}. */\nexport interface AXFileCopyData {\n /** Primary plain-text value for clipboard or previews. */\n text: string;\n /** Optional type-specific metadata for consumers (URLs, names, mime types, …). */\n meta?: Record<string, unknown>;\n}\n\n/** Return value of {@link AXFileType.copy} — shorthand string or structured data. */\nexport type AXFileCopyResult = string | AXFileCopyData | null | undefined;\n\n/** Resolves clipboard/plain text from a copy result. */\nexport function resolveFileCopyText(result: AXFileCopyResult): string | null {\n if (result == null) {\n return null;\n }\n if (typeof result === 'string') {\n const trimmed = result.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n const trimmed = result.text?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : null;\n}\n","import type { AXFileType, AXFileTypeExtension, AXFileValidations } from './file-type.models';\n\n/** Merges type-level validations with extension overrides (extension wins per field). */\nexport function mergeFileValidations(\n base: AXFileValidations,\n override?: Partial<AXFileValidations>,\n): AXFileValidations {\n if (!override) {\n return { ...base };\n }\n\n return {\n mimeTypes: override.mimeTypes ?? base.mimeTypes,\n minSize: override.minSize ?? base.minSize,\n maxSize: override.maxSize ?? base.maxSize,\n rules: override.rules ?? base.rules,\n };\n}\n\n/** Resolved validations for a type + optional extension entry. */\nexport function resolveFileValidations(type: AXFileType, extension?: AXFileTypeExtension): AXFileValidations {\n return mergeFileValidations(type.validations ?? {}, extension?.validations);\n}\n\n/** True when no mime/size/rules are defined on the type. */\nexport function isEmptyFileValidations(validations?: AXFileValidations): boolean {\n if (!validations) {\n return true;\n }\n return (\n (validations.mimeTypes?.length ?? 0) === 0 &&\n validations.minSize == null &&\n validations.maxSize == null &&\n (validations.rules?.length ?? 0) === 0\n );\n}\n\n/**\n * Extension-only mode: empty type `validations` and a non-empty `extensions` list.\n * Files must match a listed extension; rules come from that extension entry.\n */\nexport function isExtensionsOnlyType(type: AXFileType): boolean {\n return isEmptyFileValidations(type.validations) && (type.extensions?.length ?? 0) > 0;\n}\n\n/** File extension from name (lowercase, no dot). */\nexport function getFileExtension(fileName: string): string {\n const parts = fileName.trim().split('.');\n return parts.length > 1 ? (parts.pop()?.toLowerCase() ?? '') : '';\n}\n","import type { AXFileTypeContext } from './file-type.context';\nimport type { AXFileCopyResult } from './file-type.copy';\nimport { getFileExtension } from './file-type.merge';\nimport type { AXFileType, AXFileTypeExtension } from './file-type.models';\n\n/** Hint for resolving a catalog extension entry. */\nexport interface AXFileTypeExtensionHint {\n file?: File;\n extensionName?: string;\n mimeType?: string;\n}\n\n/** Matches a MIME type against a catalog pattern (`image/*`, exact type, …). */\nexport function matchesFileMime(mime: string, pattern: string): boolean {\n const normalizedMime = mime.trim().toLowerCase();\n const normalizedPattern = pattern.trim().toLowerCase();\n\n if (!normalizedPattern || normalizedPattern === '*/*' || normalizedPattern === '*') {\n return true;\n }\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.slice(0, -2);\n return normalizedMime.startsWith(`${category}/`) || (normalizedMime === '' && category === 'application');\n }\n\n return normalizedMime === normalizedPattern;\n}\n\n/** Finds an extension entry by its `name` (without dot). */\nexport function findFileTypeExtensionByName(\n type: AXFileType,\n extensionName: string,\n): AXFileTypeExtension | undefined {\n const ext = extensionName.replace(/^\\./, '').trim().toLowerCase();\n if (!ext || !type.extensions?.length) {\n return undefined;\n }\n return type.extensions.find((entry) => entry.name.toLowerCase() === ext);\n}\n\n/** Finds an extension entry whose validations include the given MIME type. */\nexport function findFileTypeExtensionForMime(\n type: AXFileType,\n mimeType: string,\n): AXFileTypeExtension | undefined {\n const mime = mimeType.trim().toLowerCase();\n if (!mime || !type.extensions?.length) {\n return undefined;\n }\n\n return type.extensions.find((entry) =>\n entry.validations?.mimeTypes?.some((pattern) => matchesFileMime(mime, pattern)),\n );\n}\n\n/** Matching extension entry for a file within a type, if any. */\nexport function findFileTypeExtension(file: File, type: AXFileType): AXFileTypeExtension | undefined {\n return resolveFileTypeExtension(type, { file });\n}\n\n/** Resolves the best-matching extension entry for a file or hint. */\nexport function resolveFileTypeExtension(\n type: AXFileType,\n hint?: AXFileTypeExtensionHint,\n): AXFileTypeExtension | undefined {\n if (!hint) {\n return undefined;\n }\n\n if (hint.file) {\n const byFileName = findFileTypeExtensionByName(type, getFileExtension(hint.file.name));\n if (byFileName) {\n return byFileName;\n }\n if (hint.file.type) {\n const byFileMime = findFileTypeExtensionForMime(type, hint.file.type);\n if (byFileMime) {\n return byFileMime;\n }\n }\n }\n\n if (hint.extensionName) {\n const byName = findFileTypeExtensionByName(type, hint.extensionName);\n if (byName) {\n return byName;\n }\n }\n\n if (hint.mimeType) {\n return findFileTypeExtensionForMime(type, hint.mimeType);\n }\n\n return undefined;\n}\n\nexport function resolveFileTypeCopy(\n type: AXFileType,\n extension?: AXFileTypeExtension,\n): AXFileType['copy'] | undefined {\n return extension?.copy ?? type.copy;\n}\n\nexport function resolveFileTypeOpen(\n type: AXFileType,\n extension?: AXFileTypeExtension,\n): AXFileType['open'] | undefined {\n return extension?.open ?? type.open;\n}\n\nexport function resolveFileTypePaste(\n type: AXFileType,\n extension?: AXFileTypeExtension,\n): AXFileType['paste'] | undefined {\n return extension?.paste ?? type.paste;\n}\n\nexport function resolveFileTypeUtility(\n type: AXFileType,\n extension: AXFileTypeExtension | undefined,\n name: string,\n): ((ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown) | undefined {\n const fromExtension = extension?.utilities?.[name];\n if (fromExtension) {\n return fromExtension;\n }\n return type.utilities?.[name];\n}\n\n/** Runs `copy` from extension first, then parent type. */\nexport async function runFileTypeCopy(\n type: AXFileType,\n payload: unknown,\n extension?: AXFileTypeExtension,\n): Promise<AXFileCopyResult> {\n const copy = resolveFileTypeCopy(type, extension);\n if (!copy) {\n return undefined;\n }\n return copy(payload);\n}\n\n/** Runs a utility from extension first, then parent type. */\nexport function runFileTypeUtility(\n type: AXFileType,\n ctx: AXFileTypeContext,\n extension: AXFileTypeExtension | undefined,\n name: string,\n ...args: unknown[]\n): Promise<unknown> | unknown {\n const utility = resolveFileTypeUtility(type, extension, name);\n if (!utility) {\n return undefined;\n }\n return utility(ctx, ...args);\n}\n\n/** Runs a catalog utility with optional file-based extension resolution. */\nexport function runFileTypeUtilityForFile(\n type: AXFileType,\n ctx: AXFileTypeContext,\n file: File | undefined,\n name: string,\n ...args: unknown[]\n): Promise<unknown> | unknown {\n const extension = file ? findFileTypeExtension(file, type) : undefined;\n return runFileTypeUtility(type, ctx, extension, name, ...args);\n}\n","import { runInInjectionContext } from '@angular/core';\n\nimport type { AXFileTypeOpenContext } from './file-type.context';\nimport type { AXFileType, AXFileTypeExtension } from './file-type.models';\nimport { resolveFileTypeOpen } from './file-type.resolve';\n\n/** Result of {@link AXFileType.open}; `false` means the payload was not opened. */\nexport type AXFileOpenResult = void | boolean | null | undefined;\n\n/** Runs `open` from extension first, then parent type, in the caller's injection context. */\nexport function runFileTypeOpen(\n type: AXFileType,\n ctx: AXFileTypeOpenContext,\n payload: unknown,\n extension?: AXFileTypeExtension,\n): Promise<AXFileOpenResult> | AXFileOpenResult {\n const open = resolveFileTypeOpen(type, extension);\n if (!open) {\n return false;\n }\n return runInInjectionContext(ctx.injector, () => open(ctx, payload));\n}\n","import { InjectionToken, Provider, Type } from '@angular/core';\nimport type { AXFileType } from './file-type.models';\n\n/** Contributes {@link AXFileType} entries (multi provider). */\nexport abstract class AXFileTypeInfoProvider {\n abstract items(): Promise<AXFileType[]>;\n}\n\nexport const AX_FILE_TYPE_INFO_PROVIDER = new InjectionToken<AXFileTypeInfoProvider[]>('AX_FILE_TYPE_INFO_PROVIDER');\n\nexport function provideFileTypeInfoProvider(provider: Type<AXFileTypeInfoProvider>): Provider {\n return {\n provide: AX_FILE_TYPE_INFO_PROVIDER,\n useClass: provider,\n multi: true,\n };\n}\n","import { AXValidationService, type AXValidationRuleResult } from '@acorex/core/validation';\nimport {\n getFileExtension,\n isExtensionsOnlyType,\n resolveFileValidations,\n} from './file-type.merge';\nimport { findFileTypeExtension } from './file-type.resolve';\nimport type { AXFileType, AXFileTypeExtension, AXFileValidationRule, AXFileValidations } from './file-type.models';\n\n/** Maps {@link AXFileValidations} to executable validation entries. */\nexport function fileValidationsToRules(validations: AXFileValidations): AXFileValidationRule[] {\n const rules: AXFileValidationRule[] = [];\n\n if (validations.mimeTypes?.length) {\n rules.push({\n rule: 'fileMimeType',\n options: { allowed: validations.mimeTypes },\n });\n }\n\n if (validations.minSize != null) {\n rules.push({\n rule: 'fileMinSize',\n options: { minSize: validations.minSize },\n });\n }\n\n if (validations.maxSize != null) {\n rules.push({\n rule: 'fileMaxSize',\n options: { maxSize: validations.maxSize },\n });\n }\n\n if (validations.rules?.length) {\n rules.push(...validations.rules);\n }\n\n return rules;\n}\n\n/** Failed validation results; empty array means the file is valid. */\nexport async function validateFileWithValidations(\n validation: AXValidationService,\n file: File,\n validations: AXFileValidations,\n): Promise<AXValidationRuleResult[]> {\n const entries = fileValidationsToRules(validations);\n const errors: AXValidationRuleResult[] = [];\n\n for (const { rule, options } of entries) {\n const result = await validation.validate(rule, file, options);\n if (!result.result) {\n errors.push(result);\n }\n }\n\n return errors;\n}\n\n/** Validates a file against a type; extension rules override when the file name matches. */\nexport async function validateFileAgainstType(\n validation: AXValidationService,\n file: File,\n type: AXFileType,\n extension?: AXFileTypeExtension,\n): Promise<AXValidationRuleResult[]> {\n const matchedExtension = extension ?? findFileTypeExtension(file, type);\n\n if (isExtensionsOnlyType(type) && !matchedExtension) {\n const ext = getFileExtension(file.name);\n return [\n {\n rule: 'fileExtension',\n result: false,\n message: ext ? `Extension \".${ext}\" is not allowed.` : 'File must have an allowed extension.',\n value: ext,\n },\n ];\n }\n\n const resolved = resolveFileValidations(type, matchedExtension);\n return validateFileWithValidations(validation, file, resolved);\n}\n","import type { AXValidationRuleResult } from '@acorex/core/validation';\n\nimport { AXValidationService } from '@acorex/core/validation';\n\nimport { Injectable, inject } from '@angular/core';\n\nimport { AX_FILE_TYPE_INFO_PROVIDER } from './file-type-info-provider';\n\nimport { findFileTypeExtension, matchesFileMime } from './file-type.resolve';\n\nimport type { AXFileType, AXFileTypeQuery } from './file-type.models';\n\nimport { filterFileTypesByPurpose } from './file-type.metadata';\n\nimport { validateFileAgainstType } from './file-type.validate';\n\n@Injectable({ providedIn: 'root' })\nexport class AXFileTypeRegistryService {\n private readonly validation = inject(AXValidationService);\n\n private readonly providers = inject(AX_FILE_TYPE_INFO_PROVIDER, { optional: true }) ?? [];\n\n private readonly registeredTypes: AXFileType[] = [];\n\n private cache: AXFileType[] | null = null;\n\n /** Registers or replaces catalog entries (e.g. from feature bootstrap). */\n\n registerTypes(types: AXFileType[]): void {\n for (const type of types) {\n const index = this.registeredTypes.findIndex((t) => t.name === type.name);\n\n if (index >= 0) {\n this.registeredTypes[index] = type;\n } else {\n this.registeredTypes.push(type);\n }\n }\n\n this.invalidateCache();\n }\n\n invalidateCache(): void {\n this.cache = null;\n }\n\n private async resolveTypes(): Promise<AXFileType[]> {\n if (this.cache) {\n return this.cache;\n }\n\n const byName = new Map<string, AXFileType>();\n\n if (this.providers.length) {\n const batches = await Promise.all(this.providers.map((p) => p.items()));\n\n for (const batch of batches) {\n for (const type of batch) {\n if (!byName.has(type.name)) {\n byName.set(type.name, type);\n }\n }\n }\n }\n\n for (const type of this.registeredTypes) {\n byName.set(type.name, type);\n }\n\n this.cache = [...byName.values()];\n\n return this.cache;\n }\n\n async getTypes(query?: AXFileTypeQuery): Promise<AXFileType[]> {\n const types = await this.resolveTypes();\n return filterFileTypesByPurpose(types, query?.purpose);\n }\n\n async get(name: string): Promise<AXFileType | undefined> {\n const types = await this.resolveTypes();\n\n return types.find((t) => t.name === name);\n }\n\n async accept(typeNames?: string | string[]): Promise<string> {\n const names = typeNames ? (Array.isArray(typeNames) ? typeNames : [typeNames]) : undefined;\n\n const types = await this.resolveTypes();\n\n const selected = names?.length ? types.filter((t) => names.includes(t.name)) : types;\n\n if (names?.length && selected.length === 0) {\n return '';\n }\n\n const parts = new Set<string>();\n\n for (const type of selected) {\n type.validations?.mimeTypes?.forEach((m) => parts.add(m));\n\n type.extensions?.forEach((ext) => {\n ext.validations?.mimeTypes?.forEach((m) => parts.add(m));\n\n parts.add(`.${ext.name.replace(/^\\./, '')}`);\n });\n }\n\n return [...parts].join(',');\n }\n\n async matchType(file: File): Promise<AXFileType | undefined> {\n const types = await this.resolveTypes();\n\n const mime = file.type.trim().toLowerCase();\n\n return types.find((type) => {\n const patterns = [\n ...(type.validations?.mimeTypes ?? []),\n\n ...(type.extensions?.flatMap((e) => e.validations?.mimeTypes ?? []) ?? []),\n ];\n\n if (!patterns.length) {\n return false;\n }\n\n return patterns.some((pattern) => matchesFileMime(mime, pattern));\n });\n }\n\n async validate(file: File, typeName: string): Promise<AXValidationRuleResult[]> {\n const type = await this.get(typeName);\n\n if (!type) {\n return [\n {\n rule: 'fileType',\n\n result: false,\n\n message: `Unknown file type: ${typeName}`,\n\n value: typeName,\n },\n ];\n }\n\n const extension = findFileTypeExtension(file, type);\n\n return validateFileAgainstType(this.validation, file, type, extension);\n }\n\n async validateAgainstTypes(\n file: File,\n\n typeNames: string | string[],\n ): Promise<AXValidationRuleResult[]> {\n const names = Array.isArray(typeNames) ? typeNames : [typeNames];\n\n let lastErrors: AXValidationRuleResult[] = [];\n\n for (const name of names) {\n const errors = await this.validate(file, name);\n\n if (errors.length === 0) {\n return [];\n }\n\n lastErrors = errors;\n }\n\n return lastErrors;\n }\n\n async validateMany(\n files: File[],\n\n typeNames: string | string[],\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n const accepted: File[] = [];\n\n const rejected: { file: File; errors: AXValidationRuleResult[] }[] = [];\n\n for (const file of files) {\n const errors = await this.validateAgainstTypes(file, typeNames);\n\n if (errors.length === 0) {\n accepted.push(file);\n } else {\n rejected.push({ file, errors });\n }\n }\n\n return { accepted, rejected };\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_AUDIO_FILE_TYPE: AXFileType = {\n name: 'audio',\n metadata: createFileTypeMetadata('system'),\n title: 'Audio',\n icon: 'fa-light fa-music ax-text-amber-500',\n validations: {\n mimeTypes: ['audio/*'],\n minSize: 1,\n maxSize: 50 * MB,\n },\n extensions: [\n { name: 'mp3', title: 'MP3' },\n { name: 'wav', title: 'WAV', validations: { maxSize: 30 * MB } },\n { name: 'ogg', title: 'OGG' },\n { name: 'm4a', title: 'M4A' },\n ],\n};\n\n@Injectable()\nexport class AXAudioFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_AUDIO_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\n/** Extension-only: no type `validations` — only listed extensions are allowed. */\nexport const AX_DOCUMENT_FILE_TYPE: AXFileType = {\n name: 'document',\n metadata: createFileTypeMetadata('system'),\n title: 'Document',\n icon: 'fa-light fa-file-lines ax-text-red-500',\n extensions: [{ name: 'pdf', title: 'PDF', validations: { mimeTypes: ['application/pdf'], maxSize: 5 * MB } }],\n};\n\n@Injectable()\nexport class AXDocumentFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_DOCUMENT_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_FILE_FILE_TYPE: AXFileType = {\n name: 'file',\n metadata: createFileTypeMetadata('system'),\n title: 'File',\n icon: 'fa-light fa-file ax-text-neutral-500',\n validations: {\n mimeTypes: ['application/*', 'text/*'],\n minSize: 1,\n maxSize: 100 * MB,\n },\n extensions: [\n { name: 'pdf', title: 'PDF', validations: { mimeTypes: ['application/pdf'], maxSize: 25 * MB } },\n { name: 'doc', title: 'Word' },\n { name: 'docx', title: 'Word' },\n { name: 'txt', title: 'Text', validations: { mimeTypes: ['text/plain'], maxSize: 5 * MB } },\n { name: 'zip', title: 'ZIP', validations: { maxSize: 50 * MB } },\n ],\n};\n\n@Injectable()\nexport class AXFileFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_FILE_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_IMAGE_FILE_TYPE: AXFileType = {\n name: 'image',\n metadata: createFileTypeMetadata('system'),\n title: 'Image',\n icon: 'fa-light fa-image ax-text-purple-500',\n validations: {\n mimeTypes: ['image/*'],\n minSize: 1,\n maxSize: 100 * MB,\n },\n extensions: [\n { name: 'jpg', title: 'JPEG' },\n { name: 'jpeg', title: 'JPEG', validations: { maxSize: 5 * MB } },\n { name: 'png', title: 'PNG' },\n { name: 'gif', title: 'GIF' },\n { name: 'webp', title: 'WebP' },\n { name: 'svg', title: 'SVG', validations: { maxSize: 2 * MB } },\n ],\n};\n\n@Injectable()\nexport class AXImageFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_IMAGE_FILE_TYPE]);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { createFileTypeMetadata } from '../file-type.metadata';\nimport type { AXFileType } from '../file-type.models';\n\nconst MB = 1024 * 1024;\n\nexport const AX_VIDEO_FILE_TYPE: AXFileType = {\n name: 'video',\n metadata: createFileTypeMetadata('system'),\n title: 'Video',\n icon: 'fa-light fa-video ax-text-blue-500',\n validations: {\n mimeTypes: ['video/*'],\n minSize: 1,\n maxSize: 500 * MB,\n },\n extensions: [\n { name: 'mp4', title: 'MP4' },\n { name: 'webm', title: 'WebM', validations: { maxSize: 200 * MB } },\n { name: 'ogg', title: 'OGG' },\n ],\n};\n\n@Injectable()\nexport class AXVideoFileTypeProvider extends AXFileTypeInfoProvider {\n items(): Promise<AXFileType[]> {\n return Promise.resolve([AX_VIDEO_FILE_TYPE]);\n }\n}\n","import { Provider, Type } from '@angular/core';\nimport { provideFileTypeInfoProvider, AXFileTypeInfoProvider } from '../file-type-info-provider';\nimport { AXAudioFileTypeProvider } from './audio-file-type.provider';\nimport { AXDocumentFileTypeProvider } from './document-file-type.provider';\nimport { AXFileFileTypeProvider } from './file-file-type.provider';\nimport { AXImageFileTypeProvider } from './image-file-type.provider';\nimport { AXVideoFileTypeProvider } from './video-file-type.provider';\n\nexport * from './image-file-type.provider';\nexport * from './video-file-type.provider';\nexport * from './audio-file-type.provider';\nexport * from './file-file-type.provider';\nexport * from './document-file-type.provider';\n\n/** Built-in file type provider classes (one logical type per provider). */\nexport const AX_BUILTIN_FILE_TYPE_PROVIDERS = [\n AXImageFileTypeProvider,\n AXVideoFileTypeProvider,\n AXAudioFileTypeProvider,\n AXFileFileTypeProvider,\n AXDocumentFileTypeProvider,\n] as const satisfies readonly Type<AXFileTypeInfoProvider>[];\n\n/** Registers all built-in file type providers (image, video, audio, file, document). */\nexport function provideBuiltinFileTypeProviders(): Provider[] {\n return AX_BUILTIN_FILE_TYPE_PROVIDERS.map((provider) => provideFileTypeInfoProvider(provider));\n}\n\n/** @deprecated Use {@link provideBuiltinFileTypeProviders}. */\nexport const provideDefaultFileTypeProviders = provideBuiltinFileTypeProviders;\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\n\nexport interface AXFileMimeTypeValidationRuleOptions extends AXValidationRuleOptions {\n /** MIME patterns, e.g. `image/*`, `image/png`. */\n allowed: string[];\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMimeType: AXFileMimeTypeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMimeTypeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMimeType';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMimeTypeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const mime = (value instanceof File || value instanceof Blob ? value.type : '').trim().toLowerCase();\n const allowed = options.allowed ?? [];\n const valid =\n allowed.length === 0 ||\n allowed.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));\n\n return {\n rule: this.name,\n result: valid,\n message: valid ? '' : (options.message ?? 'File type is not allowed.'),\n value: mime,\n };\n }\n\n private matchesMime(mime: string, pattern: string): boolean {\n if (!pattern || pattern === '*/*' || pattern === '*') {\n return true;\n }\n if (pattern.endsWith('/*')) {\n const category = pattern.slice(0, -2);\n return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');\n }\n return mime === pattern;\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\nimport { formatFileSizeBytes } from '../../format-file-size';\n\nexport interface AXFileMinSizeValidationRuleOptions extends AXValidationRuleOptions {\n /** Minimum size in bytes. */\n minSize: number;\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMinSize: AXFileMinSizeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMinSizeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMinSize';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMinSizeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const size = value instanceof File || value instanceof Blob ? value.size : 0;\n const valid = size >= options.minSize;\n const limitLabel = formatFileSizeBytes(options.minSize);\n\n return {\n rule: this.name,\n result: valid,\n message: valid\n ? ''\n : (options.message ?? `File is too small. Minimum size is ${limitLabel}.`),\n value: size,\n minSize: options.minSize,\n };\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n AXValidationRule,\n AXValidationRuleOptions,\n AXValidationRuleResult,\n} from '@acorex/core/validation';\nimport { formatFileSizeBytes } from '../../format-file-size';\n\nexport interface AXFileMaxSizeValidationRuleOptions extends AXValidationRuleOptions {\n /** Maximum size in bytes. */\n maxSize: number;\n}\n\ndeclare module '@acorex/core/validation' {\n interface AXValidationRuleOptionsMap {\n fileMaxSize: AXFileMaxSizeValidationRuleOptions;\n }\n}\n\n@Injectable()\nexport class AXFileMaxSizeValidationRule implements AXValidationRule {\n get name(): string {\n return 'fileMaxSize';\n }\n\n async validate(\n value: File | Blob,\n options: AXFileMaxSizeValidationRuleOptions,\n ): Promise<AXValidationRuleResult> {\n const size = value instanceof File || value instanceof Blob ? value.size : 0;\n const valid = size <= options.maxSize;\n const limitLabel = formatFileSizeBytes(options.maxSize);\n\n return {\n rule: this.name,\n result: valid,\n message: valid\n ? ''\n : (options.message ??\n `File is too large. Maximum size is ${limitLabel}.`),\n value: size,\n maxSize: options.maxSize,\n };\n }\n}\n","export * from './file-type.metadata';\nexport * from './file-type.models';\nexport * from './file-type.context';\nexport * from './file-type.copy';\nexport * from './file-type.open';\nexport * from './file-type.resolve';\nexport * from './file-type-info-provider';\nexport * from './file-type-registry.service';\nexport * from './file-type.merge';\nexport * from './file-type.validate';\nexport * from './types.providers';\nexport * from './rules/file-mime-type.rule';\nexport * from './rules/file-min-size.rule';\nexport * from './rules/file-max-size.rule';\n\nimport { Provider } from '@angular/core';\nimport { AXValidationRegistryService } from '@acorex/core/validation';\nimport { provideBuiltinFileTypeProviders } from './types.providers';\nimport { AXFileMaxSizeValidationRule } from './rules/file-max-size.rule';\nimport { AXFileMimeTypeValidationRule } from './rules/file-mime-type.rule';\nimport { AXFileMinSizeValidationRule } from './rules/file-min-size.rule';\n\n/** Validation rule classes to register with {@link AXValidationModule}. */\nexport const AX_FILE_VALIDATION_RULES = [\n AXFileMimeTypeValidationRule,\n AXFileMinSizeValidationRule,\n AXFileMaxSizeValidationRule,\n] as const;\n\n/** Registers file validation rules with {@link AXValidationRegistryService}. */\nexport function provideFileValidationRules(): Provider {\n return {\n provide: 'AXValidationModuleFactory',\n useFactory: (registry: AXValidationRegistryService) => () => {\n registry.register(...AX_FILE_VALIDATION_RULES);\n },\n deps: [AXValidationRegistryService],\n multi: true,\n };\n}\n\n/** Registers built-in image / video / audio / file / document type providers. */\nexport { provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders } from './types.providers';\n\n/**\n * Registers validation rules and optional built-in file type providers.\n * {@link AXFileTypeRegistryService} and {@link AXFileService} are `providedIn: 'root'`.\n */\nexport function provideFileTypeSystem(): Provider[] {\n return [provideFileValidationRules(), ...provideBuiltinFileTypeProviders()];\n}\n","import { AXFormatModule } from '@acorex/core/format';\nimport { AXValidationModule } from '@acorex/core/validation';\nimport { ModuleWithProviders, NgModule, Provider } from '@angular/core';\nimport { AXFileSizeFormatter } from './file-size-formatter';\nimport {\n AX_FILE_VALIDATION_RULES,\n provideDefaultFileTypeProviders,\n provideFileValidationRules,\n} from './file-type';\n\nexport interface AXFileModuleConfig {\n fileTypeProviders?: Provider[];\n includeDefaultFileTypes?: boolean;\n}\n\n@NgModule({\n imports: [\n AXFormatModule.forChild({ formatters: [AXFileSizeFormatter] }),\n AXValidationModule.forChild({ rules: [...AX_FILE_VALIDATION_RULES] }),\n ],\n providers: [AXFileSizeFormatter],\n})\nexport class AXFileModule {\n static forRoot(config?: AXFileModuleConfig): ModuleWithProviders<AXFileModule> {\n const includeDefaults = config?.includeDefaultFileTypes !== false;\n\n return {\n ngModule: AXFileModule,\n providers: [\n provideFileValidationRules(),\n ...(includeDefaults ? provideDefaultFileTypeProviders() : []),\n ...(config?.fileTypeProviders ?? []),\n ],\n };\n }\n\n static forChild(config?: AXFileModuleConfig): ModuleWithProviders<AXFileModule> {\n return AXFileModule.forRoot(config);\n }\n}\n","import type { AXValidationRuleResult } from '@acorex/core/validation';\nimport { DOCUMENT, inject, Injectable, isDevMode } from '@angular/core';\nimport { AXFileTypeRegistryService } from './file-type/file-type-registry.service';\nimport type { AXFileType } from './file-type/file-type.models';\n\nexport interface AXFileChooseOptions {\n /** Logical type name(s) from {@link AXFileTypeRegistryService}. When set, files are validated against the catalog. */\n fileType?: string | string[];\n accept?: string;\n multiple?: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AXFileService {\n private readonly document = inject(DOCUMENT);\n private readonly fileTypes = inject(AXFileTypeRegistryService);\n\n async getFileTypes(): Promise<AXFileType[]> {\n return this.fileTypes.getTypes();\n }\n\n async getFileType(name: string): Promise<AXFileType | undefined> {\n return this.fileTypes.get(name);\n }\n\n async getAcceptAttribute(fileType?: string | string[]): Promise<string> {\n return this.fileTypes.accept(fileType);\n }\n\n async matchFileType(file: File): Promise<AXFileType | undefined> {\n return this.fileTypes.matchType(file);\n }\n\n validate(file: File, fileType: string | string[]): Promise<AXValidationRuleResult[]> {\n return this.fileTypes.validateAgainstTypes(file, fileType);\n }\n\n validateMany(\n files: File[],\n fileType: string | string[],\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n return this.fileTypes.validateMany(files, fileType);\n }\n\n /**\n * Opens a file selection dialog.\n * With `fileType`, returns files that pass catalog validation (`accept` defaults from the catalog).\n * Without `fileType`, returns all selected files (legacy `accept` / `multiple` only).\n */\n async chooseValidated(\n options: AXFileChooseOptions,\n ): Promise<{ accepted: File[]; rejected: { file: File; errors: AXValidationRuleResult[] }[] }> {\n const resolved = await this.resolveChooseOptions(options);\n const files = await this.openFileDialog(resolved);\n\n if (files.length === 0) {\n return { accepted: [], rejected: [] };\n }\n\n if (options.fileType) {\n return this.validateMany(files, options.fileType);\n }\n\n return { accepted: files, rejected: [] };\n }\n\n async choose(options: AXFileChooseOptions): Promise<File[]> {\n const { accepted } = await this.chooseValidated(options);\n return accepted;\n }\n\n blobToBase64(blob: Blob): Promise<string> {\n if (!(blob instanceof Blob)) {\n return Promise.reject(new Error('input is not blob'));\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(reader.error);\n reader.onload = () => resolve(reader.result as string);\n reader.readAsDataURL(blob);\n });\n }\n\n getSize(file: File | Blob | string): number | false {\n if (this.isBase64(file as string)) {\n return this.getBase64Size(file as string);\n }\n return false;\n }\n\n isBase64(base64: string): boolean {\n const regx = /[^:]\\w+\\/[\\w-+\\d.]+(?=;|,)/;\n return regx.test(base64);\n }\n\n getBase64Size(base64: string): number {\n return atob(base64.substring(base64.indexOf(',') + 1)).length;\n }\n\n private async resolveChooseOptions(\n options: AXFileChooseOptions,\n ): Promise<{ accept: string; multiple: boolean }> {\n const multiple = options.multiple ?? false;\n\n if (options.fileType) {\n const accept = options.accept ?? (await this.getAcceptAttribute(options.fileType));\n\n if (isDevMode() && !accept) {\n const name = Array.isArray(options.fileType) ? options.fileType.join(', ') : options.fileType;\n console.warn(\n `[AXFileService] No accept filter for file type \"${name}\". ` +\n 'Register a file type provider (e.g. provideConversationFileCatalog).',\n );\n }\n\n return { accept, multiple };\n }\n\n return { accept: options.accept ?? '', multiple };\n }\n\n private openFileDialog(options: { accept: string; multiple: boolean }): Promise<File[]> {\n return new Promise<File[]>((resolve, reject) => {\n const input: HTMLInputElement = this.document.createElement('input');\n input.style.display = 'none';\n this.document.body.appendChild(input);\n input.type = 'file';\n input.accept = options.accept;\n input.multiple = options.multiple;\n\n const cleanup = () => {\n input.removeEventListener('change', onChange);\n input.removeEventListener('error', onError);\n if (input.parentNode) {\n this.document.body.removeChild(input);\n }\n input.remove();\n };\n\n const onError = (e: Event) => {\n cleanup();\n reject(e);\n };\n\n const onChange = () => {\n const files = Array.from(input.files ?? []);\n cleanup();\n resolve(files);\n };\n\n input.addEventListener('change', onChange);\n input.addEventListener('error', onError);\n input.click();\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["MB"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acorex/core",
3
- "version": "21.0.3-next.16",
3
+ "version": "21.0.3-next.17",
4
4
  "peerDependencies": {
5
5
  "lodash-es": ">=4.17.21",
6
6
  "memoizee": ">=0.4.15",
@@ -58,8 +58,8 @@ declare function resolveFileCopyText(result: AXFileCopyResult): string | null;
58
58
 
59
59
  /** Result of {@link AXFileType.open}; `false` means the payload was not opened. */
60
60
  type AXFileOpenResult = void | boolean | null | undefined;
61
- /** Runs {@link AXFileType.open} in the caller's injection context. */
62
- declare function runFileTypeOpen(fileType: Pick<AXFileType, 'open'>, ctx: AXFileTypeOpenContext, payload: unknown): Promise<AXFileOpenResult> | AXFileOpenResult;
61
+ /** Runs `open` from extension first, then parent type, in the caller's injection context. */
62
+ declare function runFileTypeOpen(type: AXFileType, ctx: AXFileTypeOpenContext, payload: unknown, extension?: AXFileTypeExtension): Promise<AXFileOpenResult> | AXFileOpenResult;
63
63
 
64
64
  /** Metadata key for catalog usage context. */
65
65
  declare const AX_FILE_TYPE_METADATA_PURPOSE: "purpose";
@@ -78,7 +78,7 @@ interface AXFileValidationRule {
78
78
  }
79
79
  /**
80
80
  * Common file constraints shared by {@link AXFileType} and {@link AXFileTypeExtension}.
81
- * Extension `validations` are partial and override the parent type field-by-field.
81
+ * Extension `validations` override the parent type field-by-field when merged.
82
82
  */
83
83
  interface AXFileValidations {
84
84
  mimeTypes?: string[];
@@ -86,26 +86,20 @@ interface AXFileValidations {
86
86
  maxSize?: number;
87
87
  rules?: AXFileValidationRule[];
88
88
  }
89
- /** Extension entry; `validations` override the parent {@link AXFileType.validations}. */
90
- interface AXFileTypeExtension {
91
- name: string;
92
- title?: string;
93
- icon?: string;
94
- validations?: Partial<AXFileValidations>;
95
- }
89
+ type AXFileTypeUtilities = Record<string, (ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown>;
96
90
  /**
97
91
  * Logical file category (image, video, …).
98
92
  *
99
93
  * - With type `validations` set: any file matching those rules is allowed; `extensions` only override when matched.
100
94
  * - With empty / omitted `validations` and `extensions` listed: only those extensions are allowed.
101
95
  */
102
- interface AXFileType<T = Record<string, (ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown>> {
96
+ interface AXFileType<T extends AXFileTypeUtilities = AXFileTypeUtilities> {
103
97
  name: string;
104
98
  title?: string;
105
99
  icon?: string;
106
100
  metadata?: AXFileTypeMetadata;
107
101
  validations?: AXFileValidations;
108
- extensions?: AXFileTypeExtension[];
102
+ extensions?: AXFileTypeExtension<T>[];
109
103
  /** Dynamic utility functions available for this file type. */
110
104
  utilities?: T;
111
105
  paste?: () => Promise<unknown>;
@@ -120,12 +114,41 @@ interface AXFileType<T = Record<string, (ctx: AXFileTypeContext, ...args: unknow
120
114
  */
121
115
  open?: (ctx: AXFileTypeOpenContext, payload: unknown) => Promise<AXFileOpenResult> | AXFileOpenResult;
122
116
  }
117
+ /** Extension entry — {@link AXFileType} without nested `extensions`. */
118
+ type AXFileTypeExtension<T extends AXFileTypeUtilities = AXFileTypeUtilities> = Omit<AXFileType<T>, 'extensions'>;
123
119
 
124
120
  declare function getFileTypePurposes(type: AXFileType): string[];
125
121
  declare function fileTypeMatchesPurpose(type: AXFileType, purpose: string | string[]): boolean;
126
122
  declare function filterFileTypesByPurpose(types: AXFileType[], purpose?: string | string[]): AXFileType[];
127
123
  declare function createFileTypeMetadata(purpose: string | string[]): NonNullable<AXFileType['metadata']>;
128
124
 
125
+ /** Hint for resolving a catalog extension entry. */
126
+ interface AXFileTypeExtensionHint {
127
+ file?: File;
128
+ extensionName?: string;
129
+ mimeType?: string;
130
+ }
131
+ /** Matches a MIME type against a catalog pattern (`image/*`, exact type, …). */
132
+ declare function matchesFileMime(mime: string, pattern: string): boolean;
133
+ /** Finds an extension entry by its `name` (without dot). */
134
+ declare function findFileTypeExtensionByName(type: AXFileType, extensionName: string): AXFileTypeExtension | undefined;
135
+ /** Finds an extension entry whose validations include the given MIME type. */
136
+ declare function findFileTypeExtensionForMime(type: AXFileType, mimeType: string): AXFileTypeExtension | undefined;
137
+ /** Matching extension entry for a file within a type, if any. */
138
+ declare function findFileTypeExtension(file: File, type: AXFileType): AXFileTypeExtension | undefined;
139
+ /** Resolves the best-matching extension entry for a file or hint. */
140
+ declare function resolveFileTypeExtension(type: AXFileType, hint?: AXFileTypeExtensionHint): AXFileTypeExtension | undefined;
141
+ declare function resolveFileTypeCopy(type: AXFileType, extension?: AXFileTypeExtension): AXFileType['copy'] | undefined;
142
+ declare function resolveFileTypeOpen(type: AXFileType, extension?: AXFileTypeExtension): AXFileType['open'] | undefined;
143
+ declare function resolveFileTypePaste(type: AXFileType, extension?: AXFileTypeExtension): AXFileType['paste'] | undefined;
144
+ declare function resolveFileTypeUtility(type: AXFileType, extension: AXFileTypeExtension | undefined, name: string): ((ctx: AXFileTypeContext, ...args: unknown[]) => Promise<unknown> | unknown) | undefined;
145
+ /** Runs `copy` from extension first, then parent type. */
146
+ declare function runFileTypeCopy(type: AXFileType, payload: unknown, extension?: AXFileTypeExtension): Promise<AXFileCopyResult>;
147
+ /** Runs a utility from extension first, then parent type. */
148
+ declare function runFileTypeUtility(type: AXFileType, ctx: AXFileTypeContext, extension: AXFileTypeExtension | undefined, name: string, ...args: unknown[]): Promise<unknown> | unknown;
149
+ /** Runs a catalog utility with optional file-based extension resolution. */
150
+ declare function runFileTypeUtilityForFile(type: AXFileType, ctx: AXFileTypeContext, file: File | undefined, name: string, ...args: unknown[]): Promise<unknown> | unknown;
151
+
129
152
  /** Contributes {@link AXFileType} entries (multi provider). */
130
153
  declare abstract class AXFileTypeInfoProvider {
131
154
  abstract items(): Promise<AXFileType[]>;
@@ -155,14 +178,13 @@ declare class AXFileTypeRegistryService {
155
178
  errors: AXValidationRuleResult[];
156
179
  }[];
157
180
  }>;
158
- private matchesMime;
159
181
  static ɵfac: i0.ɵɵFactoryDeclaration<AXFileTypeRegistryService, never>;
160
182
  static ɵprov: i0.ɵɵInjectableDeclaration<AXFileTypeRegistryService>;
161
183
  }
162
184
 
163
185
  /** Merges type-level validations with extension overrides (extension wins per field). */
164
186
  declare function mergeFileValidations(base: AXFileValidations, override?: Partial<AXFileValidations>): AXFileValidations;
165
- /** Resolved validations for a type + optional extension. */
187
+ /** Resolved validations for a type + optional extension entry. */
166
188
  declare function resolveFileValidations(type: AXFileType, extension?: AXFileTypeExtension): AXFileValidations;
167
189
  /** True when no mime/size/rules are defined on the type. */
168
190
  declare function isEmptyFileValidations(validations?: AXFileValidations): boolean;
@@ -173,8 +195,6 @@ declare function isEmptyFileValidations(validations?: AXFileValidations): boolea
173
195
  declare function isExtensionsOnlyType(type: AXFileType): boolean;
174
196
  /** File extension from name (lowercase, no dot). */
175
197
  declare function getFileExtension(fileName: string): string;
176
- /** Matching extension entry for a file within a type, if any. */
177
- declare function findFileTypeExtension(file: File, type: AXFileType): AXFileTypeExtension | undefined;
178
198
 
179
199
  /** Maps {@link AXFileValidations} to executable validation entries. */
180
200
  declare function fileValidationsToRules(validations: AXFileValidations): AXFileValidationRule[];
@@ -342,5 +362,5 @@ declare class AXFileService {
342
362
  static ɵprov: i0.ɵɵInjectableDeclaration<AXFileService>;
343
363
  }
344
364
 
345
- export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileValidationRules, resolveFileCopyText, resolveFileValidations, runFileTypeOpen, validateFileAgainstType, validateFileWithValidations };
346
- export type { AXFileChooseOptions, AXFileCopyData, AXFileCopyResult, AXFileMaxSizeValidationRuleOptions, AXFileMimeTypeValidationRuleOptions, AXFileMinSizeValidationRuleOptions, AXFileModuleConfig, AXFileOpenResult, AXFileSizeFormatterOptions, AXFileType, AXFileTypeContext, AXFileTypeExtension, AXFileTypeMetadata, AXFileTypeOpenContext, AXFileTypeQuery, AXFileValidationRule, AXFileValidations };
365
+ export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, findFileTypeExtensionByName, findFileTypeExtensionForMime, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, matchesFileMime, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileValidationRules, resolveFileCopyText, resolveFileTypeCopy, resolveFileTypeExtension, resolveFileTypeOpen, resolveFileTypePaste, resolveFileTypeUtility, resolveFileValidations, runFileTypeCopy, runFileTypeOpen, runFileTypeUtility, runFileTypeUtilityForFile, validateFileAgainstType, validateFileWithValidations };
366
+ export type { AXFileChooseOptions, AXFileCopyData, AXFileCopyResult, AXFileMaxSizeValidationRuleOptions, AXFileMimeTypeValidationRuleOptions, AXFileMinSizeValidationRuleOptions, AXFileModuleConfig, AXFileOpenResult, AXFileSizeFormatterOptions, AXFileType, AXFileTypeContext, AXFileTypeExtension, AXFileTypeExtensionHint, AXFileTypeMetadata, AXFileTypeOpenContext, AXFileTypeQuery, AXFileValidationRule, AXFileValidations };