Compare commits

...

20 Commits

Author SHA1 Message Date
634d1c3570 1.0.36 2021-05-10 16:12:11 +00:00
cd8c9bcdaa fix(core): update 2021-05-10 16:12:11 +00:00
f6d3d0987b 1.0.35 2021-05-06 10:34:45 +00:00
60a1de38ce fix(core): update 2021-05-06 10:34:44 +00:00
0ef6d0ccb2 1.0.34 2021-05-06 10:22:15 +00:00
8e538fd84d 1.0.33 2021-05-06 10:05:50 +00:00
6745115db7 fix(core): update 2021-05-06 10:05:49 +00:00
5ebce389d3 1.0.32 2021-05-06 10:04:51 +00:00
b4100688ac fix(version matching): now respecting packages without latest tag 2021-05-06 10:04:51 +00:00
77d515d915 1.0.31 2021-05-05 12:37:27 +00:00
aa71105b2d 1.0.30 2021-05-05 11:56:12 +00:00
e0ccb6c076 fix(core): update 2021-05-05 11:56:12 +00:00
af0d95f327 1.0.29 2021-05-05 10:54:32 +00:00
d0ac8f1418 fix(core): update 2021-05-05 10:54:31 +00:00
62f8106fc6 1.0.28 2021-04-29 21:20:19 +00:00
e87b8c994b fix(core): update 2021-04-29 21:20:18 +00:00
694ba7be25 1.0.27 2021-04-29 20:44:47 +00:00
952399c26e fix(core): update 2021-04-29 20:44:47 +00:00
ab1e83b8bf 1.0.26 2021-04-29 17:02:40 +00:00
67980f9f41 fix(core): update 2021-04-29 17:02:39 +00:00
7 changed files with 2635 additions and 1746 deletions

4204
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartnpm", "name": "@pushrocks/smartnpm",
"version": "1.0.25", "version": "1.0.36",
"private": false, "private": false,
"description": "interface with npm to retrieve package information", "description": "interface with npm to retrieve package information",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@ -14,19 +14,20 @@
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.25", "@gitzone/tsbuild": "^2.1.25",
"@gitzone/tsrun": "^1.2.12", "@gitzone/tsrun": "^1.2.12",
"@gitzone/tstest": "^1.0.52", "@gitzone/tstest": "^1.0.54",
"@pushrocks/tapbundle": "^3.2.14", "@pushrocks/tapbundle": "^3.2.14",
"@types/node": "^14.14.41", "@types/node": "^15.0.2",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0" "tslint-config-prettier": "^1.18.0"
}, },
"dependencies": { "dependencies": {
"@pushrocks/consolecolor": "^2.0.1", "@pushrocks/consolecolor": "^2.0.1",
"@pushrocks/levelcache": "^1.0.9", "@pushrocks/levelcache": "^1.0.10",
"@pushrocks/smartarchive": "^2.0.4", "@pushrocks/smartarchive": "^2.0.4",
"@pushrocks/smartfile": "^8.0.10", "@pushrocks/smartfile": "^8.0.10",
"@pushrocks/smartpromise": "^3.1.5", "@pushrocks/smartpromise": "^3.1.5",
"@pushrocks/smartrequest": "^1.1.51", "@pushrocks/smartrequest": "^1.1.51",
"@pushrocks/smarttime": "^3.0.38",
"@pushrocks/smartversion": "^2.0.7", "@pushrocks/smartversion": "^2.0.7",
"package-json": "^6.5.0" "package-json": "^6.5.0"
}, },

View File

