Skip to content

Commit 53dfd69

Browse files
Merge branch 'callback-to-promises' into add-express-promise-router
2 parents c71f414 + a134c55 commit 53dfd69

10 files changed

+289
-130
lines changed

src/registry/domain/components-cache/components-list.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
1-
import { promisify } from 'util';
21
import semver from 'semver';
32
import pLimit from 'p-limit';
43
import getUnixUTCTimestamp from 'oc-get-unix-utc-timestamp';
5-
import { Cdn, ComponentsList, Config } from '../../../types';
4+
import { ComponentsList, Config } from '../../../types';
5+
import { StorageAdapter } from 'oc-storage-adapters-utils';
66

7-
export default function componentsList(conf: Config, cdn: Cdn) {
7+
export default function componentsList(conf: Config, cdn: StorageAdapter) {
88
const filePath = (): string =>
99
`${conf.storage.options.componentsDir}/components.json`;
1010

1111
const componentsList = {
12-
getFromJson: (): Promise<ComponentsList> =>
13-
promisify(cdn.getJson)(filePath(), true),
12+
getFromJson: (): Promise<ComponentsList> => cdn.getJson(filePath(), true),
1413

1514
getFromDirectories: async (): Promise<ComponentsList> => {
1615
const componentsInfo: Dictionary<string[]> = {};
1716

1817
const getVersionsForComponent = async (
1918
componentName: string
2019
): Promise<string[]> => {
21-
const versions = await promisify(cdn.listSubDirectories)(
20+
const versions = await cdn.listSubDirectories(
2221
`${conf.storage.options.componentsDir}/${componentName}`
2322
);
2423

2524
return versions.sort(semver.compare);
2625
};
2726

2827
try {
29-
const components = await promisify(cdn.listSubDirectories)(
28+
const components = await cdn.listSubDirectories(
3029
conf.storage.options.componentsDir
3130
);
3231
const limit = pLimit(cdn.maxConcurrentRequests);
@@ -64,7 +63,7 @@ export default function componentsList(conf: Config, cdn: Cdn) {
6463
},
6564

6665
save: (data: ComponentsList): Promise<unknown> =>
67-
promisify(cdn.putFileContent)(JSON.stringify(data), filePath(), true)
66+
cdn.putFileContent(JSON.stringify(data), filePath(), true)
6867
};
6968

7069
return componentsList;

src/registry/domain/components-cache/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import _ from 'lodash';
22
import getComponentsList from './components-list';
33
import * as eventsHandler from '../events-handler';
44
import getUnixUTCTimestamp from 'oc-get-unix-utc-timestamp';
5-
import { Cdn, ComponentsList, Config } from '../../../types';
5+
import { ComponentsList, Config } from '../../../types';
6+
import { StorageAdapter } from 'oc-storage-adapters-utils';
67

7-
export default function componentsCache(conf: Config, cdn: Cdn) {
8+
export default function componentsCache(conf: Config, cdn: StorageAdapter) {
89
let cachedComponentsList: ComponentsList;
910
let refreshLoop: NodeJS.Timeout;
1011

@@ -36,8 +37,8 @@ export default function componentsCache(conf: Config, cdn: Cdn) {
3637
return data;
3738
};
3839

39-
const throwError = (code: string, message: unknown) => {
40-
eventsHandler.fire('error', { code, message });
40+
const throwError = (code: string, message: any) => {
41+
eventsHandler.fire('error', { code, message: message?.message ?? message });
4142
throw code;
4243
};
4344

src/registry/domain/components-details.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
import { promisify } from 'util';
21
import pLimit from 'p-limit';
32
import _ from 'lodash';
43
import * as eventsHandler from './events-handler';
54
import getUnixUTCTimestamp from 'oc-get-unix-utc-timestamp';
65
import {
7-
Cdn,
86
Component,
97
ComponentsDetails,
108
ComponentsList,
119
Config
1210
} from '../../types';
11+
import { StorageAdapter } from 'oc-storage-adapters-utils';
1312

14-
export default function componentsDetails(conf: Config, cdn: Cdn) {
15-
const returnError = (code: string, message: unknown) => {
16-
eventsHandler.fire('error', { code, message });
13+
export default function componentsDetails(conf: Config, cdn: StorageAdapter) {
14+
const returnError = (code: string, message: any) => {
15+
eventsHandler.fire('error', { code, message: message?.message ?? message });
1716
throw code;
1817
};
1918

2019
const filePath = (): string =>
2120
`${conf.storage.options.componentsDir}/components-details.json`;
2221

2322
const getFromJson = (): Promise<ComponentsDetails> =>
24-
promisify(cdn.getJson)(filePath(), true);
23+
cdn.getJson(filePath(), true);
2524

2625
const getFromDirectories = async (options: {
2726
componentsList: ComponentsList;
@@ -45,7 +44,7 @@ export default function componentsDetails(conf: Config, cdn: Cdn) {
4544
await Promise.all(
4645
missing.map(({ name, version }) =>
4746
limit(async () => {
48-
const content: Component = await promisify(cdn.getJson)(
47+
const content: Component = await cdn.getJson(
4948
`${conf.storage.options.componentsDir}/${name}/${version}/package.json`,
5049
true
5150
);
@@ -63,7 +62,7 @@ export default function componentsDetails(conf: Config, cdn: Cdn) {
6362
};
6463

6564
const save = (data: ComponentsDetails): Promise<unknown> =>
66-
promisify(cdn.putFileContent)(JSON.stringify(data), filePath(), true);
65+
cdn.putFileContent(JSON.stringify(data), filePath(), true);
6766

6867
const refresh = async (
6968
componentsList: ComponentsList

src/registry/domain/repository.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import fs from 'fs-extra';
2-
import { promisify } from 'util';
32
import getUnixUtcTimestamp from 'oc-get-unix-utc-timestamp';
43
import path from 'path';
54
import _ from 'lodash';
@@ -10,16 +9,20 @@ import registerTemplates from './register-templates';
109
import settings from '../../resources/settings';
1110
import strings from '../../resources';
1211
import * as validator from './validators';
12+
import getPromiseBasedAdapter from './storage-adapter';
1313
import * as versionHandler from './version-handler';
1414
import errorToString from '../../utils/error-to-string';
15-
import { Cdn, Component, Config, Repository } from '../../types';
15+
import { Component, Config, Repository } from '../../types';
16+
import { StorageAdapter } from 'oc-storage-adapters-utils';
1617

1718
const packageInfo = fs.readJsonSync(
1819
path.join(__dirname, '..', '..', '..', 'package.json')
1920
);
2021

2122
export default function repository(conf: Config): Repository {
22-
const cdn: Cdn = !conf.local && conf.storage.adapter(conf.storage.options);
23+
const cdn: StorageAdapter =
24+
!conf.local &&
25+
(getPromiseBasedAdapter(conf.storage.adapter(conf.storage.options)) as any);
2326
const options = !conf.local ? conf.storage.options : null;
2427
const repositorySource = conf.local
2528
? 'local repository'
@@ -111,7 +114,7 @@ export default function repository(conf: Config): Repository {
111114
return Promise.resolve(local.getCompiledView(componentName));
112115
}
113116

114-
return promisify(cdn.getFile)(
117+
return cdn.getFile(
115118
getFilePath(componentName, componentVersion, 'template.js')
116119
);
117120
},
@@ -171,7 +174,7 @@ export default function repository(conf: Config): Repository {
171174
}
172175
}
173176

174-
return promisify(cdn.getJson)<Component>(
177+
return cdn.getJson<Component>(
175178
getFilePath(componentName, componentVersion, 'package.json'),
176179
false
177180
);
@@ -220,7 +223,7 @@ export default function repository(conf: Config): Repository {
220223
'server.js'
221224
);
222225

223-
const content = await promisify(cdn.getFile)(filePath);
226+
const content = await cdn.getFile(filePath);
224227

225228
return { content, filePath };
226229
},
@@ -327,7 +330,7 @@ export default function repository(conf: Config): Repository {
327330
pkgDetails.packageJson
328331
);
329332

330-
await promisify(cdn.putDir)(
333+
await cdn.putDir(
331334
pkgDetails.outputFolder,
332335
`${options!.componentsDir}/${componentName}/${componentVersion}`
333336
);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { fromCallback } from 'universalify';
2+
import { StorageAdapter } from 'oc-storage-adapters-utils';
3+
4+
type RemovePromiseOverload<T> = T extends {
5+
(...args: infer B): void;
6+
(...args: any[]): Promise<any>;
7+
}
8+
? (...args: B) => void
9+
: T;
10+
11+
type LegacyStorageAdapter = {
12+
[P in keyof StorageAdapter]: RemovePromiseOverload<StorageAdapter[P]>;
13+
};
14+
15+
const officialAdapters = {
16+
s3: { name: 'oc-s3-storage-adapter', firstPromiseBasedVersion: '1.2.0' },
17+
gs: { name: 'oc-gs-storage-adapter', firstPromiseBasedVersion: '1.1.0' },
18+
'azure-blob-storage': {
19+
name: 'oc-azure-storage-adapter',
20+
firstPromiseBasedVersion: '0.1.0'
21+
}
22+
};
23+
type OfficialAdapter = keyof typeof officialAdapters;
24+
25+
function isOfficialAdapter(
26+
adapter: LegacyStorageAdapter
27+
): adapter is LegacyStorageAdapter & { adapterType: OfficialAdapter } {
28+
return Object.keys(officialAdapters).includes(
29+
adapter.adapterType as OfficialAdapter
30+
);
31+
}
32+
33+
function isPromiseBased(tryFunction: () => unknown) {
34+
try {
35+
(tryFunction as () => Promise<unknown>)().catch(() => {
36+
// To not throw unhandled promise exceptions
37+
});
38+
return true;
39+
} catch (err) {
40+
return false;
41+
}
42+
}
43+
44+
function isLegacyAdapter(
45+
adapter: StorageAdapter | LegacyStorageAdapter
46+
): adapter is LegacyStorageAdapter {
47+
return !isPromiseBased(() => (adapter as StorageAdapter).getFile(''));
48+
}
49+
50+
function convertLegacyAdapter(adapter: LegacyStorageAdapter): StorageAdapter {
51+
return {
52+
getFile: fromCallback(adapter.getFile),
53+
getJson: fromCallback(adapter.getJson),
54+
listSubDirectories: fromCallback(adapter.listSubDirectories),
55+
putDir: fromCallback(adapter.putDir),
56+
putFile: fromCallback(adapter.putFile),
57+
putFileContent: fromCallback(adapter.putFileContent),
58+
getUrl: adapter.getUrl,
59+
maxConcurrentRequests: adapter.maxConcurrentRequests,
60+
adapterType: adapter.adapterType
61+
};
62+
}
63+
64+
export default function getPromiseBasedAdapter(
65+
adapter: StorageAdapter | LegacyStorageAdapter
66+
): StorageAdapter {
67+
if (isLegacyAdapter(adapter)) {
68+
if (isOfficialAdapter(adapter)) {
69+
const pkg = officialAdapters[adapter.adapterType];
70+
process.emitWarning(
71+
`Adapters now should work with promises. Consider upgrading your package ${pkg.name} to at least version ${pkg.firstPromiseBasedVersion}`,
72+
'DeprecationWarning'
73+
);
74+
} else {
75+
process.emitWarning(
76+
'Your adapter is using the old interface of working with callbacks. Consider upgrading it to work with promises, as the previous one will be deprecated.',
77+
'DeprecationWarning'
78+
);
79+
}
80+
81+
return convertLegacyAdapter(adapter);
82+
}
83+
84+
return adapter;
85+
}

src/types.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,6 @@ export interface Config {
168168
verbosity: number;
169169
}
170170

171-
export interface Cdn {
172-
adapterType: string;
173-
getFile: (filePath: string, cb: Callback<string>) => void;
174-
getJson<T>(filePath: string, force: boolean, cb: Callback<T, string>): void;
175-
listSubDirectories: (
176-
dir: string,
177-
cb: Callback<string[], Error & { code?: string }>
178-
) => void;
179-
maxConcurrentRequests: number;
180-
putDir: (folderPath: string, filePath: string, cb: Callback) => void;
181-
putFileContent: (
182-
data: unknown,
183-
path: string,
184-
isPrivate: boolean,
185-
callback: Callback<unknown, string>
186-
) => void;
187-
}
188-
189171
type CompiledTemplate = (model: unknown) => string;
190172

191173
interface CompilerOptions {

0 commit comments

Comments
 (0)