extension-from-store 0.1.1 → 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 +36 -1
- package/bin.cjs +72 -68
- package/bin.js +70 -67
- package/dist/browser.cjs +355 -0
- package/dist/browser.d.ts +44 -0
- package/dist/browser.js +321 -0
- package/dist/core.cjs +301 -0
- package/dist/core.d.ts +10 -0
- package/dist/core.js +222 -0
- package/dist/crx.d.ts +1 -0
- package/dist/extract.d.ts +1 -1
- package/dist/index.cjs +142 -102
- package/dist/index.js +132 -92
- package/dist/manifest.d.ts +7 -0
- package/dist/meta.d.ts +1 -4
- package/dist/node-platform.d.ts +2 -0
- package/dist/platform.d.ts +8 -0
- package/dist/resolve.d.ts +21 -0
- package/dist/stores/chrome.d.ts +2 -1
- package/dist/stores/firefox.d.ts +5 -0
- package/package.json +35 -7
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[npm-version-image]: https://img.shields.io/npm/v/extension-from-store.svg?color=
|
|
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
|
|
@@ -45,6 +45,33 @@ const options = {
|
|
|
45
45
|
await fetchExtensionFromStore(url, options)
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
**Via browser entrypoint:**
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import {fetchExtensionFromStoreBrowser} from 'extension-from-store/browser'
|
|
52
|
+
|
|
53
|
+
const result = await fetchExtensionFromStoreBrowser(
|
|
54
|
+
'https://chromewebstore.google.com/detail/adblock-plus-free-ad-bloc/cfhdojbkjhnklbpkdaibdccddilifddb',
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
console.log(result.meta)
|
|
58
|
+
console.log(result.files.find((file) => file.path === 'manifest.json')?.text)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The browser entry keeps everything in memory and returns archive bytes, extracted files, and parsed manifest metadata. It does not write to disk.
|
|
62
|
+
|
|
63
|
+
**Via core helpers:**
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import {
|
|
67
|
+
detectStoreFromUrl,
|
|
68
|
+
extractChromeIdFromUrl,
|
|
69
|
+
getChromeDownloadUrl,
|
|
70
|
+
parseManifestInfo,
|
|
71
|
+
stripCrxHeader,
|
|
72
|
+
} from 'extension-from-store/core'
|
|
73
|
+
```
|
|
74
|
+
|
|
48
75
|
**Via CLI (default command is `fetch`):**
|
|
49
76
|
|
|
50
77
|
```bash
|
|
@@ -124,6 +151,14 @@ Library logging is opt-in via the `logger` hooks. The library never writes direc
|
|
|
124
151
|
- `6` filesystem conflict
|
|
125
152
|
- `7` store incompatibility
|
|
126
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
|
+
|
|
127
162
|
## License
|
|
128
163
|
|
|
129
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
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
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
|
+
}
|
|
18
20
|
|
|
19
|
-
function parseArgs(argv) {
|
|
20
|
-
const args = [...argv]
|
|
21
|
-
|
|
21
|
+
function parseArgs (argv) {
|
|
22
|
+
const args = [...argv]
|
|
23
|
+
|
|
24
|
+
if (args[0] === 'fetch') args.shift()
|
|
22
25
|
|
|
23
26
|
const result = {
|
|
24
27
|
url: '',
|
|
@@ -28,129 +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 = {
|
|
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
|
-
|
|
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)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
process.exit(0);
|
|
122
|
+
args = parseArgs(process.argv.slice(2))
|
|
123
|
+
const logger = createCliLogger(args)
|
|
124
|
+
|
|
125
|
+
await fetchExtensionFromStore(args.url, {
|
|
126
|
+
outDir: args.out || undefined,
|
|
127
|
+
userAgent: args.userAgent || undefined,
|
|
128
|
+
version: args.version || undefined,
|
|
129
|
+
extract: args.extract,
|
|
130
|
+
logger
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
process.exit(0)
|
|
131
134
|
} catch (error) {
|
|
132
135
|
if (error instanceof extensionFromStoreError) {
|
|
133
|
-
const code = EXIT_CODES[error.code] || 1
|
|
134
|
-
const message = error.message || 'Extension fetch failed'
|
|
136
|
+
const code = EXIT_CODES[error.code] || 1
|
|
137
|
+
const message = error.message || 'Extension fetch failed'
|
|
135
138
|
|
|
136
139
|
if (args?.json) {
|
|
137
|
-
console.log(JSON.stringify({
|
|
140
|
+
console.log(JSON.stringify({level: 'error', message}))
|
|
138
141
|
} else if (code !== 0) {
|
|
139
|
-
console.error(message)
|
|
142
|
+
console.error(message)
|
|
140
143
|
}
|
|
141
144
|
|
|
142
|
-
process.exit(code)
|
|
145
|
+
process.exit(code)
|
|
143
146
|
}
|
|
144
|
-
|
|
147
|
+
|
|
148
|
+
const message = String(error?.message || error)
|
|
145
149
|
|
|
146
150
|
if (args?.json) {
|
|
147
|
-
console.log(JSON.stringify({
|
|
151
|
+
console.log(JSON.stringify({level: 'error', message}))
|
|
148
152
|
} else {
|
|
149
|
-
console.error(message)
|
|
153
|
+
console.error(message)
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
process.exit(1)
|
|
156
|
+
process.exit(1)
|
|
153
157
|
}
|
|
154
158
|
}
|
|
155
159
|
|
|
156
|
-
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
|
-
|
|
5
|
-
const
|
|
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,126 +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 = {
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
);
|
|
127
|
-
process.exit(0);
|
|
119
|
+
args = parseArgs(process.argv.slice(2))
|
|
120
|
+
const logger = createCliLogger(args)
|
|
121
|
+
|
|
122
|
+
await fetchExtensionFromStore(args.url, {
|
|
123
|
+
outDir: args.out || undefined,
|
|
124
|
+
userAgent: args.userAgent || undefined,
|
|
125
|
+
version: args.version || undefined,
|
|
126
|
+
extract: args.extract,
|
|
127
|
+
logger
|
|
128
|
+
})
|
|
129
|
+
process.exit(0)
|
|
128
130
|
} catch (error) {
|
|
129
131
|
if (error instanceof extensionFromStoreError) {
|
|
130
|
-
const code = EXIT_CODES[error.code] || 1
|
|
131
|
-
const message = error.message || 'Extension fetch failed'
|
|
132
|
+
const code = EXIT_CODES[error.code] || 1
|
|
133
|
+
const message = error.message || 'Extension fetch failed'
|
|
132
134
|
|
|
133
135
|
if (args?.json) {
|
|
134
|
-
console.log(JSON.stringify({
|
|
136
|
+
console.log(JSON.stringify({level: 'error', message}))
|
|
135
137
|
} else if (code !== 0) {
|
|
136
|
-
console.error(message)
|
|
138
|
+
console.error(message)
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
process.exit(code)
|
|
141
|
+
process.exit(code)
|
|
140
142
|
}
|
|
141
|
-
|
|
143
|
+
|
|
144
|
+
const message = String(error?.message || error)
|
|
142
145
|
|
|
143
146
|
if (args?.json) {
|
|
144
|
-
console.log(JSON.stringify({
|
|
147
|
+
console.log(JSON.stringify({level: 'error', message}))
|
|
145
148
|
} else {
|
|
146
|
-
console.error(message)
|
|
149
|
+
console.error(message)
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
process.exit(1)
|
|
152
|
+
process.exit(1)
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
|
|
153
|
-
main()
|
|
156
|
+
main()
|