extension-from-store 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [npm-version-image]: https://img.shields.io/npm/v/extension-from-store.svg?color=0078D7
1
+ [npm-version-image]: https://img.shields.io/npm/v/extension-from-store.svg?color=0971fe
2
2
  [npm-version-url]: https://www.npmjs.com/package/extension-from-store
3
3
  [npm-downloads-image]: https://img.shields.io/npm/dm/extension-from-store.svg?color=2ecc40
4
4
  [npm-downloads-url]: https://www.npmjs.com/package/extension-from-store
@@ -151,6 +151,14 @@ Library logging is opt-in via the `logger` hooks. The library never writes direc
151
151
  - `6` filesystem conflict
152
152
  - `7` store incompatibility
153
153
 
154
+ ## Related projects
155
+
156
+ * [browser-extension-manifest-fields](https://github.com/cezaraugusto/browser-extension-manifest-fields)
157
+ * [browser-extension-capabilities](https://github.com/cezaraugusto/browser-extension-capabilities)
158
+ * [browser-extension-compat-data](https://github.com/cezaraugusto/browser-extension-compat-data)
159
+ * [chrome-extension-manifest-json-schema](https://github.com/cezaraugusto/chrome-extension-manifest-json-schema)
160
+ * [parse5-asset-patcher](https://github.com/cezaraugusto/parse5-asset-patcher)
161
+
154
162
  ## License
155
163
 
156
164
  MIT (c) Cezar Augusto.
package/bin.cjs CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
3
2
 
4
- const mod = require('./dist/index.cjs');
5
- const fetchExtensionFromStore = mod.fetchExtensionFromStore;
6
- const extensionFromStoreError = mod.extensionFromStoreError;
3
+ 'use strict'
4
+
5
+ const mod = require('./dist/index.cjs')
6
+
7
+ const {fetchExtensionFromStore} = mod
8
+ const {extensionFromStoreError} = mod
7
9
 
8
10
  const EXIT_CODES = {
9
11
  InvalidInput: 1,
@@ -13,12 +15,13 @@ const EXIT_CODES = {
13
15
  DownloadFailed: 4,
14
16
  ExtractionFailed: 5,
15
17
  FilesystemConflict: 6,
16
- StoreIncompatibility: 7,
17
- };
18
+ StoreIncompatibility: 7
19
+ }
20
+
21
+ function parseArgs (argv) {
22
+ const args = [...argv]
18
23
 
19
- function parseArgs(argv) {
20
- const args = [...argv];
21
- if (args[0] === 'fetch') args.shift();
24
+ if (args[0] === 'fetch') args.shift()
22
25
 
23
26
  const result = {
24
27
  url: '',
@@ -28,126 +31,130 @@ function parseArgs(argv) {
28
31
  extract: false,
29
32
  quiet: false,
30
33
  verbose: false,
31
- json: false,
32
- };
34
+ json: false
35
+ }
33
36
 
34
37
  for (let i = 0; i < args.length; i += 1) {
35
- const arg = args[i];
38
+ const arg = args[i]
36
39
 
37
40
  if (arg === '--url') {
38
- result.url = args[++i] || '';
39
- continue;
41
+ result.url = args[++i] || ''
42
+ continue
40
43
  }
41
44
 
42
45
  if (arg === '--out') {
43
- result.out = args[++i] || '';
44
- continue;
46
+ result.out = args[++i] || ''
47
+ continue
45
48
  }
46
49
 
47
50
  if (arg === '--version') {
48
- result.version = args[++i] || '';
49
- continue;
51
+ result.version = args[++i] || ''
52
+ continue
50
53
  }
54
+
51
55
  if (arg === '--extract') {
52
- result.extract = true;
53
- continue;
56
+ result.extract = true
57
+ continue
54
58
  }
55
59
 
56
60
  if (arg === '--user-agent') {
57
- result.userAgent = args[++i] || '';
58
- continue;
61
+ result.userAgent = args[++i] || ''
62
+ continue
59
63
  }
60
64
 
61
65
  if (arg === '--quiet') {
62
- result.quiet = true;
63
- continue;
66
+ result.quiet = true
67
+ continue
64
68
  }
65
69
 
66
70
  if (arg === '--verbose') {
67
- result.verbose = true;
68
- continue;
71
+ result.verbose = true
72
+ continue
69
73
  }
70
74
 
71
75
  if (arg === '--json') {
72
- result.json = true;
73
- continue;
76
+ result.json = true
77
+ continue
74
78
  }
75
79
 
76
- throw new Error(`Unknown flag: ${arg}`);
80
+ throw new Error(`Unknown flag: ${arg}`)
77
81
  }
78
82
 
79
83
  if (!result.url) {
80
- throw new Error('Missing required flag: --url');
84
+ throw new Error('Missing required flag: --url')
81
85
  }
82
86
 
83
- return result;
87
+ return result
84
88
  }
85
89
 
86
- function createCliLogger(opts) {
90
+ function createCliLogger (opts) {
87
91
  const emit = (level, message, error) => {
88
- const payload = { level, message };
92
+ const payload = {level, message}
89
93
 
90
- if (error) payload.error = String(error);
94
+ if (error) payload.error = String(error)
91
95
 
92
- console.log(JSON.stringify(payload));
93
- };
96
+ console.log(JSON.stringify(payload))
97
+ }
94
98
 
95
99
  if (opts.json) {
96
100
  return {
97
101
  onInfo: (message) => emit('info', message),
98
102
  onWarn: (message) => emit('warn', message),
99
- onError: (message, error) => emit('error', message, error),
100
- };
103
+ onError: (message, error) => emit('error', message, error)
104
+ }
101
105
  }
102
106
 
103
107
  return {
104
108
  onInfo: opts.quiet ? undefined : (message) => console.log(message),
105
109
  onWarn: opts.quiet ? undefined : (message) => console.error(message),
106
110
  onError: (message, error) => {
107
- const text = error ? `${message}\n${String(error)}` : message;
108
- console.error(text);
109
- },
110
- };
111
+ const text = error ? `${message}\n${String(error)}` : message
112
+
113
+ console.error(text)
114
+ }
115
+ }
111
116
  }
112
117
 
113
- async function main() {
114
- let args = null;
118
+ async function main () {
119
+ let args = null
115
120
 
116
121
  try {
117
- args = parseArgs(process.argv.slice(2));
118
- const logger = createCliLogger(args);
122
+ args = parseArgs(process.argv.slice(2))
123
+ const logger = createCliLogger(args)
124
+
119
125
  await fetchExtensionFromStore(args.url, {
120
126
  outDir: args.out || undefined,
121
127
  userAgent: args.userAgent || undefined,
122
128
  version: args.version || undefined,
123
129
  extract: args.extract,
124
- logger,
125
- });
130
+ logger
131
+ })
126
132
 
127
- process.exit(0);
133
+ process.exit(0)
128
134
  } catch (error) {
129
135
  if (error instanceof extensionFromStoreError) {
130
- const code = EXIT_CODES[error.code] || 1;
131
- const message = error.message || 'Extension fetch failed';
136
+ const code = EXIT_CODES[error.code] || 1
137
+ const message = error.message || 'Extension fetch failed'
132
138
 
133
139
  if (args?.json) {
134
- console.log(JSON.stringify({ level: 'error', message }));
140
+ console.log(JSON.stringify({level: 'error', message}))
135
141
  } else if (code !== 0) {
136
- console.error(message);
142
+ console.error(message)
137
143
  }
138
144
 
139
- process.exit(code);
145
+ process.exit(code)
140
146
  }
141
- const message = String(error?.message || error);
147
+
148
+ const message = String(error?.message || error)
142
149
 
143
150
  if (args?.json) {
144
- console.log(JSON.stringify({ level: 'error', message }));
151
+ console.log(JSON.stringify({level: 'error', message}))
145
152
  } else {
146
- console.error(message);
153
+ console.error(message)
147
154
  }
148
155
 
149
- process.exit(1);
156
+ process.exit(1)
150
157
  }
151
158
  }
152
159
 
153
- main();
160
+ main()
package/bin.js CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env node
2
1
 
3
- const mod = require('./dist/index.cjs');
4
- const fetchExtensionFromStore = mod.fetchExtensionFromStore;
5
- const extensionFromStoreError = mod.extensionFromStoreError;
2
+ const mod = require('./dist/index.cjs')
3
+
4
+ const {fetchExtensionFromStore} = mod
5
+ const {extensionFromStoreError} = mod
6
6
 
7
7
  const EXIT_CODES = {
8
8
  InvalidInput: 1,
@@ -12,13 +12,13 @@ const EXIT_CODES = {
12
12
  DownloadFailed: 4,
13
13
  ExtractionFailed: 5,
14
14
  FilesystemConflict: 6,
15
- StoreIncompatibility: 7,
16
- };
15
+ StoreIncompatibility: 7
16
+ }
17
17
 
18
- function parseArgs(argv) {
19
- const args = [...argv];
18
+ function parseArgs (argv) {
19
+ const args = [...argv]
20
20
 
21
- if (args[0] === 'fetch') args.shift();
21
+ if (args[0] === 'fetch') args.shift()
22
22
 
23
23
  const result = {
24
24
  url: '',
@@ -28,123 +28,129 @@ function parseArgs(argv) {
28
28
  extract: false,
29
29
  quiet: false,
30
30
  verbose: false,
31
- json: false,
32
- };
31
+ json: false
32
+ }
33
33
 
34
34
  for (let i = 0; i < args.length; i += 1) {
35
- const arg = args[i];
35
+ const arg = args[i]
36
36
 
37
37
  if (arg === '--url') {
38
- result.url = args[++i] || '';
39
- continue;
38
+ result.url = args[++i] || ''
39
+ continue
40
40
  }
41
41
 
42
42
  if (arg === '--out') {
43
- result.out = args[++i] || '';
44
- continue;
43
+ result.out = args[++i] || ''
44
+ continue
45
45
  }
46
46
 
47
47
  if (arg === '--version') {
48
- result.version = args[++i] || '';
49
- continue;
48
+ result.version = args[++i] || ''
49
+ continue
50
50
  }
51
+
51
52
  if (arg === '--extract') {
52
- result.extract = true;
53
- continue;
53
+ result.extract = true
54
+ continue
54
55
  }
55
56
 
56
57
  if (arg === '--user-agent') {
57
- result.userAgent = args[++i] || '';
58
- continue;
58
+ result.userAgent = args[++i] || ''
59
+ continue
59
60
  }
60
61
 
61
62
  if (arg === '--quiet') {
62
- result.quiet = true;
63
- continue;
63
+ result.quiet = true
64
+ continue
64
65
  }
65
66
 
66
67
  if (arg === '--verbose') {
67
- result.verbose = true;
68
- continue;
68
+ result.verbose = true
69
+ continue
69
70
  }
70
71
 
71
72
  if (arg === '--json') {
72
- result.json = true;
73
- continue;
73
+ result.json = true
74
+ continue
74
75
  }
75
76
 
76
- throw new Error(`Unknown flag: ${arg}`);
77
+ throw new Error(`Unknown flag: ${arg}`)
77
78
  }
78
79
 
79
80
  if (!result.url) {
80
- throw new Error('Missing required flag: --url');
81
+ throw new Error('Missing required flag: --url')
81
82
  }
82
83
 
83
- return result;
84
+ return result
84
85
  }
85
86
 
86
- function createCliLogger(opts) {
87
+ function createCliLogger (opts) {
87
88
  const emit = (level, message, error) => {
88
- const payload = { level, message };
89
- if (error) payload.error = String(error);
90
- console.log(JSON.stringify(payload));
91
- };
89
+ const payload = {level, message}
90
+
91
+ if (error) payload.error = String(error)
92
+
93
+ console.log(JSON.stringify(payload))
94
+ }
92
95
 
93
96
  if (opts.json) {
94
97
  return {
95
98
  onInfo: (message) => emit('info', message),
96
99
  onWarn: (message) => emit('warn', message),
97
- onError: (message, error) => emit('error', message, error),
98
- };
100
+ onError: (message, error) => emit('error', message, error)
101
+ }
99
102
  }
100
103
 
101
104
  return {
102
105
  onInfo: opts.quiet ? undefined : (message) => console.log(message),
103
106
  onWarn: opts.quiet ? undefined : (message) => console.error(message),
104
107
  onError: (message, error) => {
105
- const text = error ? `${message}\n${String(error)}` : message;
106
- console.error(text);
107
- },
108
- };
108
+ const text = error ? `${message}\n${String(error)}` : message
109
+
110
+ console.error(text)
111
+ }
112
+ }
109
113
  }
