portapack 0.3.1 → 0.3.3

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.
Files changed (74) hide show
  1. package/.eslintrc.json +67 -8
  2. package/.releaserc.js +25 -27
  3. package/CHANGELOG.md +14 -22
  4. package/LICENSE.md +21 -0
  5. package/README.md +22 -53
  6. package/commitlint.config.js +30 -34
  7. package/dist/cli/cli-entry.cjs +183 -98
  8. package/dist/cli/cli-entry.cjs.map +1 -1
  9. package/dist/index.d.ts +0 -3
  10. package/dist/index.js +178 -97
  11. package/dist/index.js.map +1 -1
  12. package/docs/.vitepress/config.ts +38 -33
  13. package/docs/.vitepress/sidebar-generator.ts +89 -38
  14. package/docs/architecture.md +186 -0
  15. package/docs/cli.md +23 -23
  16. package/docs/code-of-conduct.md +7 -1
  17. package/docs/configuration.md +12 -11
  18. package/docs/contributing.md +6 -2
  19. package/docs/deployment.md +10 -5
  20. package/docs/development.md +8 -5
  21. package/docs/getting-started.md +13 -13
  22. package/docs/index.md +1 -1
  23. package/docs/public/android-chrome-192x192.png +0 -0
  24. package/docs/public/android-chrome-512x512.png +0 -0
  25. package/docs/public/apple-touch-icon.png +0 -0
  26. package/docs/public/favicon-16x16.png +0 -0
  27. package/docs/public/favicon-32x32.png +0 -0
  28. package/docs/public/favicon.ico +0 -0
  29. package/docs/roadmap.md +233 -0
  30. package/docs/site.webmanifest +1 -0
  31. package/docs/troubleshooting.md +12 -1
  32. package/examples/main.ts +5 -30
  33. package/examples/sample-project/script.js +1 -1
  34. package/jest.config.ts +8 -13
  35. package/nodemon.json +5 -10
  36. package/package.json +2 -5
  37. package/src/cli/cli-entry.ts +2 -2
  38. package/src/cli/cli.ts +21 -16
  39. package/src/cli/options.ts +127 -113
  40. package/src/core/bundler.ts +253 -222
  41. package/src/core/extractor.ts +632 -565
  42. package/src/core/minifier.ts +173 -162
  43. package/src/core/packer.ts +141 -137
  44. package/src/core/parser.ts +74 -73
  45. package/src/core/web-fetcher.ts +270 -258
  46. package/src/index.ts +18 -17
  47. package/src/types.ts +9 -11
  48. package/src/utils/font.ts +12 -6
  49. package/src/utils/logger.ts +110 -105
  50. package/src/utils/meta.ts +75 -76
  51. package/src/utils/mime.ts +50 -50
  52. package/src/utils/slugify.ts +33 -34
  53. package/tests/unit/cli/cli-entry.test.ts +72 -70
  54. package/tests/unit/cli/cli.test.ts +314 -278
  55. package/tests/unit/cli/options.test.ts +294 -301
  56. package/tests/unit/core/bundler.test.ts +426 -329
  57. package/tests/unit/core/extractor.test.ts +793 -549
  58. package/tests/unit/core/minifier.test.ts +374 -274
  59. package/tests/unit/core/packer.test.ts +298 -264
  60. package/tests/unit/core/parser.test.ts +538 -150
  61. package/tests/unit/core/web-fetcher.test.ts +389 -359
  62. package/tests/unit/index.test.ts +238 -197
  63. package/tests/unit/utils/font.test.ts +26 -21
  64. package/tests/unit/utils/logger.test.ts +267 -260
  65. package/tests/unit/utils/meta.test.ts +29 -28
  66. package/tests/unit/utils/mime.test.ts +73 -74
  67. package/tests/unit/utils/slugify.test.ts +14 -12
  68. package/tsconfig.build.json +9 -10
  69. package/tsconfig.jest.json +1 -1
  70. package/tsconfig.json +2 -2
  71. package/tsup.config.ts +8 -9
  72. package/typedoc.json +5 -9
  73. /package/docs/{portapack-transparent.png → public/portapack-transparent.png} +0 -0
  74. /package/docs/{portapack.jpg → public/portapack.jpg} +0 -0
