Skip to content

Commit dfc55da

Browse files
committed
Start with packages api
1 parent 45b0f6a commit dfc55da

File tree

4 files changed

+49
-27
lines changed

4 files changed

+49
-27
lines changed

routes/api.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import express from 'express';
22
import url from 'node:url';
3-
import {ls_packages} from '../src/db.js';
3+
import {ls_packages, get_package_info, get_universe_packages} from '../src/db.js';
44

55
const router = express.Router();
66

@@ -9,8 +9,21 @@ router.get('/api', function(req, res, next) {
99
});
1010

1111
router.get('/api/ls', function(req, res, next) {
12-
ls_packages(res.locals.universe).then(x => res.send(x));
12+
return ls_packages(res.locals.universe).then(x => res.send(x));
1313
});
1414

15+
router.get('/api/packages', function(req, res, next) {
16+
var fields = req.query.fields && req.query.fields.split(",");
17+
return get_universe_packages(res.locals.universe, fields).then(function(x){
18+
res.send(x);
19+
});
20+
});
21+
22+
router.get('/api/packages/:package', function(req, res, next) {
23+
var fields = req.query.fields && req.query.fields.split(",");
24+
return get_package_info(req.params.package, res.locals.universe, fields).then(function(x){
25+
res.send(x)
26+
});
27+
});
1528

1629
export default router;

routes/repos.js

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,10 @@
11
import express from 'express';
2-
import zlib from 'node:zlib';
32
import createError from 'http-errors';
4-
import {doc_to_dcf, match_macos_arch} from '../src/tools.js';
3+
import {doc_to_dcf, match_macos_arch, doc_to_ndjson, cursor_stream} from '../src/tools.js';
54
import {get_universe_binaries, get_packages_index, get_package_hash} from '../src/db.js';
65

76
const router = express.Router();
87

9-
function doc_to_ndjson(x){
10-
return JSON.stringify(x) + '\n';
11-
}
12-
13-
// Somehow node:stream/promises does not catch input on-error callbacks properly
14-
// so we promisify ourselves. See https://github.com/r-universe-org/help/issues/540
15-
function cursor_stream(cursor, output, transform, gzip){
16-
return new Promise(function(resolve, reject) {
17-
var input = cursor.stream({transform: transform}).on('error', reject);
18-
if(gzip){
19-
input = input.pipe(zlib.createGzip()).on('error', reject);
20-
}
21-
input.pipe(output).on('finish', resolve).on('error', reject);
22-
});
23-
}
24-
258
function packages_index(query, req, res, mixed = false){
269
query._user = res.locals.universe;
2710
var format = req.params.format || "PACKAGES.json";

src/db.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,18 @@ function array_first(key){
127127
}
128128

129129
function build_projection(fields){
130+
if(!fields || !fields.length) return {_id:0};
130131
var projection = {Package:1, _type:1, _user:1, _indexed: 1, _id:0};
131132
fields.forEach(function (f) {
132-
projection[f] = 1;
133+
if(f == '_binaries'){
134+
projection['Built'] = 1;
135+
projection['_status'] = 1;
136+
projection['_check'] = 1;
137+
if(!fields.includes("_commit"))
138+
projection['_commit.id'] = 1;
139+
} else {
140+
projection[f] = 1;
141+
}
133142
});
134143
return projection;
135144
}
@@ -138,8 +147,9 @@ function mongo_package_files(pkg, universe){
138147
return mongo_find({_user: universe, Package: pkg, _registered: true}).toArray();
139148
}
140149

141-
function mongo_package_info(pkg, universe){
142-
return mongo_find({_user: universe, Package: pkg, _registered: true}).toArray().then(function(docs){
150+
function mongo_package_info(pkg, universe, fields){
151+
var proj = build_projection(fields);
152+
return mongo_find({_user: universe, Package: pkg, _registered: true}).project(proj).toArray().then(function(docs){
143153
if(!docs.length) //should never happen because we checked earlier
144154
throw createError(404, `Package ${pkg} not found in ${universe}`);
145155
var pkgdata = group_package_data(docs);
@@ -416,9 +426,9 @@ export function get_bucket_stream(hash){
416426
}
417427
}
418428

419-
export function get_package_info(pkg, universe){
429+
export function get_package_info(pkg, universe, fields){
420430
if(production){
421-
return mongo_package_info(pkg, universe);
431+
return mongo_package_info(pkg, universe, fields);
422432
} else {
423433
console.warn(`Fetching ${pkg} info from API...`)
424434
if(universe){
@@ -463,7 +473,7 @@ export function get_universe_vignettes(universe){
463473

464474
export function get_universe_packages(universe, fields, limit = 5000){
465475
if(production){
466-
return mongo_universe_packages(universe, fields, limit)
476+
return mongo_universe_packages(universe, fields, limit);
467477
} else {
468478
console.warn(`Fetching ${universe} packages from API...`)
469479
var apiurl = `https://${universe}.r-universe.dev/api/packages?stream=1&all=true&limit=${limit}&fields=${fields.join()}`;
@@ -554,7 +564,6 @@ export function get_packages_index(query, fields = [], mixed = false){
554564
if(production){
555565
let projection = {...pkgfields};
556566
fields.forEach(function (f) {
557-
console.log("adding", f)
558567
projection[f] = 1;
559568
});
560569
var cursor = mixed ? mongo_aggregate([

src/tools.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Buffer} from "node:buffer";
22
import tar from 'tar-stream';
3+
import zlib from 'node:zlib';
34
import gunzip from 'gunzip-maybe';
45
import {load as cheerio_load} from 'cheerio';
56
import hljs from 'highlight.js';
@@ -165,6 +166,22 @@ export function doc_to_dcf(doc){
165166
}).join("\n") + "\n\n";
166167
}
167168

169+
export function doc_to_ndjson(x){
170+
return JSON.stringify(x) + '\n';
171+
}
172+
173+
// Somehow node:stream/promises does not catch input on-error callbacks properly
174+
// so we promisify ourselves. See https://github.com/r-universe-org/help/issues/540
175+
export function cursor_stream(cursor, output, transform, gzip){
176+
return new Promise(function(resolve, reject) {
177+
var input = cursor.stream({transform: transform}).on('error', reject);
178+
if(gzip){
179+
input = input.pipe(zlib.createGzip()).on('error', reject);
180+
}
181+
input.pipe(output).on('finish', resolve).on('error', reject);
182+
});
183+
}
184+
168185
export function match_macos_arch(platform){
169186
if(platform.match("arm64|aarch64")){
170187
return {$not : /x86_64/};

0 commit comments

Comments
 (0)