110
114
 
111
- async function main() {
112
- let args = null;
115
+ async function main () {
116
+ let args = null
113
117
 
114
118
  try {
115
- args = parseArgs(process.argv.slice(2));
116
- const logger = createCliLogger(args);
119
+ args = parseArgs(process.argv.slice(2))
120
+ const logger = createCliLogger(args)
121
+
117
122
  await fetchExtensionFromStore(args.url, {
118
123
  outDir: args.out || undefined,
119
124
  userAgent: args.userAgent || undefined,
120
125
  version: args.version || undefined,
121
126
  extract: args.extract,
122
- logger,
123
- });
124
- process.exit(0);
127
+ logger
128
+ })
129
+ process.exit(0)
125
130
  } catch (error) {
126
131
  if (error instanceof extensionFromStoreError) {
127
- const code = EXIT_CODES[error.code] || 1;
128
- const message = error.message || 'Extension fetch failed';
132
+ const code = EXIT_CODES[error.code] || 1
133
+ const message = error.message || 'Extension fetch failed'
129
134
 
130
135
  if (args?.json) {
131
- console.log(JSON.stringify({ level: 'error', message }));
136
+ console.log(JSON.stringify({level: 'error', message}))
132
137
  } else if (code !== 0) {
133
- console.error(message);
138
+ console.error(message)
134
139
  }
135
140
 
136
- process.exit(code);
141
+ process.exit(code)
137
142
  }
138
- const message = String(error?.message || error);
143
+
144
+ const message = String(error?.message || error)
139
145
 
140
146
  if (args?.json) {
141
- console.log(JSON.stringify({ level: 'error', message }));
147
+ console.log(JSON.stringify({level: 'error', message}))
142
148
  } else {
143
- console.error(message);
149
+ console.error(message)
144
150
  }
145
151
 
146
- process.exit(1);
152
+ process.exit(1)
147
153
  }