@@ -1,5 +1,5 @@
1
- import { defineConfig } from 'vitepress'
2
- import { buildDocsSidebar } from './sidebar-generator'
1
+ import { defineConfig } from 'vitepress';
2
+ import { buildDocsSidebar } from './sidebar-generator';
3
3
 
4
4
  export default defineConfig({
5
5
  base: '/portapack/',
@@ -7,48 +7,53 @@ export default defineConfig({
7
7
  description: 'Bundle & Minify HTML into a Single Portable File',
8
8
  appearance: 'dark',
9
9
  lastUpdated: true,
10
-
10
+
11
11
  head: [
12
- ['link', { rel: 'icon', href: '/favicon.png' }],
12
+ ['link', { rel: 'icon', href: '/portapack/favicon.ico' }],
13
13
  ['meta', { name: 'og:title', content: 'PortaPack' }],
14
- ['meta', { name: 'og:description', content: 'Bundle & Minify HTML into a Single Portable File' }],
15
- ['meta', { name: 'og:image', content: '/og-image.png' }],
16
- ['meta', { name: 'twitter:card', content: 'summary_large_image' }]
14
+ [
15
+ 'meta',
16
+ { name: 'og:description', content: 'Bundle & Minify HTML into a Single Portable File' },
17
+ ],
18
+ ['meta', { name: 'og:image', content: '/portapack/portapack.jpg' }], // Updated to use your non-transparent logo
19
+ ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
17
20
  ],
18
21
 
19
22
  themeConfig: {
20
- logo: '/logo.png',
21
-
23
+ logo: '/portapack-transparent.png', // This path is relative to the public directory
24
+
22
25
  socialLinks: [
23
26
  { icon: 'github', link: 'https://github.com/manicinc/portapack' },
24
27
  { icon: 'twitter', link: 'https://x.com/manicagency' },
25
28
  { icon: 'discord', link: 'https://discord.gg/DzNgXdYm' },
26
- {
29
+ {
27
30
  icon: {
28
- svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>'
29
- },
30
- link: 'https://www.linkedin.com/company/manic-agency-llc/'
31
- }
31
+ svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>',
32
+ },
33
+ link: 'https://www.linkedin.com/company/manic-agency-llc/',
34
+ },
32
35
  ],
33
36
 
34
37
  footer: {
35
38
  message: 'Released under the MIT License',
36
- copyright: '© 2025 Manic Agency. All rights reserved.'
39
+ copyright: '© 2025 Manic Agency. All rights reserved.',
37
40
  },
38
41
 
39
42
  nav: [
40
43
  { text: 'Home', link: '/' },
41
44
  { text: 'Getting Started', link: '/getting-started' },
42
- {
43
- text: 'Docs',
45
+ {
46
+ text: 'Docs',
44
47
  items: [
45
48
  { text: 'CLI Reference', link: '/cli' },
46
49
  { text: 'API', link: '/api/README' },
47
50
  { text: 'Configuration', link: '/configuration' },
48
- { text: 'Advanced Usage', link: '/advanced' }
49
- ]
51
+ { text: 'Advanced Usage', link: '/advanced' },
52
+ ],
50
53
  },
51
- { text: 'Contributing', link: '/contributing' }
54
+ { text: 'Contributing', link: '/contributing' },
55
+ { text: 'Architecture', link: '/architecture'},
56
+ { text: 'Roadmap', link: 'roadmap'}
52
57
  ],
53
58
 
54
59
  sidebar: {
@@ -59,9 +64,9 @@ export default defineConfig({
59
64
  items: [
60
65
  { text: 'Introduction', link: '/getting-started/' },
61
66
  { text: 'Installation', link: '/getting-started/installation' },
62
- { text: 'Quick Start', link: '/getting-started/quick-start' }
63
- ]
64
- }
67
+ { text: 'Quick Start', link: '/getting-started/quick-start' },
68
+ ],
69
+ },
65
70
  ],
66
71
  '/cli/': [
67
72
  {
@@ -69,9 +74,9 @@ export default defineConfig({
69
74
  items: [
70
75
  { text: 'Overview', link: '/cli/' },
71
76
  { text: 'Commands', link: '/cli/commands' },
72
- { text: 'Options', link: '/cli/options' }
73
- ]
74
- }
77
+ { text: 'Options', link: '/cli/options' },
78
+ ],
79
+ },
75
80
  ],
76
81
  '/configuration/': [
77
82
  {
@@ -79,10 +84,10 @@ export default defineConfig({
79
84
  items: [
80
85
  { text: 'Overview', link: '/configuration/' },
81
86
  { text: 'Options', link: '/configuration/options' },
82
- { text: 'Advanced', link: '/configuration/advanced' }
83
- ]
84
- }
85
- ]
86
- }
87
- }
88
- })
87
+ { text: 'Advanced', link: '/configuration/advanced' },
88
+ ],
89
+ },
90
+ ],
91
+ },
92
+ },
93
+ });
@@ -1,5 +1,6 @@
1
- import { glob } from 'glob'
2
- import path from 'path'
1
+ import { glob } from 'glob';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url'; // Needed for ESM __dirname equivalent
3
4
 
