Skip to content

Commit f0296db

Browse files
@jotadevelopergriffithtp
authored andcommitted
feat: add write tarball and read tarball
1 parent 5683185 commit f0296db

File tree

12 files changed

+468
-136
lines changed

12 files changed

+468
-136
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const results = [];
2+
const _symbol = Symbol('KEY');
3+
const defaultResuponse = [
4+
results,
5+
{
6+
endCursor: 'CjgSMmoOZX52ZXJkYW=',
7+
moreResults: 'NO_MORE_RESULTS'
8+
}
9+
];
10+
const keyContent = () => {
11+
const id = Math.random();
12+
13+
return {
14+
namespace: undefined,
15+
id,
16+
kind: 'metadataDatabaseKey',
17+
path: ['metadataDatabaseKey', `${id}`]
18+
};
19+
};
20+
21+
export default class Storage {
22+
constructor() {
23+
this.KEY = _symbol;
24+
}
25+
26+
int(id) {
27+
return id;
28+
}
29+
30+
key(_key) {
31+
return _key;
32+
}
33+
34+
save(toSave) {
35+
const data = toSave.data;
36+
data[this.KEY] = keyContent();
37+
38+
results.push(data);
39+
return Promise.resolve();
40+
}
41+
42+
update(entity) {
43+
return {};
44+
}
45+
46+
delete(key) {
47+
const id = key[1];
48+
let counter = 1;
49+
const elementToRemove = results.filter((item, index) => {
50+
const medatada = item[this.KEY];
51+
52+
if (medatada.id === id) {
53+
results.splice(index, 0);
54+
return true;
55+
}
56+
57+
return false;
58+
});
59+
60+
const response = {
61+
indexUpdates: counter,
62+
mutationResults: elementToRemove
63+
};
64+
65+
return Promise.resolve([response]);
66+
}
67+
68+
createQuery() {
69+
return {
70+
filter: () => 'query'
71+
};
72+
}
73+
runQuery(query) {
74+
return Promise.resolve(defaultResuponse);
75+
}
76+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default class Storage {}

plugins/verdaccio-google-cloud/src/data-storage.js

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@ import Datastore from '@google-cloud/datastore';
55

66
import GoogleCloudStorageHandler from './storage';
77
import StorageHelper from './storage-helper';
8-
import type { ConfigMemory } from './storage-helper';
98
import type { Logger, Callback } from '@verdaccio/types';
109
import type { ILocalData } from '@verdaccio/local-storage';
11-
12-
const GOOGLE_OPTIONS: any = {
13-
projectId: process.env.GC_PROJECT_ID,
14-
keyFilename: process.env.GC_KEY_FILE
15-
};
10+
import type { ConfigGoogleStorage, GoogleCloudOptions, GoogleDataStorage } from '../types';
1611

1712
declare type GoogleDataStorage = {
1813
secret: string,
@@ -21,25 +16,57 @@ declare type GoogleDataStorage = {
2116
};
2217

2318
class GoogleCloudDatabase implements ILocalData {
19+
helper: any;
2420
path: string;
2521
logger: Logger;
2622
data: GoogleDataStorage;
27-
bucketName: string;
28-
config: ConfigMemory;
2923
locked: boolean;
30-
datastore: any;
31-
key: string;
32-
helper: any;
24+
config: ConfigGoogleStorage;
25+
kind: string;
26+
bucketName: string;
27+
keyFilename: string;
28+
GOOGLE_OPTIONS: GoogleCloudOptions;
3329

34-
constructor(config: ConfigMemory, options: any) {
30+
constructor(config: ConfigGoogleStorage, options: any) {
31+
if (!config) {
32+
throw new Error('google cloud storage missing config. Add `store.google-cloud` to your config file');
33+
}
3534
this.config = config;
3635
this.logger = options.logger;
37-
this.key = config.metadataDatabaseKey || 'VerdaccioDataStore';
38-
this.bucketName = config.bucketName || 'verdaccio-plugin';
36+
this.kind = config.kind || 'VerdaccioDataStore';
37+
// if (!this.keyFilename) {
38+
// throw new Error('Google Storage requires a a key file');
39+
// }
40+
this.bucketName = config.bucket;
41+
if (!this.bucketName) {
42+
throw new Error('Google Cloud Storage requires a bucket name, please define one.');
43+
}
3944
this.data = this._createEmtpyDatabase();
4045
this.helper = new StorageHelper(this.data.datastore, this.data.storage);
4146
}
4247

48+
_getGoogleOptions(config: ConfigGoogleStorage): GoogleCloudOptions {
49+
const GOOGLE_OPTIONS: GoogleCloudOptions = {};
50+
51+
if (!config.projectId || typeof config.projectId !== 'string') {
52+
throw new Error('Google Cloud Storage requires a ProjectId.');
53+
}
54+
55+
GOOGLE_OPTIONS.projectId = config.projectId || process.env.GOOGLE_CLOUD_VERDACCIO_PROJECT_ID;
56+
57+
const keyFileName = config.keyFilename || process.env.GOOGLE_CLOUD_VERDACCIO_KEY;
58+
if (keyFileName) {
59+
GOOGLE_OPTIONS.keyFilename = keyFileName;
60+
this.logger.warn('Using credentials in a file might be un-secure and is recommended for local development');
61+
}
62+
// const GOOGLE_OPTIONS: GoogleCloudOptions = {
63+
// projectId: 'verdaccio-01',
64+
// keyFilename: './verdaccio-01-56f693e3aab0.json'
65+
// };
66+
this.logger.warn({ content: JSON.stringify(GOOGLE_OPTIONS) }, 'Google storage settings: @{content}');
67+
return GOOGLE_OPTIONS;
68+
}
69+
4370
getSecret(): Promise<any> {
4471
return Promise.resolve(this.data.secret);
4572
}
@@ -71,7 +98,7 @@ class GoogleCloudDatabase implements ILocalData {
7198
async deleteItem(name: string, item: any) {
7299
try {
73100
const datastore = this.data.datastore;
74-
const key = datastore.key([this.key, datastore.int(item.id)]);
101+
const key = datastore.key([this.kind, datastore.int(item.id)]);
75102
const deleted = await datastore.delete(key);
76103
return deleted;
77104
} catch (err) {
@@ -86,10 +113,12 @@ class GoogleCloudDatabase implements ILocalData {
86113
return new Error('not found');
87114
} else if (deletedItems[0][0].indexUpdates > 0) {
88115
return null;
116+
} else {
117+
return new Error('this should not happen');
89118
}
90119
};
91120
this.helper
92-
.getEntities(this.key)
121+
.getEntities(this.kind)
93122
.then(async entities => {
94123
for (const item of entities) {
95124
if (item.name === name) {
@@ -105,7 +134,7 @@ class GoogleCloudDatabase implements ILocalData {
105134
}
106135

107136
get(cb: Callback) {
108-
const query = this.helper.datastore.createQuery(this.key);
137+
const query = this.helper.datastore.createQuery(this.kind);
109138
this.helper.runQuery(query).then(data => {
110139
const names = data[0].reduce((accumulator, task) => {
111140
accumulator.push(task.name);
@@ -124,8 +153,8 @@ class GoogleCloudDatabase implements ILocalData {
124153
}
125154

126155
_createEmtpyDatabase(): GoogleDataStorage {
127-
const datastore = new Datastore(GOOGLE_OPTIONS);
128-
const storage = new Storage(GOOGLE_OPTIONS);
156+
const datastore = new Datastore(this._getGoogleOptions(this.config));
157+
const storage = new Storage(this._getGoogleOptions(this.config));
129158

130159
const list: any = [];
131160
const files: any = {};

plugins/verdaccio-google-cloud/src/storage-helper.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
// @flow
22

3-
export type ConfigMemory = {
4-
metadataDatabaseKey: string,
5-
bucketName: string
6-
};
7-
83
export default class StorageHelper {
94
datastore: any;
105
storage: any;

0 commit comments

Comments
 (0)