portapack 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +83 -216
- package/dist/cli/{cli-entry.js → cli-entry.cjs} +626 -498
- package/dist/cli/cli-entry.cjs.map +1 -0
- package/dist/index.d.ts +51 -56
- package/dist/index.js +523 -443
- package/dist/index.js.map +1 -1
- package/docs/cli.md +158 -42
- package/jest.config.ts +18 -8
- package/jest.setup.cjs +66 -146
- package/package.json +5 -5
- package/src/cli/cli-entry.ts +15 -15
- package/src/cli/cli.ts +130 -119
- package/src/core/bundler.ts +174 -63
- package/src/core/extractor.ts +243 -203
- package/src/core/web-fetcher.ts +205 -141
- package/src/index.ts +161 -224
- package/tests/unit/cli/cli-entry.test.ts +66 -77
- package/tests/unit/cli/cli.test.ts +243 -145
- package/tests/unit/core/bundler.test.ts +334 -258
- package/tests/unit/core/extractor.test.ts +391 -1051
- package/tests/unit/core/minifier.test.ts +130 -221
- package/tests/unit/core/packer.test.ts +255 -106
- package/tests/unit/core/parser.test.ts +89 -458
- package/tests/unit/core/web-fetcher.test.ts +330 -285
- package/tests/unit/index.test.ts +206 -300
- package/tests/unit/utils/logger.test.ts +32 -28
- package/tsconfig.jest.json +7 -7
- package/tsup.config.ts +34 -29
- package/dist/cli/cli-entry.js.map +0 -1
- package/output.html +0 -1
- package/site-packed.html +0 -1
- package/test-output.html +0 -0
@@ -51,28 +51,29 @@ describe('Logger', () => {
|
|
51
51
|
it('creates a logger with default log level INFO', () => {
|
52
52
|
const logger = new Logger();
|
53
53
|
expect(logger).toBeDefined();
|
54
|
-
// @ts-expect-error Access private member for testing
|
55
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
54
|
+
// REMOVED: @ts-expect-error Access private member for testing (No longer needed)
|
55
|
+
expect((logger as any).level).toBe(LogLevel.INFO); // Cast to any if 'level' is truly private and inaccessible
|
56
|
+
// Or make 'level' public/internal for testing if appropriate
|
56
57
|
});
|
57
58
|
|
58
59
|
it('creates a logger with specific log level', () => {
|
59
60
|
const logger = new Logger(LogLevel.DEBUG);
|
60
61
|
expect(logger).toBeDefined();
|
61
|
-
// @ts-expect-error Access private member for testing
|
62
|
-
expect(logger.level).toBe(LogLevel.DEBUG);
|
62
|
+
// REMOVED: @ts-expect-error Access private member for testing (No longer needed)
|
63
|
+
expect((logger as any).level).toBe(LogLevel.DEBUG);
|
63
64
|
});
|
64
65
|
|
65
66
|
// Test constructor guards against invalid levels
|
66
67
|
it('defaults to INFO if constructor receives invalid level', () => {
|
67
|
-
// @ts-expect-error Testing invalid input
|
68
|
+
// @ts-expect-error Testing invalid input (KEEP this one if Logger constructor expects LogLevel)
|
68
69
|
const logger = new Logger(99);
|
69
|
-
// @ts-expect-error Access private member for testing
|
70
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
70
|
+
// REMOVED: @ts-expect-error Access private member for testing (No longer needed)
|
71
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
71
72
|
});
|
72
73
|
it('defaults to INFO if constructor receives undefined', () => {
|
73
74
|
const logger = new Logger(undefined);
|
74
|
-
// @ts-expect-error Access private member for testing
|
75
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
75
|
+
// REMOVED: @ts-expect-error Access private member for testing (No longer needed)
|
76
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
76
77
|
});
|
77
78
|
});
|
78
79
|
|
@@ -106,6 +107,7 @@ describe('Logger', () => {
|
|
106
107
|
expect(mockError).toHaveBeenCalledTimes(1);
|
107
108
|
|
108
109
|
mockWarn.mockClear();
|
110
|
+
mockError.mockClear(); // Clear mockError too for the next check
|
109
111
|
loggerError.warn('Test warn error level'); // Should not log
|
110
112
|
expect(mockWarn).not.toHaveBeenCalled();
|
111
113
|
});
|
@@ -121,6 +123,7 @@ describe('Logger', () => {
|
|
121
123
|
expect(mockWarn).toHaveBeenCalledTimes(1);
|
122
124
|
|
123
125
|
mockInfo.mockClear();
|
126
|
+
mockWarn.mockClear(); // Clear mockWarn too
|
124
127
|
loggerWarn.info('Test info warn level'); // Should not log
|
125
128
|
expect(mockInfo).not.toHaveBeenCalled();
|
126
129
|
});
|
@@ -136,6 +139,7 @@ describe('Logger', () => {
|
|
136
139
|
expect(mockInfo).toHaveBeenCalledTimes(1);
|
137
140
|
|
138
141
|
mockDebug.mockClear();
|
142
|
+
mockInfo.mockClear(); // Clear mockInfo too
|
139
143
|
loggerInfo.debug('Test debug info level'); // Should not log
|
140
144
|
expect(mockDebug).not.toHaveBeenCalled();
|
141
145
|
});
|
@@ -198,26 +202,26 @@ describe('Logger', () => {
|
|
198
202
|
describe('Logger.fromVerboseFlag()', () => {
|
199
203
|
it('creates logger with DEBUG level if verbose is true', () => {
|
200
204
|
const logger = Logger.fromVerboseFlag({ verbose: true });
|
201
|
-
// @ts-expect-error Access private member
|
202
|
-
expect(logger.level).toBe(LogLevel.DEBUG);
|
205
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
206
|
+
expect((logger as any).level).toBe(LogLevel.DEBUG);
|
203
207
|
});
|
204
208
|
|
205
209
|
it('creates logger with INFO level if verbose is false', () => {
|
206
210
|
const logger = Logger.fromVerboseFlag({ verbose: false });
|
207
|
-
// @ts-expect-error Access private member
|
208
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
211
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
212
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
209
213
|
});
|
210
214
|
|
211
215
|
it('creates logger with INFO level if verbose is undefined', () => {
|
212
216
|
const logger = Logger.fromVerboseFlag({}); // Empty options
|
213
|
-
// @ts-expect-error Access private member
|
214
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
217
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
218
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
215
219
|
});
|
216
220
|
|
217
221
|
it('creates logger with INFO level if options is undefined', () => {
|
218
222
|
const logger = Logger.fromVerboseFlag(); // No options arg
|
219
|
-
// @ts-expect-error Access private member
|
220
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
223
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
224
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
221
225
|
});
|
222
226
|
});
|
223
227
|
|
@@ -233,30 +237,30 @@ describe('Logger', () => {
|
|
233
237
|
['InFo', LogLevel.INFO],
|
234
238
|
])('creates logger with correct level for valid name "%s"', (name, expectedLevel) => {
|
235
239
|
const logger = Logger.fromLevelName(name);
|
236
|
-
// @ts-expect-error Access private member
|
237
|
-
expect(logger.level).toBe(expectedLevel);
|
240
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
241
|
+
expect((logger as any).level).toBe(expectedLevel);
|
238
242
|
expect(mockWarn).not.toHaveBeenCalled(); // No warning for valid names
|
239
243
|
});
|
240
244
|
|
241
245
|
it('defaults to INFO level if levelName is undefined', () => {
|
242
246
|
const logger = Logger.fromLevelName(undefined);
|
243
|
-
// @ts-expect-error Access private member
|
244
|
-
expect(logger.level).toBe(LogLevel.INFO);
|
247
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
248
|
+
expect((logger as any).level).toBe(LogLevel.INFO);
|
245
249
|
expect(mockWarn).not.toHaveBeenCalled();
|
246
250
|
});
|
247
251
|
|
248
252
|
it('uses provided defaultLevel if levelName is undefined', () => {
|
249
253
|
const logger = Logger.fromLevelName(undefined, LogLevel.WARN);
|
250
|
-
// @ts-expect-error Access private member
|
251
|
-
expect(logger.level).toBe(LogLevel.WARN);
|
254
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
255
|
+
expect((logger as any).level).toBe(LogLevel.WARN);
|
252
256
|
expect(mockWarn).not.toHaveBeenCalled();
|
253
257
|
});
|
254
258
|
|
255
259
|
|
256
260
|
it('defaults to INFO level and logs warning for invalid name', () => {
|
257
261
|
const logger = Logger.fromLevelName('invalidLevel');
|
258
|
-
// @ts-expect-error Access private member
|
259
|
-
expect(logger.level).toBe(LogLevel.INFO); // Falls back to default INFO
|
262
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
263
|
+
expect((logger as any).level).toBe(LogLevel.INFO); // Falls back to default INFO
|
260
264
|
// Check that console.warn was called *directly* by the static method
|
261
265
|
expect(mockWarn).toHaveBeenCalledTimes(1);
|
262
266
|
expect(mockWarn).toHaveBeenCalledWith(expect.stringContaining('[Logger] Invalid log level name "invalidLevel". Defaulting to INFO.'));
|
@@ -264,12 +268,12 @@ describe('Logger', () => {
|
|
264
268
|
|
265
269
|
it('uses provided defaultLevel and logs warning for invalid name', () => {
|
266
270
|
const logger = Logger.fromLevelName('invalidLevel', LogLevel.ERROR);
|
267
|
-
// @ts-expect-error Access private member
|
268
|
-
expect(logger.level).toBe(LogLevel.ERROR); // Falls back to provided default ERROR
|
271
|
+
// REMOVED: @ts-expect-error Access private member (No longer needed)
|
272
|
+
expect((logger as any).level).toBe(LogLevel.ERROR); // Falls back to provided default ERROR
|
269
273
|
// Check that console.warn was called *directly* by the static method
|
270
274
|
expect(mockWarn).toHaveBeenCalledTimes(1);
|
271
275
|
expect(mockWarn).toHaveBeenCalledWith(expect.stringContaining('[Logger] Invalid log level name "invalidLevel". Defaulting to ERROR.'));
|
272
276
|
});
|
273
277
|
});
|
274
278
|
});
|
275
|
-
});
|
279
|
+
});
|
package/tsconfig.jest.json
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
{
|
2
2
|
"extends": "./tsconfig.json",
|
3
3
|
"compilerOptions": {
|
4
|
-
"module": "
|
5
|
-
"moduleResolution": "
|
6
|
-
"isolatedModules":
|
4
|
+
"module": "CommonJS",
|
5
|
+
"moduleResolution": "Node", // Use classic Node resolution for CommonJS
|
6
|
+
"isolatedModules": false, // Often better to set false when using CommonJS/ts-jest
|
7
7
|
"esModuleInterop": true,
|
8
8
|
"allowSyntheticDefaultImports": true,
|
9
9
|
"sourceMap": true,
|
10
|
-
"noEmit": true,
|
11
|
-
//
|
12
|
-
"
|
13
|
-
"
|
10
|
+
"noEmit": true,
|
11
|
+
"target": "ES2022", // Keep target if your Node version supports it
|
12
|
+
"lib": ["es2022", "dom"],
|
13
|
+
"skipLibCheck": true // Add this if not present
|
14
14
|
},
|
15
15
|
"include": ["src/**/*", "tests/**/*"],
|
16
16
|
"exclude": ["node_modules", "dist"]
|
package/tsup.config.ts
CHANGED
@@ -1,71 +1,76 @@
|
|
1
1
|
/**
|
2
2
|
* @file tsup.config.ts
|
3
3
|
* @description
|
4
|
-
*
|
5
|
-
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
4
|
+
* Dual build configuration for PortaPack:
|
5
|
+
*
|
6
|
+
* 🔹 CLI Build:
|
7
|
+
* - CommonJS format (`cjs`) for CLI compatibility with Node/npx
|
8
|
+
* - .cjs file extension to avoid ESM interpretation issues
|
9
|
+
* - Shebang (`#!/usr/bin/env node`) for executability
|
10
|
+
* - No type declarations
|
11
|
+
*
|
12
|
+
* 🔹 API Build:
|
13
|
+
* - ESModule format (`esm`) for modern module usage
|
14
|
+
* - Generates type declarations (`.d.ts`)
|
15
|
+
* - Outputs to dist/ without interfering with CLI
|
11
16
|
*/
|
12
17
|
|
13
18
|
import { defineConfig } from 'tsup';
|
14
19
|
|
15
20
|
export default defineConfig([
|
21
|
+
// 🔹 CLI BUILD (CJS + .cjs + shebang)
|
16
22
|
{
|
17
|
-
// CLI build configuration
|
18
23
|
entry: {
|
19
|
-
'cli-entry': 'src/cli/cli-entry.ts',
|
24
|
+
'cli-entry': 'src/cli/cli-entry.ts',
|
20
25
|
},
|
21
|
-
|
22
|
-
|
26
|
+
outDir: 'dist/cli',
|
27
|
+
format: ['cjs'], // ✅ Required for CLI to work with npx
|
23
28
|
platform: 'node',
|
29
|
+
target: 'node18',
|
24
30
|
splitting: false,
|
25
|
-
clean: true,
|
26
|
-
dts: false,
|
31
|
+
clean: true, // Wipe dist/cli clean on each build
|
32
|
+
dts: false, // No types for CLI
|
27
33
|
sourcemap: true,
|
28
|
-
outDir: 'dist/cli',
|
29
34
|
banner: {
|
30
|
-
js: '#!/usr/bin/env node',
|
35
|
+
js: '#!/usr/bin/env node', // ✅ Required for CLI shebang
|
31
36
|
},
|
32
|
-
outExtension(
|
37
|
+
outExtension() {
|
33
38
|
return {
|
34
|
-
js: '.
|
39
|
+
js: '.cjs', // ✅ Required: prevents ESM misinterpretation
|
35
40
|
};
|
36
41
|
},
|
37
42
|
esbuildOptions(options) {
|
38
|
-
//
|
43
|
+
// Support import.meta in case CLI uses it
|
39
44
|
options.supported = {
|
40
45
|
...options.supported,
|
41
46
|
'import-meta': true,
|
42
47
|
};
|
43
48
|
},
|
44
49
|
},
|
50
|
+
|
51
|
+
// 🔹 API BUILD (ESM + Types + dist/)
|
45
52
|
{
|
46
|
-
// API build configuration
|
47
53
|
entry: {
|
48
54
|
index: 'src/index.ts',
|
49
55
|
},
|
50
|
-
|
51
|
-
|
56
|
+
outDir: 'dist',
|
57
|
+
format: ['esm'], // ✅ Modern ESM output for consumers
|
52
58
|
platform: 'node',
|
59
|
+
target: 'node18',
|
53
60
|
splitting: false,
|
54
|
-
clean: false,
|
55
|
-
dts: true,
|
61
|
+
clean: false, // Don't wipe CLI build!
|
62
|
+
dts: true, // ✅ Generate TypeScript declarations
|
56
63
|
sourcemap: true,
|
57
|
-
|
58
|
-
outExtension({ format }) {
|
64
|
+
outExtension() {
|
59
65
|
return {
|
60
|
-
js: '.js',
|
66
|
+
js: '.js',
|
61
67
|
};
|
62
68
|
},
|
63
69
|
esbuildOptions(options) {
|
64
|
-
// Make sure to preserve import.meta.url
|
65
70
|
options.supported = {
|
66
71
|
...options.supported,
|
67
72
|
'import-meta': true,
|
68
73
|
};
|
69
74
|
},
|
70
|
-
}
|
71
|
-
]);
|
75
|
+
},
|
76
|
+
]);
|