4
5
  /**
5
6
  * Sidebar item interface for VitePress configuration
@@ -11,63 +12,113 @@ export interface SidebarItem {
11
12
  collapsed?: boolean;
12
13
  }
13
14
 
15
+ // --- Helper to get the directory name in ES Modules ---
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = path.dirname(__filename);
18
+ // --- Assuming sidebar-generator.ts is directly inside 'docs' ---
19
+ // If it's deeper, adjust accordingly (e.g., path.resolve(__dirname, '..'))
20
+ const docsDir = __dirname;
21
+ const apiDir = path.join(docsDir, 'api'); // Absolute path to the api directory
22
+
14
23
  /**
15
24
  * Automatically builds sidebar from generated TypeDoc files
16
25
  * @returns Dynamically generated sidebar configuration
17
26
  */
18
27
  export function buildDocsSidebar(): SidebarItem[] {
19
28
  try {
29
+ // Log the directory being scanned
30
+ console.log(`Scanning for markdown files in: ${apiDir}`);
31
+
20
32
  // Get all markdown files from the API docs directory using absolute path
21
- const apiFiles = glob.sync('docs/api/**/*.md', { absolute: true })
22
-
33
+ // Use path.join for cross-platform compatibility
34
+ const apiFiles = glob.sync(path.join(apiDir, '**/*.md').replace(/\\/g, '/'), {
35
+ absolute: true,
36
+ }); // Use forward slashes for glob
37
+
38
+ // Log found files for debugging
39
+ console.log(`Found ${apiFiles.length} API files:`, apiFiles);
40
+
23
41
  // Build sidebar structure
24
- const apiSidebar: SidebarItem[] = []
25
-
42
+ const apiSidebar: SidebarItem[] = [];
43
+
26
44
  // Define documentation sections to process
27
45
  const sections = [
28
46
  { name: 'Modules', path: 'modules' },
29
47
  { name: 'Classes', path: 'classes' },
30
48
  { name: 'Interfaces', path: 'interfaces' },
31
49
  { name: 'Functions', path: 'functions' },
32
- { name: 'Types', path: 'types' }
33
- ]
50
+ { name: 'Types', path: 'types' },
51
+ // Add other sections if needed
52
+ ];
34
53
 
35
54
  // Process each section
36
55
  sections.forEach(({ name, path: sectionPath }) => {
37
- const sectionFiles = apiFiles.filter(file => {
38
- const relativePath = path.relative('docs', file)
39
- return relativePath.includes(`/api/${sectionPath}/`) && !relativePath.endsWith('index.md')
40
- }).map(file => {
41
- const relativePath = path.relative('docs', file)
42
- const basename = path.basename(file, '.md')
43
- return {
44
- text: basename.replace(/^_/, '').replace(/-/g, ' '),
45
- link: '/' + relativePath.replace(/\.md$/, '')
46
- }
47
- })
48
-
56
+ // Filter files based on the absolute path to the section directory
57
+ const sectionDir = path.join(apiDir, sectionPath);
58
+ const sectionFiles = apiFiles
59
+ .filter(file => {
60
+ // Check if the file is within the current section's directory
61
+ // and is not an index file directly within that section directory
62
+ const fileDirPath = path.dirname(file);
63
+ return (
64
+ file.startsWith(sectionDir) && fileDirPath !== sectionDir && !file.endsWith('index.md')
65
+ );
66
+ // Alternative, simpler check if structure is flat within sections:
67
+ // return file.startsWith(path.join(apiDir, sectionPath, '/')) && !file.endsWith('index.md');
68
+ })
69
+ .map(file => {
70
+ // Calculate path relative to the 'docs' directory for the link
71
+ const relativePath = path.relative(docsDir, file);
72
+ const basename = path.basename(file, '.md');
73
+ const link = '/' + relativePath.replace(/\\/g, '/').replace(/\.md$/, ''); // Ensure forward slashes for URL
74
+
75
+ console.log(`Processing file: ${file}, Relative Path: ${relativePath}, Link: ${link}`); // Debug log
76
+
77
+ return {
78
+ text: basename.replace(/^_/, '').replace(/-/g, ' '), // Basic cleanup
79
+ link: link,
80
+ };
81
+ })
82
+ .sort((a, b) => a.text.localeCompare(b.text)); // Sort items alphabetically
83
+
49
84
  if (sectionFiles.length > 0) {
50
85
  apiSidebar.push({
51
86
  text: name,
52
- collapsed: false,
53
- items: sectionFiles
54
- })
87
+ collapsed: false, // Or true if you prefer them collapsed
88
+ items: sectionFiles,
89
+ });
55
90
  }
56
- })
57
-
58
- // Add main API index as first item
59
- apiSidebar.unshift({
60
- text: 'API Reference',
61
- link: '/api/'
62
- })
63
-
64
- return apiSidebar
91
+ });
92
+
93
+ // Add main API index if it exists (relative to docsDir)
94
+ const mainApiIndex = path.join(apiDir, 'index.md'); // Or maybe README.md? Check your TypeDoc output
95
+ // Check if the main index file exists using glob result or fs.existsSync
96
+ const mainApiIndexExists = apiFiles.some(file => file === mainApiIndex);
97
+
98
+ if (mainApiIndexExists) {
99
+ apiSidebar.unshift({
100
+ text: 'API Overview', // Or 'API Reference'
101
+ link: '/api/', // Link to the root index file of the API section
102
+ });
103
+ } else {
104
+ // Maybe add a placeholder or log a warning if the main index is missing
105
+ console.warn(
106
+ 'Main API index file (e.g., docs/api/index.md or docs/api/README.md) not found.'
107
+ );
108
+ }
109
+
110
+ // Log the final generated sidebar
111
+ console.log('Generated API Sidebar:', JSON.stringify(apiSidebar, null, 2));
112
+
113
+ return apiSidebar;
65
114
  } catch (error) {
66
- console.error('Error building docs sidebar:', error)
115
+ console.error('Error building docs sidebar:', error);
67
116
  // Return basic sidebar if there's an error
68
- return [{
69
- text: 'API Reference',
70
- link: '/api/'
71
- }]
117
+ return [
118
+ {
119
+ text: 'API Reference (Error)',
120
+ link: '/api/',
121
+ },
122
+ ];
72
123
  }
