@push.rocks/smartnpm 2.0.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.
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +4 -0
- package/dist_ts/smartnpm.classes.npmpackage.d.ts +82 -0
- package/dist_ts/smartnpm.classes.npmpackage.js +118 -0
- package/dist_ts/smartnpm.classes.npmregistry.d.ts +41 -0
- package/dist_ts/smartnpm.classes.npmregistry.js +197 -0
- package/dist_ts/smartnpm.classes.packagedisttag.d.ts +5 -0
- package/dist_ts/smartnpm.classes.packagedisttag.js +8 -0
- package/dist_ts/smartnpm.classes.packageversion.d.ts +31 -0
- package/dist_ts/smartnpm.classes.packageversion.js +9 -0
- package/dist_ts/smartnpm.classes.registrycache.d.ts +17 -0
- package/dist_ts/smartnpm.classes.registrycache.js +35 -0
- package/dist_ts/smartnpm.interfaces.d.ts +15 -0
- package/dist_ts/smartnpm.interfaces.js +2 -0
- package/dist_ts/smartnpm.paths.d.ts +2 -0
- package/dist_ts/smartnpm.paths.js +4 -0
- package/dist_ts/smartnpm.plugins.d.ts +14 -0
- package/dist_ts/smartnpm.plugins.js +18 -0
- package/npmextra.json +17 -0
- package/package.json +49 -0
- package/readme.md +39 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +4 -0
- package/ts/smartnpm.classes.npmpackage.ts +187 -0
- package/ts/smartnpm.classes.npmregistry.ts +228 -0
- package/ts/smartnpm.classes.packagedisttag.ts +11 -0
- package/ts/smartnpm.classes.packageversion.ts +31 -0
- package/ts/smartnpm.classes.registrycache.ts +50 -0
- package/ts/smartnpm.interfaces.ts +24 -0
- package/ts/smartnpm.paths.ts +4 -0
- package/ts/smartnpm.plugins.ts +22 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// node native modules
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
export { path };
|
|
4
|
+
// @pushrocks scope
|
|
5
|
+
import * as consolecolor from '@pushrocks/consolecolor';
|
|
6
|
+
import * as levelcache from '@pushrocks/levelcache';
|
|
7
|
+
import * as smartarchive from '@pushrocks/smartarchive';
|
|
8
|
+
import * as smartfile from '@pushrocks/smartfile';
|
|
9
|
+
import * as smartpath from '@pushrocks/smartpath';
|
|
10
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
11
|
+
import * as smartrequest from '@pushrocks/smartrequest';
|
|
12
|
+
import * as smartversion from '@pushrocks/smartversion';
|
|
13
|
+
import * as smarttime from '@pushrocks/smarttime';
|
|
14
|
+
export { consolecolor, levelcache, smartarchive, smartfile, smartpath, smartpromise, smartrequest, smartversion, smarttime };
|
|
15
|
+
// third party scope
|
|
16
|
+
import packageJson from 'package-json';
|
|
17
|
+
export { packageJson };
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRucG0ucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0bnBtLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVoQixtQkFBbUI7QUFDbkIsT0FBTyxLQUFLLFlBQVksTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssVUFBVSxNQUFNLHVCQUF1QixDQUFDO0FBQ3BELE9BQU8sS0FBSyxZQUFZLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEtBQUssU0FBUyxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxZQUFZLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxLQUFLLFlBQVksTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssWUFBWSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0JBQXNCLENBQUM7QUFFbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLENBQUM7QUFFN0gsb0JBQW9CO0FBQ3BCLE9BQU8sV0FBVyxNQUFNLGNBQWMsQ0FBQztBQUV2QyxPQUFPLEVBQUUsV0FBVyxFQUFFLENBQUMifQ==
|
package/npmextra.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"npmci": {
|
|
3
|
+
"npmGlobalTools": [],
|
|
4
|
+
"npmAccessLevel": "public"
|
|
5
|
+
},
|
|
6
|
+
"gitzone": {
|
|
7
|
+
"projectType": "npm",
|
|
8
|
+
"module": {
|
|
9
|
+
"githost": "gitlab.com",
|
|
10
|
+
"gitscope": "pushrocks",
|
|
11
|
+
"gitrepo": "smartnpm",
|
|
12
|
+
"shortDescription": "interface with npm to retrieve package information",
|
|
13
|
+
"npmPackagename": "@pushrocks/smartnpm",
|
|
14
|
+
"license": "MIT"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@push.rocks/smartnpm",
|
|
3
|
+
"version": "2.0.3",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "interface with npm to retrieve package information",
|
|
6
|
+
"main": "dist_ts/index.js",
|
|
7
|
+
"typings": "dist_ts/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"author": "Lossless GmbH",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "(tstest test/)",
|
|
13
|
+
"build": "(tsbuild --web --allowimplicitany)"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@gitzone/tsbuild": "^2.1.63",
|
|
17
|
+
"@gitzone/tsrun": "^1.2.35",
|
|
18
|
+
"@gitzone/tstest": "^1.0.71",
|
|
19
|
+
"@pushrocks/tapbundle": "^5.0.3",
|
|
20
|
+
"@types/node": "^17.0.41"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@pushrocks/consolecolor": "^2.0.1",
|
|
24
|
+
"@pushrocks/levelcache": "^3.0.2",
|
|
25
|
+
"@pushrocks/smartarchive": "^3.0.6",
|
|
26
|
+
"@pushrocks/smartfile": "^10.0.1",
|
|
27
|
+
"@pushrocks/smartpath": "^5.0.5",
|
|
28
|
+
"@pushrocks/smartpromise": "^3.1.7",
|
|
29
|
+
"@pushrocks/smartrequest": "^1.1.56",
|
|
30
|
+
"@pushrocks/smarttime": "^3.0.45",
|
|
31
|
+
"@pushrocks/smartversion": "^3.0.2",
|
|
32
|
+
"package-json": "^7.0.0"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"ts/**/*",
|
|
36
|
+
"ts_web/**/*",
|
|
37
|
+
"dist/**/*",
|
|
38
|
+
"dist_*/**/*",
|
|
39
|
+
"dist_ts/**/*",
|
|
40
|
+
"dist_ts_web/**/*",
|
|
41
|
+
"assets/**/*",
|
|
42
|
+
"cli.js",
|
|
43
|
+
"npmextra.json",
|
|
44
|
+
"readme.md"
|
|
45
|
+
],
|
|
46
|
+
"browserslist": [
|
|
47
|
+
"last 1 chrome versions"
|
|
48
|
+
]
|
|
49
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @pushrocks/smartnpm
|
|
2
|
+
interface with npm to retrieve package information
|
|
3
|
+
|
|
4
|
+
## Availabililty and Links
|
|
5
|
+
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartnpm)
|
|
6
|
+
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartnpm)
|
|
7
|
+
* [github.com (source mirror)](https://github.com/pushrocks/smartnpm)
|
|
8
|
+
* [docs (typedoc)](https://pushrocks.gitlab.io/smartnpm/)
|
|
9
|
+
|
|
10
|
+
## Status for master
|
|
11
|
+
|
|
12
|
+
Status Category | Status Badge
|
|
13
|
+
-- | --
|
|
14
|
+
GitLab Pipelines | [](https://lossless.cloud)
|
|
15
|
+
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
|
16
|
+
npm | [](https://lossless.cloud)
|
|
17
|
+
Snyk | [](https://lossless.cloud)
|
|
18
|
+
TypeScript Support | [](https://lossless.cloud)
|
|
19
|
+
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
20
|
+
Code Style | [](https://lossless.cloud)
|
|
21
|
+
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
|
22
|
+
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
|
23
|
+
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
|
24
|
+
Platform support | [](https://lossless.cloud) [](https://lossless.cloud)
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Use TypeScript for best in class instellisense.
|
|
29
|
+
|
|
30
|
+
## Contribution
|
|
31
|
+
|
|
32
|
+
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
|
33
|
+
|
|
34
|
+
For further information read the linked docs at the top of this readme.
|
|
35
|
+
|
|
36
|
+
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
|
37
|
+
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
|
|
38
|
+
|
|
39
|
+
[](https://maintainedby.lossless.com)
|
package/ts/index.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as plugins from './smartnpm.plugins.js';
|
|
2
|
+
import { NpmRegistry } from './smartnpm.classes.npmregistry.js';
|
|
3
|
+
import { PackageDisttag } from './smartnpm.classes.packagedisttag.js';
|
|
4
|
+
import { PackageVersion, IVersionData } from './smartnpm.classes.packageversion.js';
|
|
5
|
+
|
|
6
|
+
export class NpmPackage {
|
|
7
|
+
public static async createFromFullMetadataAndVersionData(
|
|
8
|
+
npmRegistryArg: NpmRegistry,
|
|
9
|
+
fullMetadataArg: plugins.packageJson.FullMetadata,
|
|
10
|
+
versionsDataArg: {
|
|
11
|
+
name: string;
|
|
12
|
+
'dist-tags': { [key: string]: string };
|
|
13
|
+
versions: { [key: string]: IVersionData };
|
|
14
|
+
}
|
|
15
|
+
) {
|
|
16
|
+
const npmPackage = new NpmPackage(npmRegistryArg);
|
|
17
|
+
Object.assign(npmPackage, fullMetadataArg);
|
|
18
|
+
npmPackage.allVersions = [];
|
|
19
|
+
npmPackage.allDistTags = [];
|
|
20
|
+
for (const versionArg of Object.keys(versionsDataArg.versions)) {
|
|
21
|
+
const packageVersion = PackageVersion.createFromVersionData(
|
|
22
|
+
versionsDataArg.versions[versionArg]
|
|
23
|
+
);
|
|
24
|
+
npmPackage.allVersions.push(packageVersion);
|
|
25
|
+
}
|
|
26
|
+
for (const distTagArg of Object.keys(versionsDataArg['dist-tags'])) {
|
|
27
|
+
const packageDistTag = new PackageDisttag(
|
|
28
|
+
distTagArg,
|
|
29
|
+
versionsDataArg['dist-tags'][distTagArg]
|
|
30
|
+
);
|
|
31
|
+
npmPackage.allDistTags.push(packageDistTag);
|
|
32
|
+
}
|
|
33
|
+
return npmPackage;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// INSTANCE
|
|
37
|
+
public name: string = null;
|
|
38
|
+
public scope: string = null;
|
|
39
|
+
public version: string = null;
|
|
40
|
+
public allVersions: PackageVersion[];
|
|
41
|
+
public allDistTags: PackageDisttag[];
|
|
42
|
+
public description: string = null;
|
|
43
|
+
public keywords: string[] = null;
|
|
44
|
+
public date: string;
|
|
45
|
+
public license: string;
|
|
46
|
+
public links: {
|
|
47
|
+
npm: string;
|
|
48
|
+
homepage: string;
|
|
49
|
+
repository: string;
|
|
50
|
+
bugs: string;
|
|
51
|
+
};
|
|
52
|
+
public author: {
|
|
53
|
+
name: 'Lossless GmbH';
|
|
54
|
+
};
|
|
55
|
+
public publisher: {
|
|
56
|
+
username: 'gitzone';
|
|
57
|
+
email: 'npm@git.zone';
|
|
58
|
+
};
|
|
59
|
+
public maintainers: any = null;
|
|
60
|
+
public dist: {
|
|
61
|
+
integrity: string;
|
|
62
|
+
shasum: string;
|
|
63
|
+
tarball: string;
|
|
64
|
+
};
|
|
65
|
+
public score: {
|
|
66
|
+
final: number;
|
|
67
|
+
detail: {
|
|
68
|
+
quality: number;
|
|
69
|
+
popularity: number;
|
|
70
|
+
maintenance: number;
|
|
71
|
+
};
|
|
72
|
+
} = null;
|
|
73
|
+
public searchScore: number = null;
|
|
74
|
+
|
|
75
|
+
public npmRegistryRef: NpmRegistry;
|
|
76
|
+
constructor(npmRegistryArg: NpmRegistry) {
|
|
77
|
+
this.npmRegistryRef = npmRegistryArg;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* saves the package to disk
|
|
82
|
+
*/
|
|
83
|
+
public async saveToDisk(targetDir: string) {
|
|
84
|
+
const smartarchiveInstance = new plugins.smartarchive.SmartArchive();
|
|
85
|
+
await smartarchiveInstance.extractArchiveFromUrlToFs(this.dist.tarball, targetDir);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* saves the complete package to cache
|
|
90
|
+
*/
|
|
91
|
+
public async saveToCache() {}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* get files from package
|
|
95
|
+
*/
|
|
96
|
+
public async getFilesFromPackage(
|
|
97
|
+
filePath: string,
|
|
98
|
+
optionsArg: {
|
|
99
|
+
distTag?: string;
|
|
100
|
+
version?: string;
|
|
101
|
+
},
|
|
102
|
+
returnOnFirstArg = false
|
|
103
|
+
): Promise<plugins.smartfile.Smartfile[]> {
|
|
104
|
+
const done = plugins.smartpromise.defer<plugins.smartfile.Smartfile[]>();
|
|
105
|
+
const smartarchiveInstance = new plugins.smartarchive.SmartArchive();
|
|
106
|
+
let tarballUrl = this.dist?.tarball;
|
|
107
|
+
if (optionsArg?.version || optionsArg?.distTag) {
|
|
108
|
+
if (optionsArg.distTag && optionsArg.version) {
|
|
109
|
+
throw new Error('Please either specify version OR disttag, not both.');
|
|
110
|
+
}
|
|
111
|
+
let targetVersionString: string;
|
|
112
|
+
if (optionsArg.distTag) {
|
|
113
|
+
const targetDistTag = this.allDistTags.find((distTag) => {
|
|
114
|
+
return distTag.name === optionsArg.distTag;
|
|
115
|
+
});
|
|
116
|
+
if (targetDistTag) {
|
|
117
|
+
targetVersionString = targetDistTag.targetVersion;
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
targetVersionString = optionsArg.version;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// lets find the best matching release
|
|
124
|
+
const bestMatchingVersion = this.getBestMatchingVersion(targetVersionString);
|
|
125
|
+
if (!bestMatchingVersion) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
tarballUrl = this.allVersions.find(
|
|
129
|
+
(packageVersion) => packageVersion.version === bestMatchingVersion
|
|
130
|
+
).dist.tarball;
|
|
131
|
+
}
|
|
132
|
+
const fileObservable = await smartarchiveInstance.extractArchiveFromUrlToObservable(tarballUrl);
|
|
133
|
+
const wantedFilePath = plugins.path.join('package', filePath);
|
|
134
|
+
const allMatchingFiles: plugins.smartfile.Smartfile[] = [];
|
|
135
|
+
const subscription = fileObservable.subscribe(
|
|
136
|
+
(fileArg) => {
|
|
137
|
+
// returnOnFirstArg requires exact match
|
|
138
|
+
if (returnOnFirstArg && fileArg.path === wantedFilePath) {
|
|
139
|
+
// lets resolve with the wanted file
|
|
140
|
+
done.resolve([fileArg]);
|
|
141
|
+
subscription.unsubscribe();
|
|
142
|
+
} else if(!returnOnFirstArg && fileArg.path.startsWith(wantedFilePath)) {
|
|
143
|
+
allMatchingFiles.push(fileArg);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
(err) => {
|
|
147
|
+
console.log(err);
|
|
148
|
+
},
|
|
149
|
+
() => {
|
|
150
|
+
done.resolve(allMatchingFiles);
|
|
151
|
+
subscription.unsubscribe();
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
return done.promise;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* get files from package
|
|
159
|
+
*/
|
|
160
|
+
public async getFileFromPackage(
|
|
161
|
+
filePath: string,
|
|
162
|
+
optionsArg?: {
|
|
163
|
+
distTag?: string;
|
|
164
|
+
version?: string;
|
|
165
|
+
}
|
|
166
|
+
): Promise<plugins.smartfile.Smartfile> {
|
|
167
|
+
const result = await this.getFilesFromPackage(filePath, optionsArg, true);
|
|
168
|
+
return result[0] || null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* updates the package with information from the registry
|
|
173
|
+
*/
|
|
174
|
+
update() {}
|
|
175
|
+
|
|
176
|
+
/** */
|
|
177
|
+
public getBestMatchingVersion(versionArg: string): string {
|
|
178
|
+
// lets find the best matching release
|
|
179
|
+
const targetVersion = plugins.smartversion.SmartVersion.fromFuzzyString(versionArg);
|
|
180
|
+
const versionStrings = this.allVersions.map((packageVersion) => packageVersion.version);
|
|
181
|
+
const bestMatchingVersion = targetVersion.getBestMatch(versionStrings);
|
|
182
|
+
if (!bestMatchingVersion) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return bestMatchingVersion;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as plugins from './smartnpm.plugins.js';
|
|
2
|
+
import * as paths from './smartnpm.paths.js';
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import { ISearchObject } from './smartnpm.interfaces.js';
|
|
6
|
+
|
|
7
|
+
// classes
|
|
8
|
+
import { NpmPackage } from './smartnpm.classes.npmpackage.js';
|
|
9
|
+
import { ICacheDescriptor, RegistryCache } from './smartnpm.classes.registrycache.js';
|
|
10
|
+
|
|
11
|
+
export interface INpmRegistryConstructorOptions {
|
|
12
|
+
npmRegistryUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class NpmRegistry {
|
|
16
|
+
public options: INpmRegistryConstructorOptions;
|
|
17
|
+
public registryCache: RegistryCache;
|
|
18
|
+
private searchDomain = 'https://api.npms.io/v2/search?q=';
|
|
19
|
+
|
|
20
|
+
constructor(optionsArg: INpmRegistryConstructorOptions = {}) {
|
|
21
|
+
const defaultOptions: INpmRegistryConstructorOptions = {
|
|
22
|
+
npmRegistryUrl: 'https://registry.npmjs.org',
|
|
23
|
+
};
|
|
24
|
+
this.options = {
|
|
25
|
+
...defaultOptions,
|
|
26
|
+
...optionsArg,
|
|
27
|
+
};
|
|
28
|
+
this.registryCache = new RegistryCache(this);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* gets info about a package
|
|
33
|
+
* @param packageName
|
|
34
|
+
*/
|
|
35
|
+
public async getPackageInfo(packageName: string): Promise<NpmPackage> {
|
|
36
|
+
const fullMetadata = await plugins.packageJson(packageName, {
|
|
37
|
+
registryUrl: this.options.npmRegistryUrl,
|
|
38
|
+
fullMetadata: true,
|
|
39
|
+
}).catch(err => {
|
|
40
|
+
console.log(err);
|
|
41
|
+
return null;
|
|
42
|
+
});
|
|
43
|
+
const versionData = await plugins.packageJson(packageName, {
|
|
44
|
+
registryUrl: this.options.npmRegistryUrl,
|
|
45
|
+
allVersions: true
|
|
46
|
+
});
|
|
47
|
+
const npmPackage = await NpmPackage.createFromFullMetadataAndVersionData(this, fullMetadata, versionData as any);
|
|
48
|
+
return npmPackage;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* saves a package to disk
|
|
53
|
+
* @param packageName
|
|
54
|
+
* @param targetDir
|
|
55
|
+
*/
|
|
56
|
+
public async savePackageToDisk(packageName: string, targetDir: string): Promise<void> {
|
|
57
|
+
plugins.smartfile.fs.ensureDirSync(paths.nogitDir);
|
|
58
|
+
const npmPackage = await this.getPackageInfo(packageName);
|
|
59
|
+
await npmPackage.saveToDisk(targetDir);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* gets a file from a package as Smartfile
|
|
64
|
+
*/
|
|
65
|
+
public async getFileFromPackage(packageNameArg: string, filePathArg: string, optionsArg?: {
|
|
66
|
+
distTag?: string;
|
|
67
|
+
version?: string;
|
|
68
|
+
}): Promise<plugins.smartfile.Smartfile> {
|
|
69
|
+
// lets create a cache descriptor
|
|
70
|
+
const cacheDescriptor: ICacheDescriptor = {
|
|
71
|
+
registryUrl: this.options.npmRegistryUrl,
|
|
72
|
+
packageName: packageNameArg,
|
|
73
|
+
filePath: filePathArg,
|
|
74
|
+
distTag: optionsArg?.distTag,
|
|
75
|
+
version: optionsArg?.version
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// lets see if we have something cached
|
|
79
|
+
const cachedFile: plugins.smartfile.Smartfile = await this.registryCache.getCachedFile(cacheDescriptor);
|
|
80
|
+
|
|
81
|
+
// lets handle both occasions
|
|
82
|
+
if (!cachedFile) {
|
|
83
|
+
const npmPackage = await this.getPackageInfo(packageNameArg);
|
|
84
|
+
if (!optionsArg?.version && !optionsArg?.distTag) {
|
|
85
|
+
const latestAvailable = npmPackage.allDistTags.find(packageArg => packageArg.name === 'latest');
|
|
86
|
+
if (!latestAvailable) {
|
|
87
|
+
optionsArg = {
|
|
88
|
+
version: npmPackage.getBestMatchingVersion('*')
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const fileResult = await npmPackage.getFileFromPackage(filePathArg, optionsArg);
|
|
93
|
+
if (fileResult) {
|
|
94
|
+
this.registryCache.cacheSmartFile(cacheDescriptor, fileResult);
|
|
95
|
+
}
|
|
96
|
+
return fileResult;
|
|
97
|
+
} else {
|
|
98
|
+
return cachedFile;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async getFilesFromPackage(packageNameArg: string, filePath: string, optionsArg?: {
|
|
103
|
+
distTag?: string;
|
|
104
|
+
version?: string;
|
|
105
|
+
}): Promise<plugins.smartfile.Smartfile[]> {
|
|
106
|
+
const npmPackage = await this.getPackageInfo(packageNameArg);
|
|
107
|
+
if (!optionsArg?.version && !optionsArg?.distTag) {
|
|
108
|
+
const latestAvailable = npmPackage.allDistTags.find(packageDistTagArg => packageDistTagArg.name === 'latest');
|
|
109
|
+
if (!latestAvailable) {
|
|
110
|
+
optionsArg = {
|
|
111
|
+
version: npmPackage.getBestMatchingVersion('*')
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return npmPackage.getFilesFromPackage(filePath, optionsArg);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public async getPackageAsSmartfileVirtualDir(packageNameArg: string): Promise<plugins.smartfile.VirtualDirectory> {
|
|
119
|
+
/**
|
|
120
|
+
* TODO: rewrite as memory only
|
|
121
|
+
*/
|
|
122
|
+
const baseDir = plugins.path.join(paths.nogitDir, packageNameArg.replace('/', '__'));
|
|
123
|
+
await plugins.smartfile.fs.ensureDir(baseDir);
|
|
124
|
+
await this.savePackageToDisk(packageNameArg, baseDir);
|
|
125
|
+
const virtualDir = await plugins.smartfile.VirtualDirectory.fromFsDirPath(baseDir);
|
|
126
|
+
await plugins.smartfile.fs.remove(baseDir);
|
|
127
|
+
return virtualDir;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* searches for a package on npm
|
|
132
|
+
* @param searchObjectArg
|
|
133
|
+
*/
|
|
134
|
+
public async searchOnNpm(searchObjectArg: ISearchObject) {
|
|
135
|
+
if (this.options.npmRegistryUrl !== 'https://registry.npmjs.org') {
|
|
136
|
+
throw Error(`cannot search registries other than registry.gitlab.com`);
|
|
137
|
+
}
|
|
138
|
+
let searchString = '';
|
|
139
|
+
const addToSearchString = (addStringArg: string) => {
|
|
140
|
+
searchString = `${searchString}+${addStringArg}`;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// name
|
|
144
|
+
if (searchObjectArg.name) {
|
|
145
|
+
searchString = `${searchObjectArg.name}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// metadata
|
|
149
|
+
if (searchObjectArg.author) {
|
|
150
|
+
addToSearchString(`author:${searchObjectArg.author}`);
|
|
151
|
+
}
|
|
152
|
+
if (searchObjectArg.maintainer) {
|
|
153
|
+
addToSearchString(`maintainer:${searchObjectArg.maintainer}`);
|
|
154
|
+
}
|
|
155
|
+
if (searchObjectArg.scope) {
|
|
156
|
+
addToSearchString(`scope:${searchObjectArg.scope}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// status
|
|
160
|
+
if (searchObjectArg.deprecated) {
|
|
161
|
+
if (searchObjectArg.deprecated === true) {
|
|
162
|
+
addToSearchString(`is:deprecated`);
|
|
163
|
+
} else {
|
|
164
|
+
addToSearchString(`not:deprecated`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (searchObjectArg.unstable) {
|
|
168
|
+
if (searchObjectArg.unstable === true) {
|
|
169
|
+
addToSearchString(`is:unstable`);
|
|
170
|
+
} else {
|
|
171
|
+
addToSearchString(`not:unstable`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (searchObjectArg.insecure) {
|
|
175
|
+
if (searchObjectArg.insecure === true) {
|
|
176
|
+
addToSearchString(`is:insecure`);
|
|
177
|
+
} else {
|
|
178
|
+
addToSearchString(`not:insecure`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// search behaviour
|
|
183
|
+
if (searchObjectArg.boostExact) {
|
|
184
|
+
addToSearchString(`boost-exact:${searchObjectArg.boostExact}`);
|
|
185
|
+
}
|
|
186
|
+
if (searchObjectArg.scoreEffect) {
|
|
187
|
+
addToSearchString(`score-effect:${searchObjectArg.scoreEffect}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// analytics
|
|
191
|
+
if (searchObjectArg.qualityWeight) {
|
|
192
|
+
addToSearchString(`author:${searchObjectArg.qualityWeight}`);
|
|
193
|
+
}
|
|
194
|
+
if (searchObjectArg.popularityWeight) {
|
|
195
|
+
addToSearchString(`author:${searchObjectArg.popularityWeight}`);
|
|
196
|
+
}
|
|
197
|
+
if (searchObjectArg.maintenanceWeight) {
|
|
198
|
+
addToSearchString(`author:${searchObjectArg.maintenanceWeight}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log(
|
|
202
|
+
`info: Search on npm for ${plugins.consolecolor.coloredString(searchString, 'pink')}`
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
let body: any;
|
|
206
|
+
try {
|
|
207
|
+
const response = await plugins.smartrequest.getJson(this.searchDomain + searchString, {});
|
|
208
|
+
body = response.body;
|
|
209
|
+
} catch {
|
|
210
|
+
// we do nothing
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// lets create the packageArray
|
|
214
|
+
const packageArray: NpmPackage[] = [];
|
|
215
|
+
|
|
216
|
+
// if request failed just return it empty
|
|
217
|
+
if (!body || typeof body === 'string') {
|
|
218
|
+
return packageArray;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
for (const packageSearchInfoArg of body.results) {
|
|
222
|
+
const npmPackage = await this.getPackageInfo(packageSearchInfoArg.package.name);
|
|
223
|
+
packageArray.push(npmPackage);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return packageArray;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as plugins from './smartnpm.plugins.js';
|
|
2
|
+
|
|
3
|
+
export class PackageDisttag {
|
|
4
|
+
name: string;
|
|
5
|
+
targetVersion: string;
|
|
6
|
+
|
|
7
|
+
constructor(nameArg: string, targetVersionArg: string) {
|
|
8
|
+
this.name = nameArg;
|
|
9
|
+
this.targetVersion = targetVersionArg;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as plugins from './smartnpm.plugins.js';
|
|
2
|
+
|
|
3
|
+
export interface IVersionData {
|
|
4
|
+
name: string;
|
|
5
|
+
version: string;
|
|
6
|
+
dependencies: { [key: string]: string };
|
|
7
|
+
devDependencies: { [key: string]: string };
|
|
8
|
+
dist: {
|
|
9
|
+
integrity: string;
|
|
10
|
+
shasum: string;
|
|
11
|
+
tarball: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class PackageVersion implements IVersionData {
|
|
16
|
+
public static createFromVersionData(versionDataArg: IVersionData) {
|
|
17
|
+
const packageVersion = new PackageVersion();
|
|
18
|
+
Object.assign(packageVersion, versionDataArg);
|
|
19
|
+
return packageVersion;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
dependencies: { [key: string]: string };
|
|
25
|
+
devDependencies: { [key: string]: string };
|
|
26
|
+
dist: {
|
|
27
|
+
integrity: string;
|
|
28
|
+
shasum: string;
|
|
29
|
+
tarball: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { NpmRegistry } from './smartnpm.classes.npmregistry.js';
|
|
2
|
+
import * as plugins from './smartnpm.plugins.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export interface ICacheDescriptor {
|
|
6
|
+
registryUrl: string;
|
|
7
|
+
packageName: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
distTag?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class RegistryCache {
|
|
14
|
+
npmregistryRef: NpmRegistry;
|
|
15
|
+
public levelCache: plugins.levelcache.LevelCache;
|
|
16
|
+
|
|
17
|
+
constructor(npmRegistryRefArg: NpmRegistry) {
|
|
18
|
+
this.npmregistryRef = npmRegistryRefArg;
|
|
19
|
+
this.levelCache = new plugins.levelcache.LevelCache({
|
|
20
|
+
cacheId: encodeURIComponent(this.npmregistryRef.options.npmRegistryUrl),
|
|
21
|
+
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async getCachedFile (cacheDescriptorArg: ICacheDescriptor): Promise<plugins.smartfile.Smartfile> {
|
|
26
|
+
const cacheEntry = await this.levelCache.retrieveCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg));
|
|
27
|
+
if (cacheEntry) {
|
|
28
|
+
return plugins.smartfile.Smartfile.fromFoldedJson(cacheEntry.contents.toString());
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async cacheSmartFile (cacheDescriptorArg: ICacheDescriptor, smartfileArg: plugins.smartfile.Smartfile) {
|
|
34
|
+
if (smartfileArg && cacheDescriptorArg.version) {
|
|
35
|
+
await this.levelCache.storeCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg), new plugins.levelcache.CacheEntry({
|
|
36
|
+
contents: Buffer.from(smartfileArg.foldToJson()),
|
|
37
|
+
ttl: plugins.smarttime.getMilliSecondsFromUnits({hours: 1})
|
|
38
|
+
}));
|
|
39
|
+
} else {
|
|
40
|
+
await this.levelCache.storeCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg), new plugins.levelcache.CacheEntry({
|
|
41
|
+
contents: Buffer.from(smartfileArg.foldToJson()),
|
|
42
|
+
ttl: plugins.smarttime.getMilliSecondsFromUnits({minutes: 1})
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public getCacheDescriptorAsString(cacheDescriptorArg?: ICacheDescriptor) {
|
|
48
|
+
return `${cacheDescriptorArg.registryUrl}//+//${cacheDescriptorArg.packageName}//+//${cacheDescriptorArg.filePath}//+//${cacheDescriptorArg.distTag || cacheDescriptorArg.version}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ISearchObject {
|
|
2
|
+
// name
|
|
3
|
+
name?: string;
|
|
4
|
+
|
|
5
|
+
// metadata
|
|
6
|
+
author?: string;
|
|
7
|
+
maintainer?: string;
|
|
8
|
+
scope?: string;
|
|
9
|
+
keywords?: string[];
|
|
10
|
+
|
|
11
|
+
// status
|
|
12
|
+
deprecated?: boolean;
|
|
13
|
+
unstable?: boolean;
|
|
14
|
+
insecure?: boolean;
|
|
15
|
+
|
|
16
|
+
// search behaviour
|
|
17
|
+
boostExact?: boolean;
|
|
18
|
+
scoreEffect?: number;
|
|
19
|
+
|
|
20
|
+
// Analytics
|
|
21
|
+
qualityWeight?: number;
|
|
22
|
+
popularityWeight?: number;
|
|
23
|
+
maintenanceWeight?: number;
|
|
24
|
+
}
|