wyvrnpm 1.2.1 → 1.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.
@@ -1,43 +1,43 @@
1
- 'use strict';
2
-
3
- const S3Provider = require('./s3');
4
- const HttpProvider = require('./http');
5
- const FileProvider = require('./file');
6
-
7
- /**
8
- * Ordered list of providers. Detection runs top-to-bottom; first match wins.
9
- * Add new providers here (or call registerProvider() at runtime).
10
- */
11
- const PROVIDERS = [
12
- S3Provider, // must come before HttpProvider — S3 HTTPS URLs also match http://
13
- HttpProvider,
14
- FileProvider, // local paths and SMB UNC shares (\\server\share or //server/share)
15
- ];
16
-
17
- /**
18
- * Return an instantiated provider that can handle the given source string.
19
- * @param {string} source
20
- * @returns {import('./base')}
21
- */
22
- function getProvider(source) {
23
- for (const Provider of PROVIDERS) {
24
- if (Provider.canHandle(source)) {
25
- return new Provider();
26
- }
27
- }
28
- throw new Error(
29
- `No provider found for source: "${source}"\n` +
30
- 'Supported schemes: s3://, http://, https://, file://, local path, \\\\server\\share (SMB)',
31
- );
32
- }
33
-
34
- /**
35
- * Register a custom provider at the front of the detection list
36
- * (giving it higher priority than built-ins).
37
- * @param {typeof import('./base')} Provider
38
- */
39
- function registerProvider(Provider) {
40
- PROVIDERS.unshift(Provider);
41
- }
42
-
43
- module.exports = { getProvider, registerProvider, PROVIDERS };
1
+ 'use strict';
2
+
3
+ const S3Provider = require('./s3');
4
+ const HttpProvider = require('./http');
5
+ const FileProvider = require('./file');
6
+
7
+ /**
8
+ * Ordered list of providers. Detection runs top-to-bottom; first match wins.
9
+ * Add new providers here (or call registerProvider() at runtime).
10
+ */
11
+ const PROVIDERS = [
12
+ S3Provider, // must come before HttpProvider — S3 HTTPS URLs also match http://
13
+ HttpProvider,
14
+ FileProvider, // local paths and SMB UNC shares (\\server\share or //server/share)
15
+ ];
16
+
17
+ /**
18
+ * Return an instantiated provider that can handle the given source string.
19
+ * @param {string} source
20
+ * @returns {import('./base')}
21
+ */
22
+ function getProvider(source) {
23
+ for (const Provider of PROVIDERS) {
24
+ if (Provider.canHandle(source)) {
25
+ return new Provider();
26
+ }
27
+ }
28
+ throw new Error(
29
+ `No provider found for source: "${source}"\n` +
30
+ 'Supported schemes: s3://, http://, https://, file://, local path, \\\\server\\share (SMB)',
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Register a custom provider at the front of the detection list
36
+ * (giving it higher priority than built-ins).
37
+ * @param {typeof import('./base')} Provider
38
+ */
39
+ function registerProvider(Provider) {
40
+ PROVIDERS.unshift(Provider);
41
+ }
42
+
43
+ module.exports = { getProvider, registerProvider, PROVIDERS };
@@ -1,136 +1,136 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const BaseProvider = require('./base');
5
-
6
- // Matches: s3://bucket/...
7
- const RE_S3_URI = /^s3:\/\//;
8
- // Matches: https://bucket.s3.amazonaws.com/... or https://bucket.s3.us-east-1.amazonaws.com/...
9
- const RE_S3_VIRTUAL_HOSTED = /^https?:\/\/([^.]+)\.s3[.-][^/]*\.amazonaws\.com/;
10
- // Matches: https://s3.amazonaws.com/bucket/... or https://s3.us-east-1.amazonaws.com/bucket/...
11
- const RE_S3_PATH_STYLE = /^https?:\/\/s3[.-][^/]*\.amazonaws\.com\/([^/]+)/;
12
-
13
- class S3Provider extends BaseProvider {
14
- static canHandle(source) {
15
- return (
16
- RE_S3_URI.test(source) ||
17
- RE_S3_VIRTUAL_HOSTED.test(source) ||
18
- RE_S3_PATH_STYLE.test(source)
19
- );
20
- }
21
-
22
- static get providerName() {
23
- return 'S3';
24
- }
25
-
26
- /** Parse source into { bucket, prefix }. prefix has no leading/trailing slashes. */
27
- _parseSource(source) {
28
- if (RE_S3_URI.test(source)) {
29
- const rest = source.slice(5); // strip "s3://"
30
- const slash = rest.indexOf('/');
31
- if (slash === -1) return { bucket: rest, prefix: '' };
32
- return {
33
- bucket: rest.slice(0, slash),
34
- prefix: rest.slice(slash + 1).replace(/\/$/, ''),
35
- };
36
- }
37
-
38
- const url = new URL(source);
39
- const vhMatch = url.hostname.match(/^([^.]+)\.s3/);
40
- if (vhMatch) {
41
- return { bucket: vhMatch[1], prefix: url.pathname.slice(1).replace(/\/$/, '') };
42
- }
43
-
44
- // path-style: first path segment is the bucket
45
- const parts = url.pathname.slice(1).split('/');
46
- return {
47
- bucket: parts[0],
48
- prefix: parts.slice(1).join('/').replace(/\/$/, ''),
49
- };
50
- }
51
-
52
- async exists(options) {
53
- let S3Client, HeadObjectCommand, fromSSO;
54
- try {
55
- ({ S3Client, HeadObjectCommand } = require('@aws-sdk/client-s3'));
56
- ({ fromSSO } = require('@aws-sdk/credential-providers'));
57
- } catch {
58
- throw new Error(
59
- 'AWS SDK packages are required for S3 publishing.\n' +
60
- 'Run: npm install @aws-sdk/client-s3 @aws-sdk/credential-providers',
61
- );
62
- }
63
-
64
- const { source, platform, name, version, profile } = options;
65
- const { bucket, prefix } = this._parseSource(source);
66
- const key = [prefix, platform, name, version, 'wyvrn.json'].filter(Boolean).join('/');
67
-
68
- const clientConfig = profile ? { credentials: fromSSO({ profile }) } : {};
69
- const client = new S3Client(clientConfig);
70
- try {
71
- await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
72
- return true;
73
- } catch (err) {
74
- if (err.name === 'NotFound' || err.$metadata?.httpStatusCode === 404) return false;
75
- throw err;
76
- }
77
- }
78
-
79
- async publish(files, options) {
80
- // Lazy-load AWS SDK so the tool works without it when only HTTP is used.
81
- let S3Client, PutObjectCommand, fromSSO;
82
- try {
83
- ({ S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'));
84
- ({ fromSSO } = require('@aws-sdk/credential-providers'));
85
- } catch {
86
- throw new Error(
87
- 'AWS SDK packages are required for S3 publishing.\n' +
88
- 'Run: npm install @aws-sdk/client-s3 @aws-sdk/credential-providers',
89
- );
90
- }
91
-
92
- const { source, platform, name, version, profile } = options;
93
- const { bucket, prefix } = this._parseSource(source);
94
-
95
- // Destination key base: [prefix/]platform/name/version
96
- const keyBase = [prefix, platform, name, version].filter(Boolean).join('/');
97
- // Package root (without version) for latest.json
98
- const packageBase = [prefix, platform, name].filter(Boolean).join('/');
99
-
100
- const clientConfig = profile ? { credentials: fromSSO({ profile }) } : {};
101
- const client = new S3Client(clientConfig);
102
-
103
- await this._put(client, bucket, `${keyBase}/wyvrn.json`, files.manifest, 'application/json', PutObjectCommand);
104
- await this._put(client, bucket, `${keyBase}/wyvrn.zip`, files.zip, 'application/zip', PutObjectCommand);
105
-
106
- // Write latest.json at the package root so consumers can resolve "latest"
107
- const latestContent = Buffer.from(JSON.stringify({ version }));
108
- await this._putBuffer(client, bucket, `${packageBase}/latest.json`, latestContent, 'application/json', PutObjectCommand);
109
- }
110
-
111
- async _put(client, bucket, key, filePath, contentType, PutObjectCommand) {
112
- console.log(`[wyvrn] → s3://${bucket}/${key}`);
113
- await client.send(
114
- new PutObjectCommand({
115
- Bucket: bucket,
116
- Key: key,
117
- Body: fs.readFileSync(filePath),
118
- ContentType: contentType,
119
- }),
120
- );
121
- }
122
-
123
- async _putBuffer(client, bucket, key, content, contentType, PutObjectCommand) {
124
- console.log(`[wyvrn] → s3://${bucket}/${key}`);
125
- await client.send(
126
- new PutObjectCommand({
127
- Bucket: bucket,
128
- Key: key,
129
- Body: content,
130
- ContentType: contentType,
131
- }),
132
- );
133
- }
134
- }
135
-
136
- module.exports = S3Provider;
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const BaseProvider = require('./base');
5
+
6
+ // Matches: s3://bucket/...
7
+ const RE_S3_URI = /^s3:\/\//;
8
+ // Matches: https://bucket.s3.amazonaws.com/... or https://bucket.s3.us-east-1.amazonaws.com/...
9
+ const RE_S3_VIRTUAL_HOSTED = /^https?:\/\/([^.]+)\.s3[.-][^/]*\.amazonaws\.com/;
10
+ // Matches: https://s3.amazonaws.com/bucket/... or https://s3.us-east-1.amazonaws.com/bucket/...
11
+ const RE_S3_PATH_STYLE = /^https?:\/\/s3[.-][^/]*\.amazonaws\.com\/([^/]+)/;
12
+
13
+ class S3Provider extends BaseProvider {
14
+ static canHandle(source) {
15
+ return (
16
+ RE_S3_URI.test(source) ||
17
+ RE_S3_VIRTUAL_HOSTED.test(source) ||
18
+ RE_S3_PATH_STYLE.test(source)
19
+ );
20
+ }
21
+
22
+ static get providerName() {
23
+ return 'S3';
24
+ }
25
+
26
+ /** Parse source into { bucket, prefix }. prefix has no leading/trailing slashes. */
27
+ _parseSource(source) {
28
+ if (RE_S3_URI.test(source)) {
29
+ const rest = source.slice(5); // strip "s3://"
30
+ const slash = rest.indexOf('/');
31
+ if (slash === -1) return { bucket: rest, prefix: '' };
32
+ return {
33
+ bucket: rest.slice(0, slash),
34
+ prefix: rest.slice(slash + 1).replace(/\/$/, ''),
35
+ };
36
+ }
37
+
38
+ const url = new URL(source);
39
+ const vhMatch = url.hostname.match(/^([^.]+)\.s3/);
40
+ if (vhMatch) {
41
+ return { bucket: vhMatch[1], prefix: url.pathname.slice(1).replace(/\/$/, '') };
42
+ }
43
+
44
+ // path-style: first path segment is the bucket
45
+ const parts = url.pathname.slice(1).split('/');
46
+ return {
47
+ bucket: parts[0],
48
+ prefix: parts.slice(1).join('/').replace(/\/$/, ''),
49
+ };
50
+ }
51
+
52
+ async exists(options) {
53
+ let S3Client, HeadObjectCommand, fromSSO;
54
+ try {
55
+ ({ S3Client, HeadObjectCommand } = require('@aws-sdk/client-s3'));
56
+ ({ fromSSO } = require('@aws-sdk/credential-providers'));
57
+ } catch {
58
+ throw new Error(
59
+ 'AWS SDK packages are required for S3 publishing.\n' +
60
+ 'Run: npm install @aws-sdk/client-s3 @aws-sdk/credential-providers',
61
+ );
62
+ }
63
+
64
+ const { source, platform, name, version, profile } = options;
65
+ const { bucket, prefix } = this._parseSource(source);
66
+ const key = [prefix, platform, name, version, 'wyvrn.json'].filter(Boolean).join('/');
67
+
68
+ const clientConfig = profile ? { credentials: fromSSO({ profile }) } : {};
69
+ const client = new S3Client(clientConfig);
70
+ try {
71
+ await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
72
+ return true;
73
+ } catch (err) {
74
+ if (err.name === 'NotFound' || err.$metadata?.httpStatusCode === 404) return false;
75
+ throw err;
76
+ }
77
+ }
78
+
79
+ async publish(files, options) {
80
+ // Lazy-load AWS SDK so the tool works without it when only HTTP is used.
81
+ let S3Client, PutObjectCommand, fromSSO;
82
+ try {
83
+ ({ S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'));
84
+ ({ fromSSO } = require('@aws-sdk/credential-providers'));
85
+ } catch {
86
+ throw new Error(
87
+ 'AWS SDK packages are required for S3 publishing.\n' +
88
+ 'Run: npm install @aws-sdk/client-s3 @aws-sdk/credential-providers',
89
+ );
90
+ }
91
+
92
+ const { source, platform, name, version, profile } = options;
93
+ const { bucket, prefix } = this._parseSource(source);
94
+
95
+ // Destination key base: [prefix/]platform/name/version
96
+ const keyBase = [prefix, platform, name, version].filter(Boolean).join('/');
97
+ // Package root (without version) for latest.json
98
+ const packageBase = [prefix, platform, name].filter(Boolean).join('/');
99
+
100
+ const clientConfig = profile ? { credentials: fromSSO({ profile }) } : {};
101
+ const client = new S3Client(clientConfig);
102
+
103
+ await this._put(client, bucket, `${keyBase}/wyvrn.json`, files.manifest, 'application/json', PutObjectCommand);
104
+ await this._put(client, bucket, `${keyBase}/wyvrn.zip`, files.zip, 'application/zip', PutObjectCommand);
105
+
106
+ // Write latest.json at the package root so consumers can resolve "latest"
107
+ const latestContent = Buffer.from(JSON.stringify({ version }));
108
+ await this._putBuffer(client, bucket, `${packageBase}/latest.json`, latestContent, 'application/json', PutObjectCommand);
109
+ }
110
+
111
+ async _put(client, bucket, key, filePath, contentType, PutObjectCommand) {
112
+ console.log(`[wyvrn] → s3://${bucket}/${key}`);
113
+ await client.send(
114
+ new PutObjectCommand({
115
+ Bucket: bucket,
116
+ Key: key,
117
+ Body: fs.readFileSync(filePath),
118
+ ContentType: contentType,
119
+ }),
120
+ );
121
+ }
122
+
123
+ async _putBuffer(client, bucket, key, content, contentType, PutObjectCommand) {
124
+ console.log(`[wyvrn] → s3://${bucket}/${key}`);
125
+ await client.send(
126
+ new PutObjectCommand({
127
+ Bucket: bucket,
128
+ Key: key,
129
+ Body: content,
130
+ ContentType: contentType,
131
+ }),
132
+ );
133
+ }
134
+ }
135
+
136
+ module.exports = S3Provider;