73
- }
124
+ }
@@ -0,0 +1,186 @@
1
+ # PortaPack Architecture
2
+
3
+ ## Overview
4
+
5
+ PortaPack is a sophisticated tool that bundles entire websites—HTML, CSS, JavaScript, images, and fonts—into self-contained HTML files for offline access. This document outlines the architectural components that make up the system.
6
+
7
+ ```mermaid
8
+ graph TD
9
+ CLI[CLI Entry Point] --> Options[Options Parser]
10
+ Options --> Core
11
+ API[API Entry Point] --> Core
12
+
13
+ subgraph Core ["Core Pipeline"]
14
+ Parser[HTML Parser] --> Extractor[Asset Extractor]
15
+ Extractor --> Minifier[Asset Minifier]
16
+ Minifier --> Packer[HTML Packer]
17
+ end
18
+
19
+ subgraph Recursive ["Advanced Features"]
20
+ WebFetcher[Web Fetcher] --> MultipageBundler[Multipage Bundler]
21
+ end
22
+
23
+ WebFetcher --> Parser
24
+ Core --> Output[Bundled HTML]
25
+ MultipageBundler --> Output
26
+
27
+ subgraph Utilities ["Utilities"]
28
+ Logger[Logger]
29
+ MimeUtils[MIME Utilities]
30
+ BuildTimer[Build Timer]
31
+ Slugify[URL Slugifier]
32
+ end
33
+
34
+ Logger -.-> CLI
35
+ Logger -.-> Core
36
+ Logger -.-> Recursive
37
+ MimeUtils -.-> Extractor
38
+ MimeUtils -.-> Parser
39
+ BuildTimer -.-> CLI
40
+ BuildTimer -.-> API
41
+ Slugify -.-> MultipageBundler
42
+ ```
43
+
44
+ ## Entry Points
45
+
46
+ ### CLI Interface
47
+
48
+ The command-line interface provides a convenient way to use PortaPack through terminal commands:
49
+
50
+ | Component | Purpose |
51
+ |-----------|---------|
52
+ | `cli-entry.ts` | Executable entry point with shebang support |
53
+ | `cli.ts` | Main runner that processes args and manages execution |
54
+ | `options.ts` | Parses command-line arguments and normalizes options |
55
+
56
+ ### API Interface
57
+
58
+ The programmatic API enables developers to integrate PortaPack into their applications:
59
+
60
+ | Component | Purpose |
61
+ |-----------|---------|
62
+ | `index.ts` | Exports public functions like `pack()` with TypeScript types |
63
+ | `types.ts` | Defines shared interfaces and types for the entire system |
64
+
65
+ ## Core Pipeline
66
+
67
+ The bundling process follows a clear four-stage pipeline:
68
+
69
+ ### 1. HTML Parser (`parser.ts`)
70
+
71
+ The parser reads and analyzes the input HTML:
72
+ - Uses Cheerio for robust HTML parsing
73
+ - Identifies linked assets through element attributes (href, src, etc.)
74
+ - Creates an initial asset list with URLs and inferred types
75
+ - Handles both local file paths and remote URLs
76
+
77
+ ### 2. Asset Extractor (`extractor.ts`)
78
+
79
+ The extractor resolves and fetches all referenced assets:
80
+ - Resolves relative URLs against the base context
81
+ - Fetches content for all discovered assets
82
+ - Recursively extracts nested assets from CSS (@import, url())
83
+ - Handles protocol-relative URLs and different origins
84
+ - Provides detailed logging of asset discovery
85
+
86
+ ### 3. Asset Minifier (`minifier.ts`)
87
+
88
+ The minifier reduces the size of all content:
89
+ - Minifies HTML using html-minifier-terser
90
+ - Minifies CSS using clean-css
91
+ - Minifies JavaScript using terser
92
+ - Preserves original content if minification fails
93
+ - Configurable through command-line flags
94
+
95
+ ### 4. HTML Packer (`packer.ts`)
96
+
97
+ The packer combines everything into a single file:
98
+ - Inlines CSS into `<style>` tags
99
+ - Embeds JavaScript into `<script>` tags
100
+ - Converts binary assets to data URIs
101
+ - Handles srcset attributes properly
102
+ - Ensures proper HTML structure with base tag
103
+
104
+ ## Advanced Features
105
+
106
+ ### Web Fetcher (`web-fetcher.ts`)
107
+
108
+ For remote content, the web fetcher provides crawling capabilities:
109
+ - Uses Puppeteer for fully-rendered page capture
110
+ - Crawls websites recursively to specified depth
111
+ - Respects same-origin policy by default
112
+ - Manages browser instances efficiently
113
+ - Provides detailed logging of the crawl process
114
+
115
+ ### Multipage Bundler (`bundler.ts`)
116
+
117
+ For bundling multiple pages into a single file:
118
+ - Combines multiple HTML documents into one
119
+ - Creates a client-side router for navigation
120
+ - Generates a navigation interface
121
+ - Uses slugs for routing between pages
122
+ - Handles page templates and content swapping
123
+
124
+ ## Utilities
125
+
126
+ ### Logger (`logger.ts`)
127
+ - Customizable log levels (debug, info, warn, error)
128
+ - Consistent logging format across the codebase
129
+ - Optional timestamps and colored output
130
+
131
+ ### MIME Utilities (`mime.ts`)
132
+ - Maps file extensions to correct MIME types
133
+ - Categorizes assets by type (CSS, JS, image, font)
134
+ - Provides fallbacks for unknown extensions
135
+
136
+ ### Build Timer (`meta.ts`)
137
+ - Tracks build performance metrics
138
+ - Records asset counts and page counts
139
+ - Captures output size and build duration
140
+ - Collects errors and warnings for reporting
141
+
142
+ ### URL Slugifier (`slugify.ts`)
143
+ - Converts URLs to safe HTML IDs
144
+ - Handles special characters and normalization
145
+ - Prevents slug collisions in multipage bundles
146
+
147
+ ## Asynchronous Processing
148
+
149
+ PortaPack uses modern async patterns throughout:
150
+
151
+ - **Promise-based Pipeline**: Each stage returns promises that are awaited
152
+ - **Sequential Processing**: Assets are processed in order to avoid overwhelming resources
153
+ - **Error Boundaries**: Individual asset failures don't break the entire pipeline
154
+ - **Resource Management**: Browser instances and file handles are properly closed
155
+
156
+ ## Build System
157
+
158
+ PortaPack uses a dual build configuration:
159
+
160
+ | Build Target | Format | Purpose |
161
+ |--------------|--------|---------|
162
+ | CLI | CommonJS (.cjs) | Works with Node.js and npx |
163
+ | API | ESModule (.js) | Modern import/export support |
164
+
165
+ TypeScript declarations (.d.ts) are generated for API consumers, and source maps support debugging.
166
+
167
+ ## Current Limitations
168
+
169
+ ### Script Execution Issues
170
+
171
+ - Inlined scripts with `async`/`defer` attributes lose their intended loading behavior
172
+ - ES Modules with import/export statements may fail after bundling
173
+ - Script execution order can change, breaking dependencies
174
+
175
+ ### Content Limitations
176
+
177
+ - CORS policies may prevent access to some cross-origin resources
178
+ - Only initially rendered content from SPAs is captured by default
179
+ - Very large sites produce impractically large HTML files
180
+
181
+ ### Technical Constraints
182
+
183
+ - No streaming API or WebSocket support
184
+ - Service worker capabilities are not preserved
185
+ - Memory pressure with large sites
186
+ - Limited support for authenticated content
package/docs/cli.md CHANGED
@@ -26,25 +26,25 @@ Where `[input]` is the path to a local HTML file or a remote URL.
26
26
 