148
154
  }
149
155
 
150
- main();
156
+ main()
package/dist/core.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export { extensionFromStoreError, asExtensionFromStoreError, type ErrorCode, } from './errors';
1
+ export { extensionFromStoreError, asExtensionFromStoreError, type ErrorCode } from './errors';
2
2
  export { createLogger, type Logger } from './logger';
3
- export { parseManifestInfo, type ExtensionManifest, type ManifestInfo, } from './manifest';
4
- export { normalizeChromePlatformInfo, type ChromePlatformArch, type ChromePlatformInfo, type ChromePlatformOs, } from './platform';
5
- export { resolveDownload, sanitizeSegment, validateInput, type ResolveDownloadOptions, type ResolvedDownload, } from './resolve';
3
+ export { parseManifestInfo, type ExtensionManifest, type ManifestInfo } from './manifest';
4
+ export { normalizeChromePlatformInfo, type ChromePlatformArch, type ChromePlatformInfo, type ChromePlatformOs } from './platform';
5
+ export { resolveDownload, sanitizeSegment, validateInput, type ResolveDownloadOptions, type ResolvedDownload } from './resolve';
6
6
  export { stripCrxHeader } from './crx';
7
7
  export { getChromeDownloadUrl } from './stores/chrome';
8
8
  export { getEdgeDownloadUrl } from './stores/edge';