@ -32,16 +32,25 @@ tap.test('should create a verdaccio registry', async () => {
tap.test('should get package from verdaccio', async () => { tap.test('should get package from verdaccio', async () => {
const npmPackage = await verdaccioRegistry.getPackageInfo('@pushrocks/smartupdate'); const npmPackage = await verdaccioRegistry.getPackageInfo('@pushrocks/smartupdate');
console.log(npmPackage);
expect(npmPackage.license).to.equal('MIT'); expect(npmPackage.license).to.equal('MIT');
}); });
tap.test('should get a specific file from a package', async () => { tap.test('should get a specific file from a package', async () => {
const bundleFile = await verdaccioRegistry.getFileFromPackage( const wantedFile = await verdaccioRegistry.getFileFromPackage(
'@pushrocks/websetup', '@pushrocks/websetup',
'ts/index.ts' 'ts/index.ts'
); );
console.log(bundleFile.contentBuffer.toString()); console.log(wantedFile.contentBuffer.toString());
});
tap.test('should get a specific file from a package', async () => {
const wantedFiles = await verdaccioRegistry.getFilesFromPackage(
'@pushrocks/websetup',
'ts/'
);
for(const file of wantedFiles) {
console.log(file.path);
}
}); });
tap.start(); tap.start();

View File

@ -91,37 +91,37 @@ export class NpmPackage {
public async saveToCache() {} public async saveToCache() {}
/** /**
* get file from package * get files from package
*/ */
public async getFileFromPackage( public async getFilesFromPackage(
filePath: string, filePath: string,
optionsArg?: { optionsArg: {
distTag?: string; distTag?: string;
version?: string; version?: string;
} },
): Promise<plugins.smartfile.Smartfile> { returnOnFirstArg = false
const done = plugins.smartpromise.defer<plugins.smartfile.Smartfile>(); ): Promise<plugins.smartfile.Smartfile[]> {
const done = plugins.smartpromise.defer<plugins.smartfile.Smartfile[]>();
const smartarchiveInstance = new plugins.smartarchive.SmartArchive(); const smartarchiveInstance = new plugins.smartarchive.SmartArchive();
let tarballUrl = this.dist.tarball; let tarballUrl = this.dist?.tarball;
if (optionsArg && (optionsArg.version || optionsArg.distTag)) { if (optionsArg?.version || optionsArg?.distTag) {
if (optionsArg.distTag && optionsArg.version) { if (optionsArg.distTag && optionsArg.version) {
throw new Error('Please either sepcify version OR disttag, not both.'); throw new Error('Please either specify version OR disttag, not both.');
} }
let targetVersion: plugins.smartversion.SmartVersion; let targetVersionString: string;
if (optionsArg.distTag) { if (optionsArg.distTag) {
const targetDistTag = this.allDistTags.find((distTag) => { const targetDistTag = this.allDistTags.find((distTag) => {
return distTag.name === optionsArg.distTag; return distTag.name === optionsArg.distTag;
}); });
if (targetDistTag) { if (targetDistTag) {
targetVersion = new plugins.smartversion.SmartVersion(targetDistTag.targetVersion); targetVersionString = targetDistTag.targetVersion;
} }
} else { } else {
const smartversion = plugins.smartversion.SmartVersion.fromFuzzyString(optionsArg.version); targetVersionString = optionsArg.version;
} }
// lets find the best matching release // lets find the best matching release
const versionStrings = this.allVersions.map((packageVersion) => packageVersion.version); const bestMatchingVersion = this.getBestMatchingVersion(targetVersionString);
const bestMatchingVersion = targetVersion.getBestMatch(versionStrings);
if (!bestMatchingVersion) { if (!bestMatchingVersion) {
return null; return null;
} }
@ -131,29 +131,57 @@ export class NpmPackage {
} }
const fileObservable = await smartarchiveInstance.extractArchiveFromUrlToObservable(tarballUrl); const fileObservable = await smartarchiveInstance.extractArchiveFromUrlToObservable(tarballUrl);
const wantedFilePath = plugins.path.join('package', filePath); const wantedFilePath = plugins.path.join('package', filePath);
const allMatchingFiles: plugins.smartfile.Smartfile[] = [];
const subscription = fileObservable.subscribe( const subscription = fileObservable.subscribe(
(fileArg) => { (fileArg) => {
if (fileArg.path === wantedFilePath) { // returnOnFirstArg requires exact match
// lets care about caching if (returnOnFirstArg && fileArg.path === wantedFilePath) {
// lets resolve with the wanted file // lets resolve with the wanted file
done.resolve(fileArg); done.resolve([fileArg]);
subscription.unsubscribe(); subscription.unsubscribe();
} else if(!returnOnFirstArg && fileArg.path.startsWith(wantedFilePath)) {
allMatchingFiles.push(fileArg);
} }
}, },
(err) => { (err) => {
console.log(err); console.log(err);
}, },
() => { () => {
done.resolve(null); done.resolve(allMatchingFiles);
subscription.unsubscribe(); subscription.unsubscribe();
} }
); );
return done.promise; return done.promise;
} }
/**
* get files from package
*/
public async getFileFromPackage(
filePath: string,
optionsArg?: {
distTag?: string;
version?: string;
}
): Promise<plugins.smartfile.Smartfile> {
const result = await this.getFilesFromPackage(filePath, optionsArg, true);
return result[0];
}
/** /**
* updates the package with information from the registry * updates the package with information from the registry
*/ */
update() {} update() {}
/** */
public getBestMatchingVersion(versionArg: string): string {
// lets find the best matching release
const targetVersion = plugins.smartversion.SmartVersion.fromFuzzyString(versionArg);
const versionStrings = this.allVersions.map((packageVersion) => packageVersion.version);
const bestMatchingVersion = targetVersion.getBestMatch(versionStrings);
if (!bestMatchingVersion) {
return null;
}
return bestMatchingVersion;
}
} }

View File

@ -6,7 +6,7 @@ import { ISearchObject } from './smartnpm.interfaces';
// classes // classes
import { NpmPackage } from './smartnpm.classes.npmpackage'; import { NpmPackage } from './smartnpm.classes.npmpackage';
import { RegistryCache } from './smartnpm.classes.registrycache'; import { ICacheDescriptor, RegistryCache } from './smartnpm.classes.registrycache';
export interface INpmRegistryConstructorOptions { export interface INpmRegistryConstructorOptions {
npmRegistryUrl?: string; npmRegistryUrl?: string;
@ -36,6 +36,9 @@ export class NpmRegistry {
const fullMetadata = await plugins.packageJson(packageName, { const fullMetadata = await plugins.packageJson(packageName, {
registryUrl: this.options.npmRegistryUrl, registryUrl: this.options.npmRegistryUrl,
fullMetadata: true, fullMetadata: true,
}).catch(err => {
console.log(err);
return null;
}); });
const versionData = await plugins.packageJson(packageName, { const versionData = await plugins.packageJson(packageName, {
registryUrl: this.options.npmRegistryUrl, registryUrl: this.options.npmRegistryUrl,
@ -59,22 +62,57 @@ export class NpmRegistry {
/** /**
* gets a file from a package as Smartfile * gets a file from a package as Smartfile
*/ */
public async getFileFromPackage(packageNameArg: string, filePath: string, optionsArg?: { public async getFileFromPackage(packageNameArg: string, filePathArg: string, optionsArg?: {
distTag?: string; distTag?: string;
version?: string; version?: string;
}): Promise<plugins.smartfile.Smartfile> { }): Promise<plugins.smartfile.Smartfile> {
const fileId = `${this.options.npmRegistryUrl}//+//${packageNameArg}//+//${filePath}//+//${optionsArg?.distTag || optionsArg?.version}`; // lets create a cache descriptor
const cachedFile: plugins.smartfile.Smartfile = await this.registryCache.getCachedFile(fileId); const cacheDescriptor: ICacheDescriptor = {
registryUrl: this.options.npmRegistryUrl,
packageName: packageNameArg,
filePath: filePathArg,
distTag: optionsArg?.distTag,
version: optionsArg?.version
};
// lets see if we have something cached
const cachedFile: plugins.smartfile.Smartfile = await this.registryCache.getCachedFile(cacheDescriptor);
// lets handle both occasions
if (!cachedFile) { if (!cachedFile) {
const npmPackage = await this.getPackageInfo(packageNameArg); const npmPackage = await this.getPackageInfo(packageNameArg);
const fileResult = await npmPackage.getFileFromPackage(filePath, optionsArg); if (!optionsArg?.version && !optionsArg?.distTag) {
this.registryCache.cacheSmartFile(fileId, fileResult); const latestAvailable = npmPackage.allDistTags.find(packageArg => packageArg.name === 'latest');
if (!latestAvailable) {
optionsArg = {
version: npmPackage.getBestMatchingVersion('*')
};
}
}
const fileResult = await npmPackage.getFileFromPackage(filePathArg, optionsArg);
this.registryCache.cacheSmartFile(cacheDescriptor, fileResult);
return fileResult; return fileResult;
} else { } else {
return cachedFile; return cachedFile;
} }
} }
public async getFilesFromPackage(packageNameArg: string, filePath: string, optionsArg?: {
distTag?: string;
version?: string;
}): Promise<plugins.smartfile.Smartfile[]> {
const npmPackage = await this.getPackageInfo(packageNameArg);
if (!optionsArg?.version && !optionsArg?.distTag) {
const latestAvailable = npmPackage.allDistTags.find(packageDistTagArg => packageDistTagArg.name === 'latest');
if (!latestAvailable) {
optionsArg = {
version: npmPackage.getBestMatchingVersion('*')
};
}
}
return npmPackage.getFilesFromPackage(filePath, optionsArg);
}
public async getPackageAsSmartfileVirtualDir(packageNameArg: string): Promise<plugins.smartfile.VirtualDirectory> { public async getPackageAsSmartfileVirtualDir(packageNameArg: string): Promise<plugins.smartfile.VirtualDirectory> {
/** /**
* TODO: rewrite as memory only * TODO: rewrite as memory only

View File

@ -1,6 +1,15 @@
import { NpmRegistry } from './smartnpm.classes.npmregistry'; import { NpmRegistry } from './smartnpm.classes.npmregistry';
import * as plugins from './smartnpm.plugins'; import * as plugins from './smartnpm.plugins';
export interface ICacheDescriptor {
registryUrl: string;
packageName: string;
filePath: string;
distTag?: string;
version?: string;
}
export class RegistryCache { export class RegistryCache {
npmregistryRef: NpmRegistry; npmregistryRef: NpmRegistry;
public levelCache: plugins.levelcache.LevelCache; public levelCache: plugins.levelcache.LevelCache;
@ -13,18 +22,29 @@ export class RegistryCache {
}); });
} }
public async getCachedFile (fileId: string): Promise<plugins.smartfile.Smartfile> { public async getCachedFile (cacheDescriptorArg: ICacheDescriptor): Promise<plugins.smartfile.Smartfile> {
const cacheEntry = await this.levelCache.retrieveCacheEntryByKey(fileId); const cacheEntry = await this.levelCache.retrieveCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg));
if (cacheEntry) { if (cacheEntry) {
return plugins.smartfile.Smartfile.fromFoldedJson(cacheEntry.contents.toString()); return plugins.smartfile.Smartfile.fromFoldedJson(cacheEntry.contents.toString());
} }
return null; return null;
} }
public async cacheSmartFile (fileIdArg: string, smartfileArg: plugins.smartfile.Smartfile) { public async cacheSmartFile (cacheDescriptorArg: ICacheDescriptor, smartfileArg: plugins.smartfile.Smartfile) {
await this.levelCache.storeCacheEntryByKey(fileIdArg, new plugins.levelcache.CacheEntry({ if (smartfileArg && cacheDescriptorArg.version) {
contents: Buffer.from(smartfileArg.foldToJson()), await this.levelCache.storeCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg), new plugins.levelcache.CacheEntry({
ttl: 60000 contents: Buffer.from(smartfileArg.foldToJson()),
})); ttl: plugins.smarttime.getMilliSecondsFromUnits({hours: 1})
}));
} else {
await this.levelCache.storeCacheEntryByKey(this.getCacheDescriptorAsString(cacheDescriptorArg), new plugins.levelcache.CacheEntry({
contents: Buffer.from(smartfileArg.foldToJson()),
ttl: plugins.smarttime.getMilliSecondsFromUnits({minutes: 1})
}));
}
}
public getCacheDescriptorAsString(cacheDescriptorArg?: ICacheDescriptor) {
return `${cacheDescriptorArg.registryUrl}//+//${cacheDescriptorArg.packageName}//+//${cacheDescriptorArg.filePath}//+//${cacheDescriptorArg.distTag || cacheDescriptorArg.version}`;
} }
} }

View File

@ -11,8 +11,9 @@ import * as smartfile from '@pushrocks/smartfile';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartpromise from '@pushrocks/smartpromise';
import * as smartrequest from '@pushrocks/smartrequest'; import * as smartrequest from '@pushrocks/smartrequest';
import * as smartversion from '@pushrocks/smartversion'; import * as smartversion from '@pushrocks/smartversion';
import * as smarttime from '@pushrocks/smarttime';
export { consolecolor, levelcache, smartarchive, smartfile, smartpromise, smartrequest, smartversion }; export { consolecolor, levelcache, smartarchive, smartfile, smartpromise, smartrequest, smartversion, smarttime };
// third party scope // third party scope
import packageJson from 'package-json'; import packageJson from 'package-json';