27
27
  ## Options
28
28
 
29
- | Option | Shorthand | Description | Default |
30
- |--------|-----------|-------------|---------|
31
- | `[input]` | | Required. Input local file path or remote URL (http/https) to process. | - |
32
- | `--output <file>` | `-o` | Output file path for the bundled HTML. | `{input-basename}.packed.html` |
33
- | `--recursive [depth]` | `-r` | Recursively bundle links up to depth. If depth omitted, defaults to true (no limit). Only applies to remote URLs. | `false` (disabled) |
34
- | `--max-depth <n>` | | Set maximum depth for recursive crawling (alternative to `-r <n>`). | - |
35
- | `--minify` | `-m` | Enable all minification (HTML, CSS, JS). | - |
36
- | `--no-minify` | | Disable all asset minification (HTML, CSS, JS). | `false` |
37
- | `--no-minify-html` | | Disable only HTML minification. | `false` |
38
- | `--no-minify-css` | | Disable only CSS minification. | `false` |
39
- | `--no-minify-js` | | Disable only JavaScript minification. | `false` |
40
- | `--embed-assets` | `-e` | Embed external assets (CSS, JS, images, fonts) as data URIs or inline content. | `true` |
41
- | `--no-embed-assets` | | Keep external assets as links (requires network access when viewing). | `false` |
42
- | `--base-url <url>` | `-b` | Base URL for resolving relative URLs found in the input HTML. | Input path/URL |
43
- | `--log-level <level>` | | Set logging level (debug, info, warn, error, silent, none). | `info` |
44
- | `--verbose` | `-v` | Enable verbose logging (shortcut for `--log-level debug`). | `false` |
45
- | `--dry-run` | `-d` | Perform all steps except writing the output file. Logs intended actions. | `false` |
46
- | `--help` | `-h` | Show help information and exit. | - |
47
- | `--version` | | Show PortaPack CLI version number and exit. | - |
29
+ | Option | Shorthand | Description | Default |
30
+ | --------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------ |
31
+ | `[input]` | | Required. Input local file path or remote URL (http/https) to process. | - |
32
+ | `--output <file>` | `-o` | Output file path for the bundled HTML. | `{input-basename}.packed.html` |
33
+ | `--recursive [depth]` | `-r` | Recursively bundle links up to depth. If depth omitted, defaults to true (no limit). Only applies to remote URLs. | `false` (disabled) |
34
+ | `--max-depth <n>` | | Set maximum depth for recursive crawling (alternative to `-r <n>`). | - |
35
+ | `--minify` | `-m` | Enable all minification (HTML, CSS, JS). | - |
36
+ | `--no-minify` | | Disable all asset minification (HTML, CSS, JS). | `false` |
37
+ | `--no-minify-html` | | Disable only HTML minification. | `false` |
38
+ | `--no-minify-css` | | Disable only CSS minification. | `false` |
39
+ | `--no-minify-js` | | Disable only JavaScript minification. | `false` |
40
+ | `--embed-assets` | `-e` | Embed external assets (CSS, JS, images, fonts) as data URIs or inline content. | `true` |
41
+ | `--no-embed-assets` | | Keep external assets as links (requires network access when viewing). | `false` |
42
+ | `--base-url <url>` | `-b` | Base URL for resolving relative URLs found in the input HTML. | Input path/URL |
43
+ | `--log-level <level>` | | Set logging level (debug, info, warn, error, silent, none). | `info` |
44
+ | `--verbose` | `-v` | Enable verbose logging (shortcut for `--log-level debug`). | `false` |
45
+ | `--dry-run` | `-d` | Perform all steps except writing the output file. Logs intended actions. | `false` |
46
+ | `--help` | `-h` | Show help information and exit. | - |
47
+ | `--version` | | Show PortaPack CLI version number and exit. | - |
48
48
 