9
9
  export { resolveFirefoxDownload, type JsonRequester } from './stores/firefox';
10
- export { detectStoreFromUrl, extractChromeIdFromUrl, extractEdgeIdFromUrl, extractFirefoxSlugFromUrl, type StoreFromUrl, } from './stores/resolve-slug';
10
+ export { detectStoreFromUrl, extractChromeIdFromUrl, extractEdgeIdFromUrl, extractFirefoxSlugFromUrl, type StoreFromUrl } from './stores/resolve-slug';
package/dist/index.cjs CHANGED
@@ -168,7 +168,7 @@ async function downloadToFile(url, filePath, options, maxRedirects = 5) {
168
168
  }
169
169
  if (statusCode < 200 || statusCode >= 300) {
170
170
  if (404 === statusCode) throw new errors_extensionFromStoreError('NotFound', `Extension not found at ${url}`);
171
- if (401 === statusCode || 403 === statusCode) throw new errors_extensionFromStoreError('NotPublic', "Extension is not publicly downloadable");
171
+ if (401 === statusCode || 403 === statusCode) throw new errors_extensionFromStoreError('NotPublic', 'Extension is not publicly downloadable');
172
172
  throw new errors_extensionFromStoreError('DownloadFailed', `Failed to download ${url} (HTTP ${statusCode})`);
173
173
  }
