1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | import {
|
18 | ConfigurationAware,
|
19 | HandlerContext,
|
20 | } from "@atomist/automation-client";
|
21 | import {
|
22 | PreferenceScope,
|
23 | PreferenceStore,
|
24 | } from "@atomist/sdm";
|
25 |
|
26 | export interface Preference {
|
27 | name: string;
|
28 | namespace: string;
|
29 | value: string;
|
30 | ttl: number;
|
31 | }
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | export abstract class AbstractPreferenceStore implements PreferenceStore {
|
37 |
|
38 | protected constructor(private readonly ctx: HandlerContext) {
|
39 | }
|
40 |
|
41 | public async get<V>(key: string,
|
42 | options: { scope?: PreferenceScope | string, defaultValue?: V } = {}): Promise<V | undefined> {
|
43 | const pref = await this.doGet(key, this.scope(options.scope));
|
44 | const defaultValue = !!options ? options.defaultValue : undefined;
|
45 | if (!pref) {
|
46 | return defaultValue;
|
47 | }
|
48 | if (!!pref.ttl && pref.ttl < Date.now()) {
|
49 | return defaultValue;
|
50 | } else {
|
51 | return JSON.parse(pref.value) as V;
|
52 | }
|
53 | }
|
54 |
|
55 | public async put<V>(key: string,
|
56 | value: V,
|
57 | options: { scope?: PreferenceScope | string, ttl?: number } = {}): Promise<V> {
|
58 | const pref: Preference = {
|
59 | name: key,
|
60 | namespace: this.scope(options.scope),
|
61 | value: JSON.stringify(value),
|
62 | ttl: options.ttl,
|
63 | };
|
64 | await this.doPut(pref);
|
65 | return value;
|
66 | }
|
67 |
|
68 | public async list<V>(scope: PreferenceScope | string): Promise<Array<{ key: string; value: V }>> {
|
69 | const prefs = await this.doList(this.scope(scope));
|
70 | if (!prefs) {
|
71 | return [];
|
72 | } else {
|
73 | const values: Array<{ key: string, value: V }> = prefs.map(pref => {
|
74 | if (!!pref.ttl && pref.ttl < Date.now()) {
|
75 | return undefined;
|
76 | } else {
|
77 | return { key: pref.name, value: JSON.parse(pref.value) as V };
|
78 | }
|
79 | });
|
80 | return values.filter(v => !!v);
|
81 | }
|
82 | }
|
83 |
|
84 | public async delete(key: string, options: { scope?: PreferenceScope | string } = {}): Promise<void> {
|
85 | return this.doDelete(key, this.scope(options.scope));
|
86 | }
|
87 |
|
88 | protected abstract doGet(key: string, namespace: string): Promise<Preference | undefined>;
|
89 |
|
90 | protected abstract doPut(pref: Preference): Promise<void>;
|
91 |
|
92 | protected abstract doList(namespace: string): Promise<Preference[]>;
|
93 |
|
94 | protected abstract doDelete(key: string, namespace: string): Promise<void>;
|
95 |
|
96 | protected scopeKey(key: string, scope?: string): string {
|
97 | if (!!scope && scope.length > 0) {
|
98 | return `${scope}_$_${key}`;
|
99 | }
|
100 | return key;
|
101 | }
|
102 |
|
103 | protected scope(scope: PreferenceScope | string): string {
|
104 | if (!!scope) {
|
105 | switch (scope) {
|
106 | case PreferenceScope.Sdm:
|
107 | return (this.ctx as any as ConfigurationAware).configuration.name;
|
108 | case PreferenceScope.Workspace:
|
109 | return "";
|
110 | default:
|
111 | return scope;
|
112 | }
|
113 | }
|
114 | return "";
|
115 | }
|
116 | }
|