49
49
  ## Examples
50
50
 
@@ -169,12 +169,12 @@ npx portapack ./index.html -o bundle.html
169
169
  ## Exit Codes
170
170
 
171
171
  | Code | Description |
172
- |------|-------------|
173
- | 0 | Success |
174
- | 1 | Error |
172
+ | ---- | ----------- |
173
+ | 0 | Success |
174
+ | 1 | Error |
175
175
 
176
176
  ## Related Resources
177
177
 
178
178
  - [Getting Started](https://manicinc.github.io/portapack/getting-started)
179
179
  - [API Reference](https://manicinc.github.io/portapack/api/)
180
- - [Configuration Guide](https://manicinc.github.io/portapack/configuration)
180
+ - [Configuration Guide](https://manicinc.github.io/portapack/configuration)
@@ -3,6 +3,7 @@
3
3
  ## Our Pledge
4
4
 
5
5
  We are committed to providing a friendly, safe, and welcoming environment for all contributors, regardless of:
6
+
6
7
  - Age
7
8
  - Body size
8
9
  - Disability
@@ -18,6 +19,7 @@ We are committed to providing a friendly, safe, and welcoming environment for al
18
19
  ## Our Standards
19
20
 
20
21
  ### Positive Behavior
22
+
21
23
  - Using welcoming and inclusive language
22
24
  - Being respectful of differing viewpoints
23
25
  - Gracefully accepting constructive criticism
@@ -25,6 +27,7 @@ We are committed to providing a friendly, safe, and welcoming environment for al
25
27
  - Showing empathy towards other community members
26
28
 
27
29
  ### Unacceptable Behavior
30
+
28
31
  - Trolling, insulting/derogatory comments
29
32
  - Public or private harassment
30
33
  - Publishing others' private information
@@ -33,6 +36,7 @@ We are committed to providing a friendly, safe, and welcoming environment for al
33
36
  ## Enforcement Responsibilities
34
37
 
35
38
  Community leaders are responsible for:
39
+
36
40
  - Clarifying acceptable behavior standards
37
41
  - Providing fair and consistent feedback
38
42
  - Removing, editing, or rejecting contributions that violate this Code of Conduct
@@ -40,6 +44,7 @@ Community leaders are responsible for:
40
44
  ## Reporting Issues
41
45
 
42
46
  If you experience or witness unacceptable behavior:
47
+
43
48
  1. Email [conduct@manicinc.com](mailto:conduct@manicinc.com)
44
49
  2. Provide:
45
50
  - Your contact information
@@ -50,6 +55,7 @@ If you experience or witness unacceptable behavior:
50
55
  ## Consequences
51
56
 
52
57
  Violations may result in:
58
+
53
59
  - Temporary or permanent ban from community spaces
54
60
  - Removal of contributions
55
61
  - Public or private warnings
@@ -62,4 +68,4 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], versi
62
68
 
63
69
  ## License
64
70
 
65
- This Code of Conduct is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).
71
+ This Code of Conduct is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).
@@ -36,7 +36,7 @@ import { pack } from 'portapack';
36
36
  async function bundleLocalSite() {
37
37
  const result = await pack('./index.html');
38
38
  console.log(result.html);
39
-
39
+
40
40
  // Access metadata about the build
41
41
  console.log(`Output size: ${result.metadata.outputSize} bytes`);
42
42
  console.log(`Build time: ${result.metadata.buildTimeMs} ms`);
@@ -49,9 +49,9 @@ async function bundleWithOptions() {
49
49
  minifyCss: true,
50
50
  minifyJs: true,
51
51
  baseUrl: 'https://example.com',
52
- embedAssets: true
52
+ embedAssets: true,
53
53
  });
54
-
54
+
55
55
  // Use or save the bundled HTML
56
56
  console.log(result.html);
57
57
  }
