-
Notifications
You must be signed in to change notification settings - Fork 1
/
get-all-resource-ids.ts
130 lines (114 loc) · 4.22 KB
/
get-all-resource-ids.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import * as request from 'request';
import * as fs from 'fs';
import {IBundle} from "./spec/bundle";
import {IList} from "./spec/list";
import {Arguments, Argv} from "yargs";
import {CompareOptions} from "./compare";
export class GetAllResourceIdsOptions {
fhir_base: string;
resource_type: string;
out: string;
'as-list-resource' = false;
countPerPage = 100;
}
export class GetAllResourceIds {
private readonly options: GetAllResourceIdsOptions;
public static command = 'get-all-resource-ids <fhir_base> <resource_type>';
public static description = 'Gets all resource ids for the specified resource types';
public static args(yargs: Argv): Argv {
return yargs
.positional('fhir_base', {
type: 'string',
describe: 'The base url of the spec server'
})
.positional('resource_type', {
type: 'string',
describe: 'The resource type to get all resource ids for'
})
.option('out', {
alias: 'a',
describe: 'File path to output the ids to'
})
.option('as-list-resource', {
describe: 'Output as a JSON List resource',
alias: 'l',
type: 'boolean',
default: false
})
.option('count-per-page', {
describe: 'The number of resources to request per page',
alias: 'c',
type: 'number',
default: 100
});
}
public static handler(args: Arguments) {
new GetAllResourceIds(<GetAllResourceIdsOptions><any>args).execute()
.then(() => process.exit(0));
}
constructor(options: GetAllResourceIdsOptions) {
this.options = options;
}
private async submitRequest(url: string): Promise<IBundle> {
return new Promise((resolve, reject) => {
request({ url: url, json: true }, (error, response, body) => {
if (error) {
reject(error);
} else {
resolve(body);
}
});
});
}
private async getNext(url: string, bundle?: IBundle) {
const response: IBundle = await this.submitRequest(url);
response.entry = response.entry || [];
if (response && bundle) {
bundle.entry = bundle.entry.concat(response.entry);
bundle.total = bundle.entry.length;
} else if (!bundle) {
bundle = response;
}
if (response.link) {
const nextLink = response.link.find(l => l.relation === 'next');
if (nextLink) {
console.log(`Get next page of results from ${nextLink.url}`);
await this.getNext(nextLink.url, bundle);
}
}
return bundle;
}
public async execute() {
const startingUrl = this.options.fhir_base + (this.options.fhir_base.endsWith('/') ? '' : '/') + this.options.resource_type + '?_elements=id&_count=' + this.options.countPerPage;
const bundle = await this.getNext(startingUrl);
if (bundle && bundle.entry) {
const ids = bundle.entry.map(e => e.resource.id);
let content: string;
if (this.options["as-list-resource"]) {
const listResource: IList = {
resourceType: 'List',
status: 'current',
mode: 'working',
entry: ids.map(i => {
return {
item: {
reference: `${this.options.resource_type}/${i}`
}
};
})
};
content = JSON.stringify(listResource, null, '\t');
} else {
content = ids.join('\n');
}
if (this.options.out) {
fs.writeFileSync(this.options.out, content);
console.log(`Wrote IDs to ${this.options.out}`);
} else {
console.log(content);
}
} else {
console.log('No bundle or entries returned');
}
}
}