174
174
  await (0, external_node_stream_promises_namespaceObject.pipeline)(stream, external_node_fs_default().createWriteStream(filePath));
package/dist/index.js CHANGED
@@ -123,7 +123,7 @@ async function downloadToFile(url, filePath, options, maxRedirects = 5) {
123
123
  }
124
124
  if (statusCode < 200 || statusCode >= 300) {
125
125
  if (404 === statusCode) throw new errors_extensionFromStoreError('NotFound', `Extension not found at ${url}`);
126
- if (401 === statusCode || 403 === statusCode) throw new errors_extensionFromStoreError('NotPublic', "Extension is not publicly downloadable");
126
+ if (401 === statusCode || 403 === statusCode) throw new errors_extensionFromStoreError('NotPublic', 'Extension is not publicly downloadable');
127
127
  throw new errors_extensionFromStoreError('DownloadFailed', `Failed to download ${url} (HTTP ${statusCode})`);
128
128
  }
129
129
  await (0, __WEBPACK_EXTERNAL_MODULE_node_stream_promises_5adae1f2__.pipeline)(stream, __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].createWriteStream(filePath));
package/dist/resolve.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { Logger } from './logger';
2
- import type { ChromePlatformInfo } from './platform';
3
1
  import { type JsonRequester } from './stores/firefox';
2
+ import type { ChromePlatformInfo } from './platform';
3
+ import type { Logger } from './logger';
4
4
  export type ResolvedDownload = {
5
5
  store: 'chrome' | 'edge' | 'firefox';
6
6
  downloadUrl: string;
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "engineStrict": false,
11
11
  "name": "extension-from-store",
12
- "version": "0.2.0",
12
+ "version": "0.2.1",
13
13
  "description": "Download public browser extensions from official stores",
14
14
  "homepage": "https://www.npmjs.com/package/extension-from-store",
15
15
  "type": "module",
@@ -43,14 +43,13 @@
43
43
  "scripts": {
44
44
  "build": "rslib build",
45
45
  "typecheck": "tsc --noEmit",
46
- "check": "pnpm dlx @biomejs/biome@1.9.4 check --write",
47
46
  "dev": "rslib build --watch",
48
- "format": "pnpm dlx @biomejs/biome@1.9.4 format --write",
49
47
  "pretest": "npm run build",
50
48
  "test": "vitest run",
51
49
  "test:live": "RUN_LIVE_FETCH=1 vitest run tests/live-fetch.test.ts",
52
50
  "prepublishOnly": "npm run build",
53
- "publish:provenance": "np patch --no-tests --any-branch --yolo --message 'release: %s' --provenance"
51
+ "lint": "eslint .",
52
+ "lint:fix": "eslint . --fix"
54
53
  },
55
54
  "publishConfig": {
56
55
  "provenance": true
@@ -83,12 +82,29 @@
83
82
  "extract-zip": "^2.0.1",
84
83
  "fflate": "^0.8.2"
85
84
  },
85
+ "pnpm": {
86
+ "overrides": {
87
+ "vite": ">=7.3.5",
88
+ "vitest": ">=3.2.6",
89
+ "rollup": ">=4.59.0",
90
+ "minimatch": ">=9.0.7",
91
+ "picomatch": ">=4.0.4",
92
+ "postcss": ">=8.5.10",
93
+ "js-yaml": ">=4.2.0",
94
+ "brace-expansion": ">=2.0.2",
95
+ "tmp": ">=0.2.6",
96
+ "esbuild": ">=0.25.0"
97
+ }
98
+ },
86
99
  "devDependencies": {
87
- "@biomejs/biome": "^1.9.4",
88
100
  "@rslib/core": "^0.6.9",
89
101
  "@types/node": "^22.8.1",
102
+ "eslint": "^10.5.0",
103
+ "eslint-config-auditor": "^2.0.0",
90
104
  "typescript": "^5.8.3",
91
105
  "vitest": "^3.1.3"
92
106
  },
93
- "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1"
107
+ "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1",
108
+ "bugs": "https://github.com/cezaraugusto/extension-from-store/issues",
109
+ "sideEffects": false
94
110
  }