portapack 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +67 -8
- package/.github/workflows/ci.yml +5 -4
- package/.releaserc.js +25 -27
- package/CHANGELOG.md +12 -19
- package/LICENSE.md +21 -0
- package/README.md +34 -36
- package/commitlint.config.js +30 -34
- package/dist/cli/cli-entry.cjs +199 -135
- package/dist/cli/cli-entry.cjs.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +194 -134
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.ts +36 -34
- package/docs/.vitepress/sidebar-generator.ts +89 -38
- package/docs/cli.md +29 -82
- package/docs/code-of-conduct.md +7 -1
- package/docs/configuration.md +103 -117
- package/docs/contributing.md +6 -2
- package/docs/deployment.md +10 -5
- package/docs/development.md +8 -5
- package/docs/getting-started.md +76 -45
- package/docs/index.md +1 -1
- package/docs/public/android-chrome-192x192.png +0 -0
- package/docs/public/android-chrome-512x512.png +0 -0
- package/docs/public/apple-touch-icon.png +0 -0
- package/docs/public/favicon-16x16.png +0 -0
- package/docs/public/favicon-32x32.png +0 -0
- package/docs/public/favicon.ico +0 -0
- package/docs/site.webmanifest +1 -0
- package/docs/troubleshooting.md +12 -1
- package/examples/main.ts +7 -10
- package/examples/sample-project/script.js +1 -1
- package/jest.config.ts +8 -13
- package/nodemon.json +5 -10
- package/package.json +2 -5
- package/src/cli/cli-entry.ts +2 -2
- package/src/cli/cli.ts +21 -16
- package/src/cli/options.ts +127 -113
- package/src/core/bundler.ts +254 -221
- package/src/core/extractor.ts +639 -520
- package/src/core/minifier.ts +173 -162
- package/src/core/packer.ts +141 -137
- package/src/core/parser.ts +74 -73
- package/src/core/web-fetcher.ts +270 -258
- package/src/index.ts +18 -17
- package/src/types.ts +9 -11
- package/src/utils/font.ts +12 -6
- package/src/utils/logger.ts +110 -105
- package/src/utils/meta.ts +75 -76
- package/src/utils/mime.ts +50 -50
- package/src/utils/slugify.ts +33 -34
- package/tests/unit/cli/cli-entry.test.ts +72 -70
- package/tests/unit/cli/cli.test.ts +314 -278
- package/tests/unit/cli/options.test.ts +294 -301
- package/tests/unit/core/bundler.test.ts +426 -329
- package/tests/unit/core/extractor.test.ts +828 -380
- package/tests/unit/core/minifier.test.ts +374 -274
- package/tests/unit/core/packer.test.ts +298 -264
- package/tests/unit/core/parser.test.ts +538 -150
- package/tests/unit/core/web-fetcher.test.ts +389 -359
- package/tests/unit/index.test.ts +238 -197
- package/tests/unit/utils/font.test.ts +26 -21
- package/tests/unit/utils/logger.test.ts +267 -260
- package/tests/unit/utils/meta.test.ts +29 -28
- package/tests/unit/utils/mime.test.ts +73 -74
- package/tests/unit/utils/slugify.test.ts +14 -12
- package/tsconfig.build.json +9 -10
- package/tsconfig.jest.json +2 -1
- package/tsconfig.json +2 -2
- package/tsup.config.ts +8 -8
- package/typedoc.json +5 -9
- package/docs/demo.md +0 -46
- /package/docs/{portapack-transparent.png → public/portapack-transparent.png} +0 -0
- /package/docs/{portapack.jpg → public/portapack.jpg} +0 -0
package/src/types.ts
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
*/
|
19
19
|
export interface Asset {
|
20
20
|
type: 'css' | 'js' | 'image' | 'font' | 'video' | 'audio' | 'other'; // Add video and audio
|
21
|
-
|
21
|
+
|
22
22
|
/** The resolved or original URL of the asset */
|
23
23
|
url: string;
|
24
24
|
|
@@ -94,17 +94,16 @@ export interface BundleOptions {
|
|
94
94
|
// --- LogLevel Enum ---
|
95
95
|
// Defines available log levels as a numeric enum for comparisons.
|
96
96
|
export enum LogLevel {
|
97
|
-
NONE = 0,
|
98
|
-
ERROR = 1,
|
99
|
-
WARN = 2,
|
100
|
-
INFO = 3,
|
101
|
-
DEBUG = 4
|
97
|
+
NONE = 0, // No logging (equivalent to 'silent')
|
98
|
+
ERROR = 1, // Only errors
|
99
|
+
WARN = 2, // Errors and warnings
|
100
|
+
INFO = 3, // Errors, warnings, and info (Default)
|
101
|
+
DEBUG = 4, // All messages (Verbose)
|
102
102
|
}
|
103
103
|
|
104
104
|
// --- String Literal Type for LogLevel Names (Optional, useful for CLI parsing) ---
|
105
105
|
export type LogLevelName = 'debug' | 'info' | 'warn' | 'error' | 'silent' | 'none';
|
106
106
|
|
107
|
-
|
108
107
|
/**
|
109
108
|
* Summary statistics and metadata returned after the packing/bundling process completes.
|
110
109
|
*/
|
@@ -138,14 +137,13 @@ export interface BuildResult {
|
|
138
137
|
metadata: BundleMetadata;
|
139
138
|
}
|
140
139
|
|
141
|
-
|
142
140
|
/** CLI-specific options extending BundleOptions. */
|
143
141
|
export interface CLIOptions extends BundleOptions {
|
144
142
|
/** Input file or URL (positional). */
|
145
143
|
input?: string;
|
146
144
|
/** Max depth for recursive crawling (numeric alias for recursive). */
|
147
|
-
|
148
|
-
|
145
|
+
maxDepth?: number; // Used by commander, then merged into 'recursive'
|
146
|
+
minify?: boolean; // Minify assets (defaults to true)
|
149
147
|
}
|
150
148
|
|
151
149
|
/**
|
@@ -160,4 +158,4 @@ export interface CLIResult {
|
|
160
158
|
|
161
159
|
/** Final exit code intended for the process (0 for success, non-zero for errors) */
|
162
160
|
exitCode: number;
|
163
|
-
}
|
161
|
+
}
|
package/src/utils/font.ts
CHANGED
@@ -16,12 +16,18 @@ export function getFontMimeType(fontUrl: string): string {
|
|
16
16
|
const ext = path.extname(fontUrl).toLowerCase().replace('.', '');
|
17
17
|
|
18
18
|
switch (ext) {
|
19
|
-
case 'woff':
|
20
|
-
|
21
|
-
case '
|
22
|
-
|
23
|
-
case '
|
24
|
-
|
19
|
+
case 'woff':
|
20
|
+
return 'font/woff';
|
21
|
+
case 'woff2':
|
22
|
+
return 'font/woff2';
|
23
|
+
case 'ttf':
|
24
|
+
return 'font/ttf';
|
25
|
+
case 'otf':
|
26
|
+
return 'font/otf';
|
27
|
+
case 'eot':
|
28
|
+
return 'application/vnd.ms-fontobject';
|
29
|
+
default:
|
30
|
+
return 'application/octet-stream';
|
25
31
|
}
|
26
32
|
}
|
27
33
|
|
package/src/utils/logger.ts
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
* to control output verbosity throughout the application (core, API, CLI).
|
5
5
|
*/
|
6
6
|
|
7
|
-
// FIX: Use a regular import for the enum, not 'import type'
|
8
7
|
import { LogLevel } from '../types';
|
9
8
|
// Assuming LogLevel enum is defined and exported in '../types' like:
|
10
9
|
// export enum LogLevel { NONE = 0, ERROR = 1, WARN = 2, INFO = 3, DEBUG = 4 }
|
@@ -14,7 +13,7 @@ import { LogLevel } from '../types';
|
|
14
13
|
* (Note: Currently constructor only accepts LogLevel directly)
|
15
14
|
*/
|
16
15
|
export interface LoggerOptions {
|
17
|
-
|
16
|
+
level?: LogLevel;
|
18
17
|
}
|
19
18
|
|
20
19
|
/**
|
@@ -22,118 +21,124 @@ export interface LoggerOptions {
|
|
22
21
|
* Uses standard console methods (debug, info, warn, error) for output.
|
23
22
|
*/
|
24
23
|
export class Logger {
|
25
|
-
|
26
|
-
|
24
|
+
/** The current minimum log level required for a message to be output. */
|
25
|
+
public level: LogLevel;
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
27
|
+
/**
|
28
|
+
* Creates a new Logger instance.
|
29
|
+
* Defaults to LogLevel.INFO if no level is provided.
|
30
|
+
*
|
31
|
+
* @param {LogLevel} [level=LogLevel.INFO] - The initial log level for this logger instance.
|
32
|
+
* Must be one of the values from the LogLevel enum.
|
33
|
+
*/
|
34
|
+
constructor(level: LogLevel = LogLevel.INFO) {
|
35
|
+
// Defaulting to INFO level using the enum value
|
36
|
+
// Ensure a valid LogLevel enum member is provided or default correctly
|
37
|
+
this.level = level !== undefined && LogLevel[level] !== undefined ? level : LogLevel.INFO; // Use the enum value for default
|
38
|
+
}
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
/**
|
41
|
+
* Updates the logger's current level. Messages below this level will be suppressed.
|
42
|
+
*
|
43
|
+
* @param {LogLevel} level - The new log level to set. Must be a LogLevel enum member.
|
44
|
+
*/
|
45
|
+
setLevel(level: LogLevel): void {
|
46
|
+
this.level = level;
|
47
|
+
}
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
49
|
+
/**
|
50
|
+
* Logs a debug message if the current log level is DEBUG or higher.
|
51
|
+
*
|
52
|
+
* @param {string} message - The debug message string.
|
53
|
+
*/
|
54
|
+
debug(message: string): void {
|
55
|
+
// Use enum member for comparison
|
56
|
+
if (this.level >= LogLevel.DEBUG) {
|
57
|
+
console.debug(`[DEBUG] ${message}`);
|
61
58
|
}
|
59
|
+
}
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
}
|
61
|
+
/**
|
62
|
+
* Logs an informational message if the current log level is INFO or higher.
|
63
|
+
*
|
64
|
+
* @param {string} message - The informational message string.
|
65
|
+
*/
|
66
|
+
info(message: string): void {
|
67
|
+
// Use enum member for comparison
|
68
|
+
if (this.level >= LogLevel.INFO) {
|
69
|
+
console.info(`[INFO] ${message}`);
|
73
70
|
}
|
71
|
+
}
|
74
72
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
}
|
73
|
+
/**
|
74
|
+
* Logs a warning message if the current log level is WARN or higher.
|
75
|
+
*
|
76
|
+
* @param {string} message - The warning message string.
|
77
|
+
*/
|
78
|
+
warn(message: string): void {
|
79
|
+
// Use enum member for comparison
|
80
|
+
if (this.level >= LogLevel.WARN) {
|
81
|
+
console.warn(`[WARN] ${message}`);
|
85
82
|
}
|
83
|
+
}
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
}
|
85
|
+
/**
|
86
|
+
* Logs an error message if the current log level is ERROR or higher.
|
87
|
+
*
|
88
|
+
* @param {string} message - The error message string.
|
89
|
+
*/
|
90
|
+
error(message: string): void {
|
91
|
+
// Use enum member for comparison
|
92
|
+
if (this.level >= LogLevel.ERROR) {
|
93
|
+
console.error(`[ERROR] ${message}`);
|
97
94
|
}
|
95
|
+
}
|
98
96
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
97
|
+
/**
|
98
|
+
* Static factory method to create a Logger instance based on a simple boolean `verbose` flag.
|
99
|
+
*
|
100
|
+
* @static
|
101
|
+
* @param {{ verbose?: boolean }} [options={}] - An object potentially containing a `verbose` flag.
|
102
|
+
* @returns {Logger} A new Logger instance set to LogLevel.DEBUG if options.verbose is true,
|
103
|
+
* otherwise set to LogLevel.INFO.
|
104
|
+
*/
|
105
|
+
static fromVerboseFlag(options: { verbose?: boolean } = {}): Logger {
|
106
|
+
// Use enum members for assignment
|
107
|
+
return new Logger(options.verbose ? LogLevel.DEBUG : LogLevel.INFO);
|
108
|
+
}
|
111
109
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
110
|
+
/**
|
111
|
+
* Static factory method to create a Logger instance based on a LogLevel string name.
|
112
|
+
* Useful for creating a logger from config files or environments variables.
|
113
|
+
*
|
114
|
+
* @static
|
115
|
+
* @param {string | undefined} levelName - The name of the log level (e.g., 'debug', 'info', 'warn', 'error', 'silent'/'none'). Case-insensitive.
|
116
|
+
* @param {LogLevel} [defaultLevel=LogLevel.INFO] - The level to use if levelName is invalid or undefined.
|
117
|
+
* @returns {Logger} A new Logger instance set to the corresponding LogLevel.
|
118
|
+
*/
|
119
|
+
static fromLevelName(levelName?: string, defaultLevel: LogLevel = LogLevel.INFO): Logger {
|
120
|
+
if (!levelName) {
|
121
|
+
return new Logger(defaultLevel);
|
122
|
+
}
|
123
|
+
switch (levelName.toLowerCase()) {
|
124
|
+
// Return enum members
|
125
|
+
case 'debug':
|
126
|
+
return new Logger(LogLevel.DEBUG);
|
127
|
+
case 'info':
|
128
|
+
return new Logger(LogLevel.INFO);
|
129
|
+
case 'warn':
|
130
|
+
return new Logger(LogLevel.WARN);
|
131
|
+
case 'error':
|
132
|
+
return new Logger(LogLevel.ERROR);
|
133
|
+
case 'silent':
|
134
|
+
case 'none':
|
135
|
+
return new Logger(LogLevel.NONE);
|
136
|
+
default:
|
137
|
+
// Use console.warn directly here as logger might not be ready
|
138
|
+
console.warn(
|
139
|
+
`[Logger] Invalid log level name "${levelName}". Defaulting to ${LogLevel[defaultLevel]}.`
|
140
|
+
);
|
141
|
+
return new Logger(defaultLevel);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
package/src/utils/meta.ts
CHANGED
@@ -12,89 +12,88 @@ import type { BundleMetadata } from '../types'; // Assuming types are in ../type
|
|
12
12
|
* (asset counts, page counts, errors) during the HTML bundling process.
|
13
13
|
*/
|
14
14
|
export class BuildTimer {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
private startTime: number;
|
16
|
+
private input: string;
|
17
|
+
private pagesBundled?: number; // Tracks pages for recursive bundles
|
18
|
+
private assetCount: number = 0; // Tracks discovered/processed assets
|
19
|
+
private errors: string[] = []; // Collects warnings/errors
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
/**
|
22
|
+
* Creates and starts a build timer session for a given input.
|
23
|
+
*
|
24
|
+
* @param {string} input - The source file path or URL being processed.
|
25
|
+
*/
|
26
|
+
constructor(input: string) {
|
27
|
+
this.startTime = Date.now();
|
28
|
+
this.input = input;
|
29
|
+
}
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
/**
|
32
|
+
* Explicitly sets the number of assets discovered or processed.
|
33
|
+
* This might be called after asset extraction/minification.
|
34
|
+
*
|
35
|
+
* @param {number} count - The total number of assets.
|
36
|
+
*/
|
37
|
+
setAssetCount(count: number): void {
|
38
|
+
this.assetCount = count;
|
39
|
+
}
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
/**
|
42
|
+
* Records a warning or error message encountered during the build.
|
43
|
+
* These are added to the final metadata.
|
44
|
+
*
|
45
|
+
* @param {string} message - The warning or error description.
|
46
|
+
*/
|
47
|
+
addError(message: string): void {
|
48
|
+
this.errors.push(message);
|
49
|
+
}
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
/**
|
52
|
+
* Sets the number of pages bundled, typically used in multi-page
|
53
|
+
* or recursive bundling scenarios.
|
54
|
+
*
|
55
|
+
* @param {number} count - The number of HTML pages included in the bundle.
|
56
|
+
*/
|
57
|
+
setPageCount(count: number): void {
|
58
|
+
this.pagesBundled = count;
|
59
|
+
}
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
61
|
+
/**
|
62
|
+
* Stops the timer, calculates final metrics, and returns the complete
|
63
|
+
* BundleMetadata object. Merges any explicitly provided metadata
|
64
|
+
* (like assetCount calculated elsewhere) with the timer's tracked data.
|
65
|
+
*
|
66
|
+
* @param {string} finalHtml - The final generated HTML string, used to calculate output size.
|
67
|
+
* @param {Partial<BundleMetadata>} [extra] - Optional object containing metadata fields
|
68
|
+
* (like assetCount or pre-calculated errors) that should override the timer's internal values.
|
69
|
+
* @returns {BundleMetadata} The finalized metadata object for the build process.
|
70
|
+
*/
|
71
|
+
finish(html: string, extra?: Partial<BundleMetadata>): BundleMetadata {
|
72
|
+
const buildTimeMs = Date.now() - this.startTime;
|
73
|
+
const outputSize = Buffer.byteLength(html || '', 'utf-8');
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
const combinedErrors = Array.from(new Set([...this.errors, ...(extra?.errors ?? [])]));
|
75
|
+
// Combine internal errors with any errors passed in 'extra', avoiding duplicates
|
76
|
+
const combinedErrors = Array.from(new Set([...this.errors, ...(extra?.errors ?? [])]));
|
78
77
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
78
|
+
const finalMetadata: BundleMetadata = {
|
79
|
+
input: this.input,
|
80
|
+
outputSize,
|
81
|
+
buildTimeMs,
|
82
|
+
assetCount: extra?.assetCount ?? this.assetCount,
|
83
|
+
pagesBundled: extra?.pagesBundled ?? this.pagesBundled,
|
84
|
+
// Assign the combined errors array
|
85
|
+
errors: combinedErrors,
|
86
|
+
};
|
88
87
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
88
|
+
// Clean up optional fields if they weren't set/provided or are empty
|
89
|
+
if (finalMetadata.pagesBundled === undefined) {
|
90
|
+
delete finalMetadata.pagesBundled;
|
91
|
+
}
|
92
|
+
// Delete errors only if the *combined* array is empty
|
93
|
+
if (finalMetadata.errors?.length === 0) {
|
94
|
+
delete finalMetadata.errors;
|
95
|
+
}
|
97
96
|
|
98
|
-
|
97
|
+
return finalMetadata;
|
99
98
|
}
|
100
|
-
}
|
99
|
+
}
|
package/src/utils/mime.ts
CHANGED
@@ -10,46 +10,46 @@ import type { Asset } from '../types'; // Assuming types are in ../types
|
|
10
10
|
* Maps common file extensions to their corresponding MIME types and general Asset types.
|
11
11
|
*/
|
12
12
|
const MIME_MAP: Record<string, { mime: string; assetType: Asset['type'] }> = {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
13
|
+
// CSS
|
14
|
+
'.css': { mime: 'text/css', assetType: 'css' },
|
15
|
+
// JavaScript
|
16
|
+
'.js': { mime: 'application/javascript', assetType: 'js' },
|
17
|
+
'.mjs': { mime: 'application/javascript', assetType: 'js' },
|
18
|
+
// Images
|
19
|
+
'.png': { mime: 'image/png', assetType: 'image' },
|
20
|
+
'.jpg': { mime: 'image/jpeg', assetType: 'image' },
|
21
|
+
'.jpeg': { mime: 'image/jpeg', assetType: 'image' },
|
22
|
+
'.gif': { mime: 'image/gif', assetType: 'image' },
|
23
|
+
'.svg': { mime: 'image/svg+xml', assetType: 'image' },
|
24
|
+
'.webp': { mime: 'image/webp', assetType: 'image' },
|
25
|
+
'.ico': { mime: 'image/x-icon', assetType: 'image' },
|
26
|
+
'.avif': { mime: 'image/avif', assetType: 'image' },
|
27
|
+
// Fonts
|
28
|
+
'.woff': { mime: 'font/woff', assetType: 'font' },
|
29
|
+
'.woff2': { mime: 'font/woff2', assetType: 'font' },
|
30
|
+
'.ttf': { mime: 'font/ttf', assetType: 'font' },
|
31
|
+
'.otf': { mime: 'font/otf', assetType: 'font' },
|
32
|
+
'.eot': { mime: 'application/vnd.ms-fontobject', assetType: 'font' },
|
33
|
+
// Audio/Video (add more as needed)
|
34
|
+
'.mp3': { mime: 'audio/mpeg', assetType: 'other' },
|
35
|
+
'.ogg': { mime: 'audio/ogg', assetType: 'other' },
|
36
|
+
'.wav': { mime: 'audio/wav', assetType: 'other' },
|
37
|
+
'.mp4': { mime: 'video/mp4', assetType: 'other' },
|
38
|
+
'.webm': { mime: 'video/webm', assetType: 'other' },
|
39
|
+
// Other common web types
|
40
|
+
'.json': { mime: 'application/json', assetType: 'other' },
|
41
|
+
'.webmanifest': { mime: 'application/manifest+json', assetType: 'other' },
|
42
|
+
'.xml': { mime: 'application/xml', assetType: 'other' },
|
43
|
+
'.html': { mime: 'text/html', assetType: 'other' }, // Usually not needed as asset, but for completeness
|
44
|
+
'.txt': { mime: 'text/plain', assetType: 'other' },
|
45
45
|
};
|
46
46
|
|
47
47
|
/**
|
48
48
|
* Default MIME type and Asset type for unknown file extensions.
|
49
49
|
*/
|
50
50
|
const DEFAULT_MIME_TYPE = {
|
51
|
-
|
52
|
-
|
51
|
+
mime: 'application/octet-stream',
|
52
|
+
assetType: 'other' as Asset['type'], // Explicit cast needed
|
53
53
|
};
|
54
54
|
|
55
55
|
/**
|
@@ -61,21 +61,21 @@ const DEFAULT_MIME_TYPE = {
|
|
61
61
|
* if the extension is unknown.
|
62
62
|
*/
|
63
63
|
export function guessMimeType(urlOrPath: string): { mime: string; assetType: Asset['type'] } {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
64
|
+
if (!urlOrPath) {
|
65
|
+
return DEFAULT_MIME_TYPE;
|
66
|
+
}
|
67
|
+
// Extract the extension, handling potential query parameters or fragments
|
68
|
+
let ext = '';
|
69
|
+
try {
|
70
|
+
// Use URL parsing first to handle URLs correctly
|
71
|
+
const parsedUrl = new URL(urlOrPath);
|
72
|
+
ext = path.extname(parsedUrl.pathname).toLowerCase();
|
73
|
+
} catch {
|
74
|
+
// If it's not a valid URL, treat it as a path
|
75
|
+
ext = path.extname(urlOrPath).toLowerCase();
|
76
|
+
}
|
77
77
|
|
78
|
-
|
78
|
+
return MIME_MAP[ext] || DEFAULT_MIME_TYPE;
|
79
79
|
}
|
80
80
|
|
81
81
|
/**
|
@@ -86,5 +86,5 @@ export function guessMimeType(urlOrPath: string): { mime: string; assetType: Ass
|
|
86
86
|
* @returns {string} The corresponding font MIME type or a default.
|
87
87
|
*/
|
88
88
|
export function getFontMimeType(fontUrl: string): string {
|
89
|
-
|
90
|
-
}
|
89
|
+
return guessMimeType(fontUrl).mime; // Delegate to the main function
|
90
|
+
}
|