@@ -59,12 +59,12 @@ async function bundleWithOptions() {
59
59
  // Recursive bundling of a website
60
60
  async function bundleWebsite() {
61
61
  const result = await pack('https://example.com', {
62
- recursive: 2, // Crawl up to 2 levels deep
62
+ recursive: 2, // Crawl up to 2 levels deep
63
63
  minifyHtml: true,
64
64
  minifyCss: true,
65
- minifyJs: true
65
+ minifyJs: true,
66
66
  });
67
-
67
+
68
68
  console.log(`Bundled ${result.metadata.pagesBundled} pages`);
69
69
  }
70
70
  ```
@@ -83,18 +83,18 @@ import {
83
83
 
84
84
  // Bundle a single HTML file or URL
85
85
  const singleResult = await generatePortableHTML('./index.html', {
86
- minifyHtml: true
86
+ minifyHtml: true,
87
87
  });
88
88
 
89
89
  // Recursively bundle a site
90
90
  const recursiveResult = await generateRecursivePortableHTML('https://example.com', 2, {
91
- minifyCss: true
91
+ minifyCss: true,
92
92
  });
93
93
 
94
94
  // Create multi-page bundle
95
95
  const multiPageBundle = await bundleMultiPageHTML([
96
96
  { path: '/', html: '<html>...</html>' },
97
- { path: '/about', html: '<html>...</html>' }
97
+ { path: '/about', html: '<html>...</html>' },
98
98
  ]);
99
99
  ```
100
100
 
@@ -117,7 +117,7 @@ For details, see the [CLI Reference](https://manicinc.github.io/portapack/cli).
117
117
 
118
118
  - 📖 [Explore CLI Options](https://manicinc.github.io/portapack/cli)
119
119
  - 🛠 [Advanced Configuration](https://manicinc.github.io/portapack/configuration)
120
- - 💻 [API Reference](https://manicinc.github.io/portapack/api/)
120
+ - 💻 [API Reference](https://manicinc.github.io/portapack/api/README.html)
121
121
 
122
122
  ## Troubleshooting
123
123
 
@@ -126,6 +126,7 @@ Encountering issues? Check our [Troubleshooting Guide](https://manicinc.github.i
126
126
  ## Contributing
127
127
 
128
128
  Interested in improving PortaPack?
129
+
129
130
  - [View Contributing Guidelines](https://manicinc.github.io/portapack/contributing)
130
131
 
131
132
  ## Support
@@ -133,4 +134,4 @@ Interested in improving PortaPack?
133
134
  - 🐛 [Report an Issue](https://github.com/manicinc/portapack/issues)
134
135
  - 💬 [Community Support](https://discord.gg/DzNgXdYm)
135
136
 
136
- Built by [Manic.agency](https://manic.agency)
137
+ Built by [Manic.agency](https://manic.agency)