Files
cnpmcore/test/core/service/PackageSyncerService/executeTask.test.ts
fengmk2 4427a4fca5 feat: use egg v4 (#747)
BREAKING CHANGE: only support egg >= 4.0.0

the first app on egg v4

https://github.com/eggjs/egg/issues/3644
2025-02-09 15:43:24 +08:00

2643 lines
172 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { strict as assert } from 'node:assert';
import { app, mock } from '@eggjs/mock/bootstrap';
import { TestUtil } from '../../../../test/TestUtil';
import { PackageSyncerService } from '../../../../app/core/service/PackageSyncerService';
import { PackageManagerService } from '../../../../app/core/service/PackageManagerService';
import { Package as PackageModel } from '../../../../app/repository/model/Package';
import { Task as TaskModel } from '../../../../app/repository/model/Task';
import { Task as TaskEntity } from '../../../../app/core/entity/Task';
import { HistoryTask as HistoryTaskModel } from '../../../../app/repository/model/HistoryTask';
import { NPMRegistry } from '../../../../app/common/adapter/NPMRegistry';
import { NFSAdapter } from '../../../../app/common/adapter/NFSAdapter';
import { getScopeAndName } from '../../../../app/common/PackageUtil';
import { PackageRepository } from '../../../../app/repository/PackageRepository';
import { RegistryManagerService } from '../../../../app/core/service/RegistryManagerService';
import { Registry } from '../../../../app/core/entity/Registry';
import { RegistryType } from '../../../../app/common/enum/Registry';
import { TaskService } from '../../../../app/core/service/TaskService';
import { ScopeManagerService } from '../../../../app/core/service/ScopeManagerService';
import { UserService } from '../../../../app/core/service/UserService';
import { ChangeRepository } from '../../../../app/repository/ChangeRepository';
import { PackageVersion } from '../../../../app/repository/model/PackageVersion';
import { TaskState } from '../../../../app/common/enum/Task';
describe('test/core/service/PackageSyncerService/executeTask.test.ts', () => {
let packageSyncerService: PackageSyncerService;
let packageManagerService: PackageManagerService;
let packageRepository: PackageRepository;
let npmRegistry: NPMRegistry;
let registryManagerService: RegistryManagerService;
let taskService: TaskService;
let scopeManagerService: ScopeManagerService;
let userService: UserService;
let changeRepository: ChangeRepository;
beforeEach(async () => {
packageSyncerService = await app.getEggObject(PackageSyncerService);
packageManagerService = await app.getEggObject(PackageManagerService);
packageRepository = await app.getEggObject(PackageRepository);
npmRegistry = await app.getEggObject(NPMRegistry);
taskService = await app.getEggObject(TaskService);
registryManagerService = await app.getEggObject(RegistryManagerService);
scopeManagerService = await app.getEggObject(ScopeManagerService);
userService = await app.getEggObject(UserService);
changeRepository = await app.getEggObject(ChangeRepository);
});
describe('executeTask()', () => {
it('should execute "foobar" task', async () => {
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json'),
persist: false,
repeats: 2,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz'),
persist: false,
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foobar' });
assert.equal(model!.isPrivate, false);
assert(log.includes(', skipDependencies: true'));
// sync again
await packageSyncerService.createTask('foobar');
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const manifests = await packageManagerService.listPackageFullManifests('', 'foobar');
// console.log(JSON.stringify(manifests, null, 2));
// should have 2 maintainers
assert(manifests.data!.maintainers.length >= 1);
const abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', 'foobar');
// console.log(JSON.stringify(abbreviatedManifests, null, 2));
assert.equal(abbreviatedManifests.data!.name, manifests.data!.name);
app.mockAgent().assertNoPendingInterceptors();
});
it('should resync history version if forceSyncHistory is true', async () => {
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json'),
persist: false,
repeats: 2,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
repeats: 2,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz'),
persist: false,
repeats: 2,
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
await packageSyncerService.createTask('foobar', { forceSyncHistory: true, skipDependencies: true });
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream2 = await packageSyncerService.findTaskLog(task);
assert(stream2);
const log2 = await TestUtil.readStreamToLog(stream2);
// console.log(log2);
assert(/Remove version 1\.0\.0 for force sync history/.test(log2));
assert(/Syncing version 1\.0\.0/.test(log2));
app.mockAgent().assertNoPendingInterceptors();
});
it('should not sync dependencies where task queue length too high', async () => {
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'taskQueueHighWaterSize', 2);
await packageSyncerService.createTask('foobar', { skipDependencies: false });
await packageSyncerService.createTask('foo', { skipDependencies: false });
await packageSyncerService.createTask('bar', { skipDependencies: false });
await packageSyncerService.createTask('foobarfoo', { skipDependencies: false });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, 'foobar');
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foobar' });
assert.equal(model!.isPrivate, false);
assert(log.includes(', taskQueue: 3/2'));
assert(log.includes(', skipDependencies: true'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should execute @node-rs/xxhash task, contains optionalDependencies', async () => {
app.mockHttpclient('https://registry.npmjs.org/%40node-rs%2Fxxhash', 'GET', {
data: '{"_id":"@node-rs/xxhash","_rev":"12-c16041461d207648f8785b03ff497026","name":"@node-rs/xxhash","dist-tags":{"latest":"1.2.1","depracated":"1.1.2"},"versions":{"1.0.0":{"name":"@node-rs/xxhash","version":"1.0.0","description":"Fastest xxhash implementation in Node.js","keywords":["hash","xxhash","xxhashjs","Rust","node-rs","napi","napi-rs","N-API","Node-API"],"author":{"name":"LongYinan","email":"lynweklm@gmail.com"},"homepage":"https://github.com/napi-rs/node-rs","license":"MIT","main":"index.js","typings":"index.d.ts","napi":{"name":"xxhash","triples":{"defaults":true,"additional":["i686-pc-windows-msvc","x86_64-unknown-linux-musl","aarch64-unknown-linux-gnu","armv7-unknown-linux-gnueabihf","aarch64-apple-darwin","aarch64-linux-android","x86_64-unknown-freebsd","aarch64-unknown-linux-musl","aarch64-pc-windows-msvc"]}},"engines":{"node":">= 12"},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"repository":{"type":"git","url":"git+https://github.com/napi-rs/node-rs.git"},"scripts":{"artifacts":"napi artifacts -d ../../artifacts","bench":"cross-env NODE_ENV=production node benchmark/xxhash.js","build":"napi build --platform --release","build:debug":"napi build --platform","prepublishOnly":"napi prepublish","version":"napi version"},"dependencies":{"@node-rs/helper":"^1.2.1","@node-rs/xxhash-win32-x64-msvc":"1.0.0","@node-rs/xxhash-darwin-x64":"1.0.0","@node-rs/xxhash-linux-x64-gnu":"1.0.0","@node-rs/xxhash-win32-ia32-msvc":"1.0.0","@node-rs/xxhash-linux-x64-musl":"1.0.0","@node-rs/xxhash-linux-arm64-gnu":"1.0.0","@node-rs/xxhash-linux-arm-gnueabihf":"1.0.0","@node-rs/xxhash-darwin-arm64":"1.0.0","@node-rs/xxhash-android-arm64":"1.0.0","@node-rs/xxhash-freebsd-x64":"1.0.0","@node-rs/xxhash-linux-arm64-musl":"1.0.0","@node-rs/xxhash-win32-arm64-msvc":"1.0.0"},"devDependencies":{"@types/xxhashjs":"^0.2.2","webpack":"^5.59.1","xxhash":"^0.3.0","xxhashjs":"^0.2.2"},"funding":{"type":"github","url":"https://github.com/sponsors/Brooooooklyn"},"gitHead":"dd157413b2c918c5d29c0d47071606bfabbddb64","optionalDependencies":{"@node-rs/xxhash-win32-x64-msvc":"1.0.0","@node-rs/xxhash-darwin-x64":"1.0.0","@node-rs/xxhash-linux-x64-gnu":"1.0.0","@node-rs/xxhash-win32-ia32-msvc":"1.0.0","@node-rs/xxhash-linux-x64-musl":"1.0.0","@node-rs/xxhash-linux-arm64-gnu":"1.0.0","@node-rs/xxhash-linux-arm-gnueabihf":"1.0.0","@node-rs/xxhash-darwin-arm64":"1.0.0","@node-rs/xxhash-android-arm64":"1.0.0","@node-rs/xxhash-freebsd-x64":"1.0.0","@node-rs/xxhash-linux-arm64-musl":"1.0.0","@node-rs/xxhash-win32-arm64-msvc":"1.0.0"},"_id":"@node-rs/xxhash@1.0.0","_nodeVersion":"14.18.1","_npmVersion":"lerna/4.0.0/node@v14.18.1+x64 (linux)","dist":{"integrity":"sha512-wVhbJT3QumfE7zlMLAZoAllaUufN5r3ia8vatKaqcG/Bau9SdFmcZpo8IuWDfSX+Jqyh9dViSRpUYChrVUvyFw==","shasum":"8c9a8c3be47b82de1a5cb42b2d38f652520bf73c","tarball":"https://registry.npmjs.org/@node-rs/xxhash/-/xxhash-1.0.0.tgz","fileCount":5,"unpackedSize":10143,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+Dksaw6q6YpTDITfpfAwI15qCuQT84NvQKOpMqq4ZdQIgHvVlZ7+kJk4gzGM7hD10eILXlpOfqQa6Z6NZtcOvX+M="}]},"_npmUser":{"name":"broooooklyn","email":"lynweklm@gmail.com"},"directories":{},"maintainers":[{"name":"broooooklyn","email":"lynweklm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/xxhash_1.0.0_1634889276349_0.690262990489863"},"_hasShrinkwrap":false}},"time":{"created":"2021-10-22T07:54:36.303Z","1.0.0":"2021-10-22T07:54:36.493Z","modified":"2022-05-14T10:40:20.461Z"},"maintainers":[{"name":"dxd_sjtu","email":"dxd_sjtu@outlook.com"},{"name":"broooooklyn","email":"lynweklm@gmail.com"}],"description":"Fastest xxhash implementation in Node.js","homepage":"https://github.com/napi-rs/node-rs","keywords":["hash","xxhash","xxhashjs","Rust","node-rs","napi","napi-rs","N-API","Node-API"],"repository":{"type":"git","url":"git+https://github.com/napi-rs/node-rs.git"},"author":{"name":"LongYinan","email":"lynweklm@gmail.com"},"bugs":{"url":"https://github.com/napi-rs/node-rs/issues"},"license":"MIT","readme":"mock readme","readmeFilename":"README.md"}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@node-rs/xxhash/-/xxhash-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
await packageSyncerService.createTask('@node-rs/xxhash');
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const manifests = await packageManagerService.listPackageFullManifests('@node-rs', 'xxhash');
// console.log(JSON.stringify(manifests, null, 2));
// assert.equal(manifests.data.maintainers.length, 2);
const abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('@node-rs', 'xxhash');
// console.log(JSON.stringify(abbreviatedManifests, null, 2));
assert.equal(abbreviatedManifests.data!.name, manifests.data!.name);
assert(abbreviatedManifests.data!.versions['1.0.0']);
assert(abbreviatedManifests.data!.versions['1.0.0'].optionalDependencies);
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync cnpmcore-test-sync-deprecated and mock 451', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data);
assert(manifests!.data!.versions['0.0.0']);
assert.equal(manifests.data.versions['0.0.0'].deprecated, 'only test for cnpmcore');
assert.equal(manifests.data.versions['0.0.0']._hasShrinkwrap, false);
let abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert.equal(abbreviatedManifests!.data!.versions['0.0.0']!.deprecated, 'only test for cnpmcore');
assert.equal(abbreviatedManifests!.data!.versions['0.0.0']!._hasShrinkwrap, false);
app.mockAgent().assertNoPendingInterceptors();
// mock 451 and unpublished
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
status: 451,
data: '{"error":"Not found"}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data);
assert(manifests.data.time.unpublished);
abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert(abbreviatedManifests.data!.time!.unpublished);
app.mockAgent().assertNoPendingInterceptors();
// sync again
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
manifests = await packageManagerService.listPackageFullManifests('', name);
assert(!manifests.data!.time.unpublished);
assert.equal(manifests.data!.versions['0.0.0']!.deprecated, 'only test for cnpmcore');
assert.equal(manifests.data!.versions['0.0.0']!._hasShrinkwrap, false);
abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert(!abbreviatedManifests.data!.time?.unpublished);
assert.equal(abbreviatedManifests.data!.versions['0.0.0']!.deprecated, 'only test for cnpmcore');
assert.equal(abbreviatedManifests.data!.versions['0.0.0']!._hasShrinkwrap, false);
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync cnpmcore-test-sync-deprecated and ignore 404 in removed', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data);
assert(manifests!.data!.versions['0.0.0']);
assert.equal(manifests.data.versions['0.0.0'].deprecated, 'only test for cnpmcore');
assert.equal(manifests.data.versions['0.0.0']._hasShrinkwrap, false);
const abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert.equal(abbreviatedManifests!.data!.versions['0.0.0']!.deprecated, 'only test for cnpmcore');
assert.equal(abbreviatedManifests!.data!.versions['0.0.0']!._hasShrinkwrap, false);
app.mockAgent().assertNoPendingInterceptors();
// mock 404 and no unpublished
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
status: 404,
data: '{"error":"Not found"}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
assert(log.includes('Package not found, status 404'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync fail when package not exists', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-package-not-exists', 'GET', {
status: 404,
data: '{"error":"Not found"}',
persist: false,
});
const name = 'cnpmcore-test-sync-package-not-exists';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Package not found, status 404'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore PositionNotEqualToLength error', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org//foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const err = {
name: 'PositionNotEqualToLengthError',
message: 'Position is not equal to file length',
code: 'PositionNotEqualToLength',
status: '409',
};
mock.error(NFSAdapter.prototype, 'appendBytes', err);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🔗'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore ObjectNotAppendable error', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const err = {
name: 'ObjectNotAppendableError',
message: 'The object is not appendable',
code: 'ObjectNotAppendable',
status: '409',
};
mock.error(NFSAdapter.prototype, 'appendBytes', err);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🔗'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync cnpmcore-test-sync-dependencies => cnpmcore-test-sync-deprecated', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-dependencies.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies/-/cnpmcore-test-sync-dependencies-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
let name = 'cnpmcore-test-sync-dependencies';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 📦 Add dependency "cnpmcore-test-sync-deprecated" sync task: '));
// will sync cnpmcore-test-sync-deprecated
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Sync cause by "cnpmcore-test-sync-dependencies" dependencies, parent task: '));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync cnpmcore-test-sync-dependencies => cnpmcore-test-sync-deprecated and not add dependencies', async () => {
let name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-dependencies.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies/-/cnpmcore-test-sync-dependencies-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
name = 'cnpmcore-test-sync-dependencies';
const task = await packageSyncerService.createTask(name);
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('] 📦 Add dependency "cnpmcore-test-sync-deprecated" sync task: '));
assert(log.includes('] 📖 Has dependency "cnpmcore-test-sync-deprecated" sync task: '));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync package optionalDependencies', async () => {
const name = 'resvg-js';
const task = await packageSyncerService.createTask(name);
app.mockHttpclient('https://registry.npmjs.org/resvg-js', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/resvg-js.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/resvg-js/-/resvg-js-2.4.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
app.mockAgent().assertNoPendingInterceptors();
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 📦 Add dependency "@resvg/resvg-js-win32-x64-msvc" sync task: '));
});
it('should bring auth token which in registry database.', async () => {
const testToken = 'test-auth-token';
const registry = await registryManagerService.ensureDefaultRegistry();
await registryManagerService.updateRegistry(registry.registryId, { ...registry, authToken: testToken });
const fullManifests = await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json');
const tgzBuffer1_0_0 = await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz');
const tgzBuffer1_1_0 = await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz');
let fullManifestsHeader;
let tgzBuffer1_0_0Header;
let tgzBuffer1_1_0Header;
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', (_, opts) => {
fullManifestsHeader = opts.headers;
return {
data: fullManifests,
persist: false,
repeats: 2,
};
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', (_, opts) => {
tgzBuffer1_0_0Header = opts.headers;
return {
data: tgzBuffer1_0_0,
persist: false,
};
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', (_, opts) => {
tgzBuffer1_1_0Header = opts.headers;
return {
data: tgzBuffer1_1_0,
persist: false,
};
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert.equal(fullManifestsHeader?.authorization, `Bearer ${testToken}`);
assert.equal(tgzBuffer1_0_0Header?.authorization, `Bearer ${testToken}`);
assert.equal(tgzBuffer1_1_0Header?.authorization, `Bearer ${testToken}`);
});
it('should ignore publish error on sync task', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
mock.error(packageManagerService.constructor.prototype, 'publish');
const task = await packageSyncerService.createTask(name);
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('❌ [1] Synced version 0.0.0 error, publish error: MockError: mm mock error'));
assert(log.includes('❌ All versions sync fail, package not exists'));
const res = await app.httpRequest()
.get(`/-/package/${name}/syncs/${task.taskId}`)
.expect(200);
assert.equal(res.body.state, 'fail');
assert.equal(res.body.error, 'publish error: MockError: mm mock error');
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore when all version publish ForbiddenError', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
const err = new Error('mock ForbiddenError');
err.name = 'ForbiddenError';
mock.error(packageManagerService.constructor.prototype, 'publish', err);
const task = await packageSyncerService.createTask(name);
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('🐛 [1] Synced version 0.0.0 already exists, skip publish, try to set in local manifest'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore download error error on sync task', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
status: 500,
data: 'mock request error',
persist: false,
repeats: 3,
});
const name = 'cnpmcore-test-sync-deprecated';
const task = await packageSyncerService.createTask(name);
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
app.mockAgent().assertNoPendingInterceptors();
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('❌ [1] Synced version 0.0.0 fail, download tarball error: DownloadStatusInvalidError: Download https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz status(500) invalid'));
assert(log.includes('❌ All versions sync fail, package not exists'));
});
describe('sync version idempotence', async () => {
beforeEach(async () => {
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
repeats: 2,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
});
it('should sync 2 versions package: @cnpmcore/test-sync-package-has-two-versions', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🟢 Synced updated 2 versions, removed 0 versions'));
assert(log.includes('] 🚧 Syncing versions 0 => 2'));
// mock listPackageFullManifests return only one version
// 如果 version publish 同步中断了,没有刷新 manifests会导致下一次同步重新 version publish然后报错
// Avoid: Can't modify pre-existing version: 1.0.0
const scopedAndName = getScopeAndName(name);
const manifests = await packageManagerService.listPackageFullManifests(scopedAndName[0], scopedAndName[1]);
assert(manifests.data);
delete manifests.data.versions['1.0.0'];
mock.data(PackageManagerService.prototype, 'listPackageFullManifests', manifests);
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Synced version 1.0.0 already exists, skip publish, try to set in local manifest'));
assert(log.includes('] 🟢 Synced updated'));
assert(log.includes('] 🚧 Syncing versions 1 => 2'));
app.mockAgent().assertNoPendingInterceptors();
await mock.restore();
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
const abbrs = await packageManagerService.listPackageAbbreviatedManifests(scopedAndName[0], scopedAndName[1]);
assert(abbrs.data);
delete abbrs.data.versions['1.0.0'];
mock.data(PackageManagerService.prototype, 'listPackageAbbreviatedManifests', abbrs);
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🐛 Remote version 1.0.0 not exists on local abbreviated manifests, need to refresh'));
assert(log.includes('] 🟢 Synced updated'));
assert(log.includes('] 🚧 Syncing versions 2 => 2'));
app.mockAgent().assertNoPendingInterceptors();
await mock.restore();
// mock tag on database but not on manifest dist
// https://github.com/cnpm/cnpmcore/issues/97
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
const result = await npmRegistry.getFullManifests(name);
const latestVersion = result.data['dist-tags'].latest;
result.data['dist-tags'].foo = '2.0.0';
mock.data(NPMRegistry.prototype, 'getFullManifests', result);
mock.data(PackageManagerService.prototype, 'savePackageTag', null);
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🚧 Remote tag(foo: 2.0.0) not exists in local dist-tags'));
assert(!log.includes('] 🚧 Refreshing manifests to dists ......'));
assert(log.includes('] 🚧 Syncing versions 2 => 2'));
assert(log.includes(`] 📖 @cnpmcore/test-sync-package-has-two-versions latest version: ${latestVersion}, published time: ${JSON.stringify(result.data.time[latestVersion])}`));
app.mockAgent().assertNoPendingInterceptors();
});
it('should updated package manifests when version already published', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
const { user } = await userService.create({
name: 'test-user',
password: 'this-is-password',
email: 'hello@example.com',
ip: '127.0.0.1',
});
const publishCmd = {
scope: '@cnpmcore',
name: 'test-sync-package-has-two-versions',
version: '1.0.0',
description: '1.0.0',
readme: '',
registryId: undefined,
packageJson: { name, test: 'test', version: '1.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: false,
};
const pkgVersion = await packageManagerService.publish(publishCmd, user);
assert(pkgVersion.version === '1.0.0');
const publishCmd2 = {
scope: '@cnpmcore',
name: 'test-sync-package-has-two-versions',
version: '2.0.0',
description: '2.0.0',
readme: '',
registryId: undefined,
packageJson: { name, test: 'test', version: '2.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: true,
};
const pkgVersion2 = await packageManagerService.publish(publishCmd2, user);
assert(pkgVersion2.version === '2.0.0');
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Synced version 2.0.0 already exists, skip publish, try to set in local manifest'));
assert(log.includes('] 🚧 Syncing versions 1 => 2'));
const fullManifests = await packageManagerService.listPackageFullManifests('@cnpmcore', 'test-sync-package-has-two-versions');
assert(fullManifests.data);
assert(fullManifests.data.versions['2.0.0']);
});
it('should skip self registry', async () => {
const name = '@cnpmcore/test-self-sync';
const { user } = await userService.create({
name: 'test-user',
password: 'this-is-password',
email: 'hello@example.com',
ip: '127.0.0.1',
});
const registry = await registryManagerService.ensureSelfRegistry();
const publishCmd = {
scope: '@cnpmcore',
name: 'test-self-sync',
version: '1.0.0',
description: '1.0.0',
readme: '',
registryId: registry.registryId,
packageJson: { name, test: 'test', version: '1.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: false,
};
const pkgVersion = await packageManagerService.publish(publishCmd, user);
assert(pkgVersion.version === '1.0.0');
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`${name} has been published to the self registry, skip sync ❌❌❌❌❌`));
});
it('should updated package manifests when version insert duplicated', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
const { user } = await userService.create({
name: 'test-user',
password: 'this-is-password',
email: 'hello@example.com',
ip: '127.0.0.1',
});
const publishCmd = {
scope: '@cnpmcore',
name: 'test-sync-package-has-two-versions',
version: '1.0.0',
description: '1.0.0',
readme: '',
registryId: undefined,
packageJson: { name, test: 'test', version: '1.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: false,
};
const pkgVersion = await packageManagerService.publish(publishCmd, user);
assert(pkgVersion.version === '1.0.0');
const publishCmd2 = {
scope: '@cnpmcore',
name: 'test-sync-package-has-two-versions',
version: '2.0.0',
description: '2.0.0',
readme: '',
registryId: undefined,
packageJson: { name, test: 'test', version: '2.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: true,
};
const pkgVersion2 = await packageManagerService.publish(publishCmd2, user);
assert(pkgVersion2.version === '2.0.0');
// 模拟查询未发现版本重复,写入时异常
mock(packageRepository, 'findPackageVersion', async () => {
return null;
});
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Synced version 2.0.0 already exists, skip publish, try to set in local manifest'));
assert(log.includes('] 🚧 Syncing versions 1 => 2'));
});
it('should skip version when insert error', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
const { user } = await userService.create({
name: 'test-user',
password: 'this-is-password',
email: 'hello@example.com',
ip: '127.0.0.1',
});
const publishCmd = {
scope: '@cnpmcore',
name: 'test-sync-package-has-two-versions',
version: '1.0.0',
description: '1.0.0',
readme: '',
registryId: undefined,
packageJson: { name, test: 'test', version: '1.0.0' },
dist: {
content: Buffer.alloc(0),
},
isPrivate: false,
publishTime: new Date(),
skipRefreshPackageManifests: false,
};
const pkgVersion = await packageManagerService.publish(publishCmd, user);
assert(pkgVersion.version === '1.0.0');
// 模拟查询未发现版本重复,写入时异常
mock(packageRepository, 'findPackageVersion', async () => {
return null;
});
mock(packageRepository, 'createPackageVersion', async () => {
throw new Error('mock error');
});
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes(' Synced updated 0 versions, removed 0 versions'));
});
it('event cork should work', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const finishedTask = await taskService.findTask(task.taskId) as TaskEntity;
const changes = await changeRepository.query(0, 100);
const [ firstChange ] = changes;
const firstChangeDate = new Date(firstChange.createdAt);
const taskFinishedDate = new Date(finishedTask!.updatedAt);
// 任务结束后一起触发
assert(firstChangeDate.getTime() - taskFinishedDate.getTime() > 0);
});
it('should bulk update maintainer dist', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
let called = 0;
mock(packageManagerService, 'refreshPackageMaintainersToDists', async () => {
called++;
});
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const finishedTask = await taskService.findTask(task.taskId) as TaskEntity;
assert.equal(finishedTask.state, TaskState.Success);
assert.equal(called, 1);
});
});
it.skip('should sync missing versions in database', async () => {
// https://www.npmjs.com/package/@cnpmcore/test-sync-package-has-two-versions
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🟢 Synced updated 2 versions, removed 0 versions'));
assert(log.includes('] 🚧 Syncing versions 0 => 2'));
const pkg = await packageRepository.findPackage('@cnpmcore', 'test-sync-package-has-two-versions');
assert(pkg);
await packageRepository.removePackageVersions(pkg.packageId);
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('] 🟢 Synced updated 0 versions, removed 0 versions'));
assert(log.includes('] 🐛 Remote version 1.0.0 not exists on database'));
assert(log.includes('] 🐛 Remote version 2.0.0 not exists on database'));
assert(log.includes('] 🚧 Syncing versions 2 => 2'));
});
it('should sync removed versions', async () => {
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🟢 Synced updated 2 versions'));
app.mockAgent().assertNoPendingInterceptors();
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
repeats: 2,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('removed 1 versions'));
assert(log.includes('] 🟢 Removed version 1.0.0 success'));
const r = await packageManagerService.listPackageFullManifests('@cnpmcore', 'test-sync-package-has-two-versions');
assert(Object.keys(r.data!.versions).length === 1);
assert(!r.data!.versions['1.0.0'], '1.0.0 should not exists');
});
it('should work on unpublished package', async () => {
app.mockHttpclient('https://registry.npmjs.org/rollup-config-mbp', 'GET', {
data: '{"_id":"rollup-config-mbp","name":"rollup-config-mbp","time":{"created":"2020-09-25T09:18:36.405Z","0.0.1-alpha.1":"2020-09-25T09:18:36.552Z","modified":"2022-01-14T12:34:32.620Z","unpublished":{"time":"2022-01-14T12:34:32.620Z","versions":["0.0.1-alpha.1"]}}}',
persist: false,
});
let name = 'rollup-config-mbp';
// ignore unpublished when local package not exists
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
let data = await packageManagerService.listPackageFullManifests('', name);
assert(data.data === null);
// sync unpublished
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🟢 Synced '));
data = await packageManagerService.listPackageFullManifests('', name);
// console.log(data.data);
assert(!data.data!.time.unpublished);
assert(data.data!.maintainers);
app.mockAgent().assertNoPendingInterceptors();
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","name":"cnpmcore-test-sync-deprecated","time":{"created":"2020-09-25T09:18:36.405Z","0.0.1-alpha.1":"2020-09-25T09:18:36.552Z","modified":"2022-01-14T12:34:32.620Z","unpublished":{"time":"2022-01-14T12:34:32.620Z","versions":["0.0.1-alpha.1"]}}}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
data = await packageManagerService.listPackageFullManifests('', name);
// console.log(data.data);
assert(data.data!.time.unpublished);
assert(!data.data!.maintainers);
app.mockAgent().assertNoPendingInterceptors();
});
it('should work on mock package.readme is undefined', async () => {
const pkg = await TestUtil.readJSONFile(TestUtil.getFixtures('registry.npmjs.org/cnpmcore-test-sync-dependencies.json'));
delete pkg.readme;
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies', 'GET', {
data: JSON.stringify(pkg),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-dependencies/-/cnpmcore-test-sync-dependencies-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-dependencies';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 📦 Add dependency "cnpmcore-test-sync-deprecated" sync task: '));
const { data } = await packageManagerService.listPackageFullManifests('', name);
assert.equal(data!.readme, '');
});
it('should auto sync missing hasInstallScript property', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
// https://github.com/cnpm/cnpm/issues/374
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚧 Syncing versions 0 => 1'));
let res = await packageManagerService.listPackageFullManifests('', name);
assert(res.data);
assert(res.data.versions);
assert((res.data as any).versions[res.data['dist-tags'].latest].hasInstallScript === undefined);
app.mockAgent().assertNoPendingInterceptors();
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","version":"0.0.0","description":"","main":"index.js","scripts":{"install":"echo 1"},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚧 Syncing versions 1 => 1'));
assert(res.data);
res = await packageManagerService.listPackageFullManifests('', name);
assert(res.data!.versions?.[res.data!['dist-tags'].latest]?.hasInstallScript === true);
const abbrRes = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert(abbrRes.data!.versions[abbrRes.data!['dist-tags'].latest]?.hasInstallScript === true);
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore package.version.readme exists', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":"mock readme content","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('] 🔗 https://registry.npmjs.org/cnpmcore-test-sync-deprecated'));
const { data } = await packageManagerService.listPackageFullManifests('', name);
assert(data!.readme === 'mock readme content');
assert(data!.versions['0.0.0']!.readme === undefined);
});
it('should work on mock package.readme is object', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const data = await packageManagerService.listPackageFullManifests('', name);
assert.equal(data!.data!.readme, '{"foo":"mock readme is object"}');
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync dist-tags change', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('[1] Synced version 0.0.0 success'));
assert(log.includes('🟢 Synced 1 tags: [{"action":"change","tag":"latest","version":"0.0.0"}]'));
let data = await packageManagerService.listPackageFullManifests('', name);
assert.deepEqual(data!.data!['dist-tags'], { latest: '0.0.0' });
// update tags, add beta tag
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0","beta":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('[1] Synced version 0.0.0 success'));
assert(log.includes('🟢 Synced 1 tags: [{"action":"change","tag":"beta","version":"0.0.0"}]'));
data = await packageManagerService.listPackageFullManifests('', name);
assert(data.data);
assert.deepEqual(data.data['dist-tags'], { latest: '0.0.0', beta: '0.0.0' });
// all tags exists
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0","beta":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('[1] Synced version 0.0.0 success'));
assert(!log.includes('🟢 Synced 1 tags: '));
data = await packageManagerService.listPackageFullManifests('', name);
assert.deepEqual(data!.data!['dist-tags'], { latest: '0.0.0', beta: '0.0.0' });
// sync remove beta tags
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqvSEQ9eD3eZ09kfQOKO1j6LnjPeqAfbyYLWlEpxmJHAiAzD+2a4RHF8Vu5N+2wT4kagARnRb47FqpgD08elWVBgA=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/cnpmcore-test-sync-deprecated_0.0.0_1639246164624_0.5739637441745657"},"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('[1] Synced version 0.0.0 success'));
assert(log.includes('Synced 1 tags: [{"action":"remove","tag":"beta"}]'));
data = await packageManagerService.listPackageFullManifests('', name);
assert(data.data);
assert.deepEqual(data.data['dist-tags'], { latest: '0.0.0' });
app.mockAgent().assertNoPendingInterceptors();
});
it('should only sync specific version when strictSyncSpecivicVersion is true.', async () => {
mock(app.config.cnpmcore, 'strictSyncSpecivicVersion', true);
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name, { specificVersions: [ '1.0.0' ] });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('] 🟢 Synced updated 1 versions'));
assert(app.mockAgent().pendingInterceptors().length === 1);
});
it('should sync specific versions and latest version.', async () => {
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name, { specificVersions: [ '1.0.0' ] });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('] 🟢 Synced updated 2 versions'));
assert(app.mockAgent().pendingInterceptors().length === 0);
});
it('should sync specific versions and latest version.', async () => {
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name, { specificVersions: [ '1.0.0', '9.99.9' ] });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('🚧 Some specific versions are not available: 👉 9.99.9'));
});
it('should not sync nonexistent specific versions in strict mode.', async () => {
mock(app.config.cnpmcore, 'strictSyncSpecivicVersion', true);
app.mockHttpclient('https://registry.npmjs.org/%40cnpmcore%2Ftest-sync-package-has-two-versions', 'GET', {
data: '{"_id":"@cnpmcore/test-sync-package-has-two-versions","_rev":"4-541287ae0a14039fea89ac08fa5ec53d","name":"@cnpmcore/test-sync-package-has-two-versions","dist-tags":{"latest":"2.0.0","next":"2.0.0"},"versions":{"1.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"1.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@1.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-WR0T96H8t7ss1FK8GWPPblx+usbjU4bNGRjMHS9t/oVA5DgJDxitydPSFPeIUtXciyekI7R47do9Lc3GgC4P5A==","shasum":"2ddc6ee93b92be6d64139fb1a631d2610f43e946","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj5Ui2GU8nVmHFk0hCt/i3gPW9eQdOCZgKzpAlkvERwQIhAPZ0NCefLoEfOpnbdKAUr7Ng9Sy6FMnTsDxDaM2dQHNw"}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_1.0.0_1639442699824_0.6948988437963031"},"_hasShrinkwrap":false},"2.0.0":{"name":"@cnpmcore/test-sync-package-has-two-versions","version":"2.0.0","description":"cnpmcore local test package","main":"index.js","scripts":{"test":"echo \\"hello\\""},"author":"","license":"MIT","gitHead":"60cfb1cf401f87a60a1b0dfd7ee739f98ffd7847","_id":"@cnpmcore/test-sync-package-has-two-versions@2.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-qgHLQzXq+VN7q0JWibeBYrqb3Iajl4lpVuxlQstclRz4ejujfDFswBGSXmCv9FyIIdmSAe5bZo0oHQLsod3pAA==","shasum":"891eb8e08ceadbd86e75b6d66f31f7e5a28a8d68","tarball":"https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-2.0.0.tgz","fileCount":2,"unpackedSize":238,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAWVz7mIHF23Gq4a+Swsj2ZSdn87991HcE1+fQm8shNCAiByOIuhaZAbo9hct24qYf7FWqx6Lyluo+Rpnrn91//Ibg=="}]},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/test-sync-package-has-two-versions_2.0.0_1639442732240_0.33204392278137207"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-14T00:44:59.775Z","1.0.0":"2021-12-14T00:44:59.940Z","modified":"2022-05-23T02:33:52.613Z","2.0.0":"2021-12-14T00:45:32.457Z"},"maintainers":[{"email":"killa07071201@gmail.com","name":"killagu"},{"email":"fengmk2@gmail.com","name":"fengmk2"}],"description":"cnpmcore local test package","license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/test-sync-package-has-two-versions/-/test-sync-package-has-two-versions-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = '@cnpmcore/test-sync-package-has-two-versions';
await packageSyncerService.createTask(name, { specificVersions: [ '1.0.0', '9.99.9' ] });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('🚧 Some specific versions are not available: 👉 9.99.9'));
const manifest = await packageManagerService.listPackageAbbreviatedManifests('@cnpmcore', 'test-sync-package-has-two-versions');
assert(manifest.data?.['dist-tags']);
assert.equal(manifest.data?.['dist-tags'].latest, '1.0.0');
});
// 有任务积压,不一定能够同步完
it.skip('should sync sourceRegistryIsCNpm = true && syncUpstreamFirst = true', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(', syncUpstream: true'));
assert(log.includes('][UP] 🚧🚧🚧🚧🚧 Waiting sync "cnpmcore-test-sync-deprecated" task on https://r.cnpmjs.org 🚧'));
assert(log.includes('][UP] 🟢🟢🟢🟢🟢 https://r.cnpmjs.org/cnpmcore-test-sync-deprecated 🟢'));
});
it('should not sync upstream when task queue too high', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
mock(app.config.cnpmcore, 'taskQueueHighWaterSize', 1);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
await packageSyncerService.createTask(name + '-foo');
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(', syncUpstream: false'));
assert(log.includes(', taskQueue: 1/1'));
assert(!log.includes('][UP] 🚧🚧🚧🚧🚧 Waiting sync "cnpmcore-test-sync-deprecated" task on https://r.cnpmjs.org 🚧'));
});
it('should sync sourceRegistryIsCNpm = true && syncUpstreamFirst = false', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', false);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('][UP] 🟢🟢🟢🟢🟢 https://r.cnpmjs.org/cnpmcore-test-sync-deprecated 🟢'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync sourceRegistryIsCNpm = true and mock createSyncTask error', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
mock.error(NPMRegistry.prototype, 'createSyncTask');
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, create sync task error:`));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync sourceRegistryIsCNpm = true and mock createSyncTask return missing logId', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
mock.data(NPMRegistry.prototype, 'createSyncTask', { data: { ok: true }, res: {} });
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, missing logId`));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync sourceRegistryIsCNpm = true and mock getSyncTask syncDone = false', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/sync', 'PUT', {
data: {
ok: true,
logId: '633eea1359147b6066fae99f',
},
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
mock(app.config.cnpmcore, 'sourceRegistrySyncTimeout', 300);
let first = true;
mock(NPMRegistry.prototype, 'getSyncTask', async () => {
if (!first) {
throw new Error('mock error');
}
first = false;
return { data: { syncDone: false }, res: {}, status: 200 };
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes('][UP] 🚧 HTTP [200]'));
assert.match(log, /\]\[UP\] 🚧 HTTP \[unknow\] \[\d+ms\] error: /);
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync sourceRegistryIsCNpm = true and mock sync upstream timeout', async () => {
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/sync', 'PUT', {
data: {
ok: true,
logId: '633eea1359147b6066fae99f',
},
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/sync/log/633eea1359147b6066fae99f', 'GET', {
data: {
ok: false,
syncDone: false,
log: '',
},
persist: true,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://r.cnpmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
mock(app.config.cnpmcore, 'sourceRegistrySyncTimeout', 300);
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚮 give up 🚮 ❌❌❌❌❌'));
assert(log.includes(`][UP] ❌ Sync ${name} fail, timeout`));
app.mockAgent().assertNoPendingInterceptors();
});
it('should mock getFullManifests error', async () => {
mock.error(NPMRegistry.prototype, 'getFullManifests');
const name = 'cnpmcore-test-sync-dependencies';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes(`❌ Synced ${name} fail, request manifests error`));
// retry task
const task2 = await packageSyncerService.findExecuteTask();
assert(task2);
assert(task2.id === task.id);
});
it('should mock getFullManifests invalid maintainers error', async () => {
mock.data(NPMRegistry.prototype, 'getFullManifests', {
data: {
maintainers: [{ name: 'foo' }],
},
res: {},
headers: {},
});
const name = 'cnpmcore-test-sync-dependencies';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ invalid maintainers: '));
});
it('should try to use latest tag version maintainers instead', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated', 'GET', {
data: '{"_id":"cnpmcore-test-sync-deprecated","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-sync-deprecated","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-sync-deprecated","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-sync-deprecated@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz","fileCount":1,"unpackedSize":250},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-deprecated/-/cnpmcore-test-sync-deprecated-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
// https://registry.npmjs.org/postman-jsdoc-theme
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('📖 Use the latest version(0.0.0) maintainers instead'));
assert(log.includes('] 🔗'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should stop sync when upstream blocked', async () => {
// sync first
const name = 'cnpmcore-test-block-from-upstream';
app.mockHttpclient(`https://registry.npmjs.org/${name}`, 'GET', {
data: '{"_id":"cnpmcore-test-block-from-upstream","_rev":"2-bc8b9a2f6532d1bb3f94eaa4e82dbfe0","name":"cnpmcore-test-block-from-upstream","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"name":"cnpmcore-test-block-from-upstream","readme":"foo readme","version":"0.0.0","description":"","main":"index.js","scripts":{},"author":"","license":"ISC","dependencies":{},"_id":"cnpmcore-test-block-from-upstream@0.0.0","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-ptVWDP7Z39wOBk5EBwi2x8/SKZblEsVcdL0jjIsaI2KdLwVpRRRnezJSKpUsXr982nGf0j7nh6RcHSg4Wlu3AA==","shasum":"c73398ff6db39d138a56c04c7a90f35b70d7b78f","tarball":"https://registry.npmjs.org/cnpmcore-test-block-from-upstream/-/cnpmcore-test-block-from-upstream-0.0.0.tgz","fileCount":1,"unpackedSize":250},"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"directories":{},"maintainers":[{"name":"fengmk2","email":"fengmk2@gmail.com"}],"_hasShrinkwrap":false,"deprecated":"only test for cnpmcore"}},"time":{"created":"2021-12-11T18:09:24.624Z","0.0.0":"2021-12-11T18:09:24.768Z","modified":"2022-04-12T06:56:55.617Z"},"maintainers":[],"license":"ISC","readme":{"foo":"mock readme is object"},"readmeFilename":""}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-block-from-upstream/-/cnpmcore-test-block-from-upstream-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
await packageSyncerService.createTask(name);
let task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
const pkg = await packageRepository.findPackage('', name);
const pkgVersion = await packageRepository.findPackageVersion(pkg!.packageId, '0.0.0');
assert(pkg?.name === name);
assert(pkgVersion);
// mock unpublish
app.mockHttpclient(`https://registry.npmjs.org/${name}`, 'GET', {
data: `{"error":"[UNAVAILABLE_FOR_LEGAL_REASONS] ${name} was blocked, reason: foo (operator: cnpmcore_admin/61f154594ce7cf8f5827edf8)"}`,
persist: false,
status: 451,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
});
it('should stop sync by block list', async () => {
const name = 'cnpmcore-test-sync-blocklist';
mock(app.config.cnpmcore, 'syncPackageBlockList', [ name, 'foo' ]);
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ stop sync by block list: [\"cnpmcore-test-sync-blocklist\",\"foo\"]'));
});
it('should sync upper case "D" success', async () => {
app.mockHttpclient('https://registry.npmjs.org/D', 'GET', {
data: '{"_id":"D","_rev":"9-83b2794fe968ab4d4dc5c72475afe1ed","name":"D","dist-tags":{"latest":"1.0.0"},"versions":{"0.0.1":{"name":"D","version":"0.0.1","description":"","main":"index.js","scripts":{"test":"echo \\"Error: no test specified\\" && exit 1"},"author":{"name":"zhengzk"},"license":"MIT","_id":"D@0.0.1","_shasum":"292f54dbd43f36e4853f6a09e77617c23c46228b","_from":".","_npmVersion":"2.15.1","_nodeVersion":"4.4.3","_npmUser":{"name":"zhengzk","email":"studyc@163.com"},"dist":{"shasum":"292f54dbd43f36e4853f6a09e77617c23c46228b","tarball":"https://registry.npmjs.org/D/-/D-0.0.1.tgz","integrity":"sha512-8LsXYQFO1mko5MQ7qh72xjbCtB6PiNFC+q97eEZ85vrGL5HwMb27CuhWJKbcN6LrL8/zEwQYolHSV/jMyZ4zYg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICqSbDSXvMFKDfikUr0uttJJGWnrYFHfbOab67m0qOtZAiEAimvItLP13BkE5ex448H7eRtfAzOfQ1lCqNd1ygihn7A="}]},"maintainers":[{"name":"zhengzk","email":"studyc@163.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/D-0.0.1.tgz_1464672428722_0.6098439614288509"},"deprecated":"Package no longer supported. Contact support@npmjs.com for more info.","directories":{}},"1.0.0":{"name":"D","version":"1.0.0","description":"This package is no longer supported and has been deprecated. To avoid malicious use, npm is hanging on to the package name.","main":"index.js","scripts":{"test":"echo \\"Error: no test specified\\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/npm/deprecate-holder.git"},"author":"","license":"ISC","bugs":{"url":"https://github.com/npm/deprecate-holder/issues"},"homepage":"https://github.com/npm/deprecate-holder#readme","_id":"D@1.0.0","_npmVersion":"5.3.0","_nodeVersion":"8.2.1","_npmUser":{"name":"lisayu","email":"lisa@npmjs.com"},"dist":{"integrity":"sha512-nQvrCBu7K2pSSEtIM0EEF03FVjcczCXInMt3moLNFbjlWx6bZrX72uT6/1uAXDbnzGUAx9gTyDiQ+vrFi663oA==","shasum":"c348a4e034f72847be51206fc530fc089e9cc2a9","tarball":"https://registry.npmjs.org/D/-/D-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICZ8ljQHo15g72enGrhsxRggI5u1HmTzqaSwDdKK7pWMAiBophHVaH8mkvZjw45S2C65XmgOEqaKxKqv59mniAjosw=="}]},"maintainers":[{"email":"lisa@npmjs.com","name":"lisayu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/D-1.0.0.tgz_1502418423486_0.45665086852386594"},"deprecated":"Package no longer supported. Contact support@npmjs.com for more info.","directories":{}}},"readme":"# Deprecated Package\\n\\nThis package is no longer supported and has been deprecated. To avoid malicious use, npm is hanging on to the package name.\\n\\nPlease contact support@npmjs.com if you have questions about this package. \\n","maintainers":[{"email":"npm@npmjs.com","name":"npm"}],"time":{"modified":"2022-06-13T02:13:35.883Z","created":"2016-05-31T05:27:12.203Z","0.0.1":"2016-05-31T05:27:12.203Z","1.0.0":"2017-08-11T02:27:03.593Z"},"license":"ISC","readmeFilename":"README.md","description":"This package is no longer supported and has been deprecated. To avoid malicious use, npm is hanging on to the package name.","homepage":"https://github.com/npm/deprecate-holder#readme","repository":{"type":"git","url":"git+https://github.com/npm/deprecate-holder.git"},"bugs":{"url":"https://github.com/npm/deprecate-holder/issues"},"users":{"subbarao":true}}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/D/-/D-0.0.1.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/D/-/D-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'D';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚧🚧🚧🚧🚧 Syncing from https://registry.npmjs.org/D, '));
assert(log.includes('🔗'));
const res = await app.httpRequest()
.get(`/${name}`)
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
const data = res.body;
assert(data.name === name);
// assert(data.dist === name);
assert(data.versions[data['dist-tags'].latest].dist.tarball.includes('/D/-/D-'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync upper case "Buffer" success', async () => {
app.mockHttpclient('https://registry.npmjs.org/Buffer', 'GET', {
data: '{"_id":"Buffer","_rev":"5-b918bb11193c501a415c51047d6d68c7","name":"Buffer","description":"API-compatible Node.JS Buffer for Ender.js (browser)","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0":{"author":{"name":"AJ ONeal","email":"coolaj86@gmail.com","url":"http://coolaj86.info"},"name":"Buffer","description":"API-compatible Node.JS Buffer for Ender.js (browser)","version":"0.0.0","repository":{"type":"git","url":"git://github.com/coolaj86/browser-buffer.git"},"main":"index.js","engines":{"node":">= 0.2.0"},"dependencies":{},"devDependencies":{},"_npmJsonOpts":{"file":"/Users/coolaj86/.npm/Buffer/0.0.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"Buffer@0.0.0","_engineSupported":true,"_npmVersion":"1.0.15","_nodeVersion":"v0.4.8","_defaultsLoaded":true,"dist":{"shasum":"82cf8e986a2109ff6d1d6f1c436e47d07127aea4","tarball":"https://registry.npmjs.org/Buffer/-/Buffer-0.0.0.tgz","integrity":"sha512-+zdncl8lI5TCkARStn9F1BwcuJYofYmD0oEHe5FNfCvGfeDJwf6+dSikCdQN6BMXXmHMhNNUagBN367WST1AIQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbPvXxxdsc/1aMyduDYXMbRVTFU71ajZ5BztZ3S07ofQIgBy/kpAuBDMIhlfOQW2l2XIq8eMs6BNqjEPXo3CJ5WrE="}]},"scripts":{},"maintainers":[{"name":"coolaj86","email":"coolaj86@gmail.com"}]}},"maintainers":[{"name":"coolaj86","email":"coolaj86@gmail.com"}],"time":{"modified":"2022-06-13T02:13:16.055Z","created":"2011-08-01T20:40:41.355Z","0.0.0":"2011-08-01T20:40:41.710Z"},"author":{"name":"AJ ONeal","email":"coolaj86@gmail.com","url":"http://coolaj86.info"},"repository":{"type":"git","url":"git://github.com/coolaj86/browser-buffer.git"}}',
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/Buffer/-/Buffer-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'Buffer';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🚧🚧🚧🚧🚧 Syncing from https://registry.npmjs.org/Buffer, '));
assert(log.includes('🔗'));
const res = await app.httpRequest()
.get(`/${name}`)
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
const data = res.body;
assert(data.name === name);
assert(data.versions[data['dist-tags'].latest].dist.tarball.includes('/Buffer/-/Buffer-'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should mock security holding package', async () => {
app.mockHttpclient('https://registry.npmjs.org/cnpmcore-test-sync-security-holding-package', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/security-holding-package.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/webpack.js.org/-/webpack.js.org-0.0.1-security.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'cnpmcore-test-sync-security-holding-package';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`] 🟢 Package "${name}" was removed in remote registry`));
});
it('should mock getFullManifests missing tarball error and downloadTarball error', async () => {
app.mockHttpclient('http://foo.com/a.tgz', 'GET', {
status: 500,
persist: false,
repeats: 3,
data: 'server error',
});
mock.error(NPMRegistry.prototype, 'downloadTarball');
mock.data(NPMRegistry.prototype, 'getFullManifests', {
data: {
maintainers: [{ name: 'fengmk2', email: 'fengmk2@gmai.com' }],
versions: {
'1.0.0': {
version: '1.0.0',
dist: { tarball: '' },
},
'2.0.0': {
version: '2.0.0',
dist: { tarball: 'http://foo.com/a.tgz' },
},
},
},
res: {},
headers: {},
});
const name = 'cnpmcore-test-sync-deprecated';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('Synced version 1.0.0 fail, missing tarball, dist: '));
assert(log.includes('❌ All versions sync fail, package not exists'));
assert(log.includes('Synced version 2.0.0 fail, download tarball error'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should mock downloadTarball status !== 200', async () => {
app.mockHttpclient('http://foo.com/a.tgz', 'GET', {
status: 500,
persist: false,
repeats: 3,
data: 'server error',
});
mock.data(NPMRegistry.prototype, 'getFullManifests', {
data: {
maintainers: [{ name: 'fengmk2', email: 'fengmk2@gmai.com' }],
versions: {
'2.0.0': {
version: '2.0.0',
dist: { tarball: 'http://foo.com/a.tgz' },
},
},
},
res: {},
headers: {},
});
const name = 'cnpmcore-test-sync-dependencies';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes(`❌❌❌❌❌ ${name} ❌❌❌❌❌`));
assert(log.includes('❌ All versions sync fail, package not exists'));
assert(log.includes('Synced version 2.0.0 fail, download tarball error: DownloadStatusInvalidError: Download http://foo.com/a.tgz status(500) invalid'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync mk2test-module-cnpmsync with different metas', async () => {
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/mk2test-module-cnpmsync.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync/-/mk2test-module-cnpmsync-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync/-/mk2test-module-cnpmsync-3.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'mk2test-module-cnpmsync';
mock(app.config.cnpmcore, 'allowPublishNonScopePackage', true);
await TestUtil.createPackage({ name, version: '2.0.0', isPrivate: false });
await packageSyncerService.createTask(name, { tips: 'sync test tips here' });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Synced version 2.0.0 success, different meta: {"peerDependenciesMeta":{"bufferutil":{"optional":true},"utf-8-validate":{"optional":true}},"os":["linux"],"cpu":["x64"],"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"}}'));
assert(log.includes('Z] 👉👉👉👉👉 Tips: sync test tips here 👈👈👈👈👈'));
assert(log.includes(', skipDependencies: false'));
let manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data?.versions['2.0.0']);
assert.equal(manifests.data.versions['2.0.0'].peerDependenciesMeta?.bufferutil.optional, true);
assert.equal(manifests.data.versions['2.0.0'].os?.[0], 'linux');
assert.equal(manifests.data.versions['2.0.0'].cpu?.[0], 'x64');
// publishTime
assert.equal(manifests.data.time['1.0.0'], '2021-09-27T08:10:48.747Z');
let abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
// console.log(JSON.stringify(abbreviatedManifests.data, null, 2));
assert(abbreviatedManifests.data?.versions['2.0.0']);
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].peerDependenciesMeta?.bufferutil.optional, true);
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].os?.[0], 'linux');
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].cpu?.[0], 'x64');
app.mockAgent().assertNoPendingInterceptors();
// again should skip sync different metas
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/mk2test-module-cnpmsync.json'),
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('🟢 Synced version 2.0.0 success, different meta:'));
app.mockAgent().assertNoPendingInterceptors();
// should delete readme
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/mk2test-module-cnpmsync.json'),
persist: false,
});
manifests.data.versions['2.0.0'].readme = 'mock version readme content';
mock.data(PackageManagerService.prototype, 'listPackageFullManifests', manifests);
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🟢 Synced version 2.0.0 success, different meta: {}, delete exists readme'));
app.mockAgent().assertNoPendingInterceptors();
await mock.restore();
manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data?.versions['2.0.0']);
assert(manifests.data.versions['2.0.0'].readme === undefined);
// should sync missing cpu on abbreviated manifests
const pkg = await packageRepository.findPackage('', name);
const pkgVersion = await packageRepository.findPackageVersion(pkg!.packageId, '2.0.0');
assert(pkgVersion);
await packageManagerService.savePackageVersionManifest(pkgVersion, {}, { cpu: undefined, libc: [ 'glibc' ] });
await packageManagerService.refreshPackageChangeVersionsToDists(pkg!, [ '2.0.0' ]);
abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert(!abbreviatedManifests.data!.versions['2.0.0'].cpu);
assert.deepStrictEqual(abbreviatedManifests.data!.versions['2.0.0'].libc, [ 'glibc' ]);
app.mockHttpclient('https://registry.npmjs.org/mk2test-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/mk2test-module-cnpmsync.json'),
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('🟢 Synced version 2.0.0 success, different meta: {"cpu":["x64"]}'));
app.mockAgent().assertNoPendingInterceptors();
await mock.restore();
abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
assert(abbreviatedManifests.data?.versions['2.0.0']);
assert.equal(abbreviatedManifests.data.versions['2.0.0'].cpu?.[0], 'x64');
assert(!abbreviatedManifests.data!.versions['2.0.0'].libc);
});
it('should sync missing acceptDependencies with different metas', async () => {
app.mockHttpclient('https://registry.npmjs.org/accept-dependencies-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/accept-dependencies-module-cnpmsync.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/accept-dependencies-module-cnpmsync/-/accept-dependencies-module-cnpmsync-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/accept-dependencies-module-cnpmsync/-/accept-dependencies-module-cnpmsync-3.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const name = 'accept-dependencies-module-cnpmsync';
mock(app.config.cnpmcore, 'allowPublishNonScopePackage', true);
await TestUtil.createPackage({ name, version: '2.0.0', isPrivate: false });
await packageSyncerService.createTask(name, { tips: 'sync test tips here' });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('Synced version 2.0.0 success, different meta: {"peerDependenciesMeta":{"bufferutil":{"optional":true},"utf-8-validate":{"optional":true}},"os":["linux"],"cpu":["x64"],"_npmUser":{"name":"fengmk2","email":"fengmk2@gmail.com"},"acceptDependencies":{"webpack":"^4.46.x"}}'));
assert(log.includes('Z] 👉👉👉👉👉 Tips: sync test tips here 👈👈👈👈👈'));
assert(log.includes(', skipDependencies: false'));
const manifests = await packageManagerService.listPackageFullManifests('', name);
assert(manifests.data?.versions['2.0.0']);
assert.equal(manifests.data.versions['2.0.0'].peerDependenciesMeta?.bufferutil.optional, true);
assert.equal(manifests.data.versions['2.0.0'].os?.[0], 'linux');
assert.equal(manifests.data.versions['2.0.0'].cpu?.[0], 'x64');
// publishTime
assert.equal(manifests.data.time['1.0.0'], '2021-09-27T08:10:48.747Z');
const abbreviatedManifests = await packageManagerService.listPackageAbbreviatedManifests('', name);
// console.log(JSON.stringify(abbreviatedManifests.data, null, 2));
assert(abbreviatedManifests.data?.versions['2.0.0']);
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].peerDependenciesMeta?.bufferutil.optional, true);
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].os?.[0], 'linux');
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].cpu?.[0], 'x64');
assert.equal(abbreviatedManifests.data!.versions['2.0.0'].acceptDependencies?.webpack, '^4.46.x');
app.mockAgent().assertNoPendingInterceptors();
// again should skip sync different metas
app.mockHttpclient('https://registry.npmjs.org/accept-dependencies-module-cnpmsync', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/accept-dependencies-module-cnpmsync.json'),
persist: false,
});
await packageSyncerService.createTask(name);
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('🟢 Synced version 2.0.0 success, different meta:'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync download data work on enableSyncDownloadData = true', async () => {
mock(app.config.cnpmcore, 'syncDownloadDataSourceRegistry', 'https://rold.cnpmjs.org');
mock(app.config.cnpmcore, 'enableSyncDownloadData', true);
mock(app.config.cnpmcore, 'syncDownloadDataMaxDate', '2021-12-28');
app.mockHttpclient('https://registry.npmjs.org/pedding', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/pedding.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
const response = await TestUtil.readJSONFile(TestUtil.getFixtures('downloads.json'));
app.mockHttpclient('https://rold.cnpmjs.org/downloads/range/2011-01-01:2021-12-28/pedding', 'GET', {
data: response,
status: 200,
});
const name = 'pedding';
await packageSyncerService.createTask(name, { syncDownloadData: true });
let task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('][DownloadData] 🟢 202101: 31 days'));
assert(log.includes('][DownloadData] 🟢🟢🟢🟢🟢'));
assert(log.includes('] 🟢🟢🟢🟢🟢'));
let res = await app.httpRequest()
.get(`/downloads/range/2020-12-28:2021-12-28/${name}`)
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
let data = res.body;
assert(data.downloads.length > 0);
assert(Object.keys(data.versions).length === 0);
// console.log('%j', data);
// again should sync download data only
await packageSyncerService.createTask(name, { syncDownloadData: true });
task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('][DownloadData] 🟢 202110: 31 days'));
assert(log.includes('][DownloadData] 🟢🟢🟢🟢🟢'));
assert(log.includes(`] 🟢🟢🟢🟢🟢 Sync "${name}" download data success 🟢🟢🟢🟢🟢`));
res = await app.httpRequest()
.get(`/downloads/range/2020-12-28:2021-12-28/${name}`)
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
data = res.body;
assert(data.downloads.length > 0);
assert(Object.keys(data.versions).length === 0);
// console.log('%j', data);
app.mockAgent().assertNoPendingInterceptors();
});
it('should ignore sync download data work on enableSyncDownloadData = false', async () => {
app.mockHttpclient('https://registry.npmjs.org/pedding', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/pedding.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'enableSyncDownloadData', false);
const name = 'pedding';
await packageSyncerService.createTask(name, { syncDownloadData: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(!log.includes('][DownloadData] 🟢 202111: 10 days'));
assert(!log.includes('][DownloadData] 🟢🟢🟢🟢🟢'));
const res = await app.httpRequest()
.get(`/downloads/range/2020-12-28:2021-12-28/${name}`)
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
const data = res.body;
assert(data.downloads.length === 0);
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync download data and mock getDownloadRanges error', async () => {
app.mockHttpclient('https://registry.npmjs.org/pedding', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/pedding.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/pedding/-/pedding-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'syncDownloadDataSourceRegistry', 'https://rold.cnpmjs.org');
mock(app.config.cnpmcore, 'enableSyncDownloadData', true);
mock(app.config.cnpmcore, 'syncDownloadDataMaxDate', '2021-12-28');
mock.error(NPMRegistry.prototype, 'getDownloadRanges');
const name = 'pedding';
await packageSyncerService.createTask(name, { syncDownloadData: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('][DownloadData] ❌ Get download data error: '));
assert(log.includes('][DownloadData] ❌❌❌❌❌ 🚮 give up 🚮 ❌❌❌❌❌'));
app.mockAgent().assertNoPendingInterceptors();
});
describe('should sync from spec registry', async () => {
let registry: Registry;
beforeEach(async () => {
registry = await registryManagerService.createRegistry({
name: 'cnpm',
changeStream: 'https://replicate.npmjs.com/_changes',
host: 'https://custom.npmjs.com',
userPrefix: 'cnpm:',
type: RegistryType.Npm,
});
});
it('should ignore syncUpstreamFirst', async () => {
await scopeManagerService.createScope({
name: '@dnpm',
registryId: registry.registryId,
});
app.mockHttpclient('https://custom.npmjs.com/@dnpm/banana', 'GET', {
data: await TestUtil.readFixturesFile('r.cnpmjs.org/cnpmcore-test-sync-deprecated.json'),
persist: false,
});
app.mockHttpclient('https://custom.npmjs.com/@dnpm/banana/-/banana-0.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
mock(app.config.cnpmcore, 'sourceRegistry', 'https://r.cnpmjs.org');
mock(app.config.cnpmcore, 'sourceRegistryIsCNpm', true);
mock(app.config.cnpmcore, 'syncUpstreamFirst', true);
const name = '@dnpm/banana';
await packageSyncerService.createTask(name);
const task = await packageSyncerService.findExecuteTask();
assert(task);
assert.equal(task.targetName, name);
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
// console.log(log);
assert(log.includes('syncUpstream: false'));
});
it('should sync from target registry & default registry', async () => {
await packageSyncerService.createTask('cnpm-pkg', { registryId: registry.registryId });
await packageSyncerService.createTask('npm-pkg');
// custom registry
app.mockHttpclient('https://custom.npmjs.com/cnpm-pkg', 'GET', {
status: 500,
data: 'mock custom.npmjs.com error',
persist: false,
repeats: 3,
});
let task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
let stream = await packageSyncerService.findTaskLog(task);
assert(stream);
let log = await TestUtil.readStreamToLog(stream);
assert(log.includes('Syncing from https://custom.npmjs.com/cnpm-pkg'));
// default registry
app.mockHttpclient('https://default.npmjs.org/npm-pkg', 'GET', {
status: 500,
data: 'mock default.npmjs.org error',
persist: false,
repeats: 3,
});
task = await packageSyncerService.findExecuteTask();
mock(app.config.cnpmcore, 'sourceRegistry', 'https://default.npmjs.org');
await packageSyncerService.executeTask(task);
stream = await packageSyncerService.findTaskLog(task);
assert(stream);
log = await TestUtil.readStreamToLog(stream);
assert(log.includes('Syncing from https://default.npmjs.org/npm-pkg'));
app.mockAgent().assertNoPendingInterceptors();
});
it('should sync from default registry when pkg.registryId is undefined', async () => {
const pkgName = '@cnpmcore/sync_not_match_registry_name';
await TestUtil.createPackage({
name: pkgName,
registryId: undefined,
isPrivate: false,
}, {
name: 'mock_username',
});
// default registry
app.mockHttpclient('https://registry.npmjs.org/@cnpmcore/sync_not_match_registry_name', 'GET', {
status: 500,
data: 'mock default.npmjs.org error',
persist: false,
repeats: 3,
});
await taskService.createTask(TaskEntity.createSyncPackage(pkgName, {}), true);
const task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('Syncing from https://registry.npmjs.org/@cnpmcore/sync_not_match_registry_name'));
});
it('should sync from target registry when pkg.registryId is undefined', async () => {
const pkgName = '@cnpm/banana';
await TestUtil.createPackage({
name: pkgName,
isPrivate: false,
}, {
name: 'mock_username',
});
await packageSyncerService.createTask(pkgName);
const task = await packageSyncerService.findExecuteTask();
// create custom scope
await scopeManagerService.createScope({
name: '@cnpm',
registryId: registry.registryId,
});
app.mockHttpclient('https://custom.npmjs.com/@cnpm/banana', 'GET', {
status: 500,
data: 'mock error',
persist: false,
repeats: 3,
});
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('Syncing from https://custom.npmjs.com/@cnpm/banana'));
const pkg = await packageRepository.findPackage('@cnpm', 'banana');
assert(pkg!.registryId === registry.registryId);
});
it('should sync from target registry when pkg not exists', async () => {
const pkgName = '@cnpm/banana';
await packageSyncerService.createTask(pkgName);
const task = await packageSyncerService.findExecuteTask();
// create custom scope
await scopeManagerService.createScope({
name: '@cnpm',
registryId: registry.registryId,
});
app.mockHttpclient('https://custom.npmjs.com/@cnpm/banana', 'GET', {
status: 500,
data: 'mock error',
persist: false,
repeats: 3,
});
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('Syncing from https://custom.npmjs.com/@cnpm/banana'));
});
it('should not sync from target registry if not match', async () => {
const pkgName = '@cnpmcore/sync_not_match_registry_name';
await TestUtil.createPackage({
name: pkgName,
registryId: 'mock_registry_id',
isPrivate: false,
}, {
name: 'mock_username',
});
await taskService.createTask(TaskEntity.createSyncPackage(pkgName, {
registryId: registry.registryId,
}), true);
const task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log.includes('skip sync'));
});
});
describe('syncDeleteMode = ignore', async () => {
// already synced pkg
beforeEach(async () => {
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json'),
persist: false,
repeats: 1,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz'),
persist: false,
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
});
it('should ignore when upstream is removed', async () => {
// removed in remote
mock(app.config.cnpmcore, 'syncDeleteMode', 'ignore');
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/security-holding-package.json'),
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foobar' });
assert(model);
const versions = await PackageVersion.find({ packageId: model.packageId });
assert.equal(model!.isPrivate, false);
assert(versions.length === 2);
});
it('should block when upstream is removed', async () => {
// removed in remote
mock(app.config.cnpmcore, 'syncDeleteMode', 'block');
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/security-holding-package.json'),
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foobar' });
assert(model);
const versions = await PackageVersion.find({ packageId: model.packageId });
assert.equal(model!.isPrivate, false);
assert(versions.length === 2);
const manifests = await packageManagerService.listPackageFullManifests('', 'foobar');
assert(manifests.blockReason === 'Removed in remote registry');
assert(manifests.data);
assert(manifests.data.block === 'Removed in remote registry');
const pkg = await packageRepository.findPackage('', 'foobar');
assert(pkg);
await app.httpRequest()
.get(`/${pkg.name}`)
.expect(451);
// could resotre
await packageManagerService.unblockPackage(pkg);
await app.httpRequest()
.get(`/${pkg.name}`)
.expect(200);
});
it('unpublish package idempotent', async () => {
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/security-holding-package.json'),
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
assert(!await TaskModel.findOne({ taskId: task.taskId }));
assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'foobar' });
assert(model);
const versions = await PackageVersion.find({ packageId: model.packageId });
assert(versions.length === 0);
// resync
app.mockLog();
await packageSyncerService.createTask('foobar', { skipDependencies: true });
task = await packageSyncerService.findExecuteTask();
await packageSyncerService.executeTask(task);
assert(task);
const pkg = await packageRepository.findPackage('', 'foobar');
app.expectLog(`[packageManagerService.unpublishPackage:skip] ${pkg?.packageId} already unpublished`);
});
it('should resync history version if forceSyncHistory is true', async () => {
const manifest = JSON.parse((await TestUtil.readFixturesFile('registry.npmjs.org/foobar.json')).toString());
manifest.versions['1.0.0']._npmUser = { name: 'apple', email: 'apple@cnpmjs.org' };
manifest.maintainers = [ ...manifest.maintainers, { name: 'apple', email: 'apple@cnpmjs.org' }];
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: manifest,
persist: false,
repeats: 1,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
repeats: 2,
});
app.mockHttpclient('https://registry.npmjs.org/foobar/-/foobar-1.1.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.1.0.tgz'),
persist: false,
repeats: 2,
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
let task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
// should sync publisher
const syncInfo = await packageManagerService.listPackageFullManifests('', 'foobar');
assert.equal(syncInfo.data?.versions['1.0.0']?._npmUser?.name, 'apple');
// resync
manifest.versions['1.0.0']._npmUser = { name: 'banana', email: 'banana@cnpmjs.org' };
app.mockHttpclient('https://registry.npmjs.org/foobar', 'GET', {
data: manifest,
persist: false,
repeats: 1,
});
await packageSyncerService.createTask('foobar', { skipDependencies: true });
task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
const stream2 = await packageSyncerService.findTaskLog(task);
assert(stream2);
const log2 = await TestUtil.readStreamToLog(stream2);
// console.log(log2);
assert(/different meta: {"_npmUser":{"name":"banana","email":"banana@cnpmjs.org"}}/.test(log2));
});
});
describe('strictValidatePackageDeps = true', async () => {
// already synced pkg
beforeEach(async () => {
app.mockHttpclient(/^https:\/\/registry\.npmjs\.org\/invalid\-deps/, 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/invalid-deps.json'),
persist: false,
});
app.mockHttpclient('https://registry.npmjs.org/invalid-deps/-/invalid-deps-1.0.0.tgz', 'GET', {
data: await TestUtil.readFixturesFile('registry.npmjs.org/foobar/-/foobar-1.0.0.tgz'),
persist: false,
});
});
it('should not create pkg when invalid deps', async () => {
// removed in remote
mock(app.config.cnpmcore, 'strictValidatePackageDeps', true);
await packageSyncerService.createTask('invalid-deps', { skipDependencies: true });
const task = await packageSyncerService.findExecuteTask();
assert(task);
await packageSyncerService.executeTask(task);
// assert(!await TaskModel.findOne({ taskId: task.taskId }));
// assert(await HistoryTaskModel.findOne({ taskId: task.taskId }));
const stream = await packageSyncerService.findTaskLog(task);
assert(stream);
const log = await TestUtil.readStreamToLog(stream);
assert(log);
// console.log(log);
const model = await PackageModel.findOne({ scope: '', name: 'invalid-deps' });
assert(!model);
// shoud requeue
const reTask = await packageSyncerService.findExecuteTask();
assert(reTask.attempts === 2);
});
});
});
});