Skip to content

Commit 173200b

Browse files
committed
fix plugin loading
1 parent e08817c commit 173200b

File tree

3 files changed

+88
-70
lines changed

3 files changed

+88
-70
lines changed

src/library/plugin/pluginLoader.ts

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { z } from "zod";
1212
import env from 'env-var';
1313
import { existsSync } from 'fs';
1414
import fs from 'fs/promises';
15-
import { fromFailablePromise } from "../../utils/TaskEither";
15+
import { fromFailablePromise, liftZodParseResult } from "../../utils/TaskEither";
1616

1717
export const configurationSchema = z.object({
1818
pluginDir: z.string().optional(),
@@ -25,37 +25,37 @@ export const configurationSchema = z.object({
2525

2626
export type Configuration = z.infer<typeof configurationSchema>;
2727

28+
export const _readConfiguration =
29+
<T>(parseConfiguration: (s: string) => z.SafeParseReturnType<T, T>) =>
30+
(cfgPath?: string):
31+
TaskEither<string, T> =>
32+
pipe(
33+
TE.Do,
34+
TE.bind('finalCfgPath',
35+
(_) => TE.fromIOEither(() => {
36+
const finalCfgPath =
37+
path.resolve(cfgPath ?? env.get('MINAUTH_CONFIG')
38+
.default("config.yaml")
39+
.asString())
40+
41+
console.log(`reading configuration from ${finalCfgPath}`);
42+
43+
return existsSync(finalCfgPath) ?
44+
E.right(finalCfgPath) :
45+
E.left('configuration file does not exists');
46+
})
47+
),
48+
TE.bind('cfgFileContent', ({ finalCfgPath }) =>
49+
fromFailablePromise<string>(() => fs.readFile(finalCfgPath, 'utf-8'))
50+
),
51+
TE.chain(
52+
({ cfgFileContent }) =>
53+
liftZodParseResult(parseConfiguration(cfgFileContent))
54+
)
55+
);
56+
2857
export const readConfiguration =
29-
(cfgPath?: string):
30-
TaskEither<string, Configuration> =>
31-
pipe(
32-
TE.Do,
33-
TE.bind('finalCfgPath',
34-
(_) => TE.fromIOEither(() => {
35-
const finalCfgPath =
36-
path.resolve(cfgPath ?? env.get('MINAUTH_CONFIG')
37-
.default("config.yaml")
38-
.asString())
39-
40-
console.log(`reading configuration from ${finalCfgPath}`);
41-
42-
return existsSync(finalCfgPath) ?
43-
E.right(finalCfgPath) :
44-
E.left('configuration file does not exists');
45-
})
46-
),
47-
TE.bind('cfgFileContent', ({ finalCfgPath }) =>
48-
fromFailablePromise<string>(() => fs.readFile(finalCfgPath, 'utf-8'))
49-
),
50-
TE.chain(
51-
({ cfgFileContent }) => {
52-
const parseResult = configurationSchema.safeParse(cfgFileContent);
53-
const ret = parseResult.success ?
54-
E.right(parseResult.data as Configuration) :
55-
E.left(`error while parsing configuration: ${parseResult.error}`);
56-
return TE.fromEither(ret);
57-
})
58-
)
58+
_readConfiguration(configurationSchema.safeParse)
5959

6060
//
6161

@@ -73,7 +73,7 @@ const importPluginModule =
7373

7474
const validatePluginCfg =
7575
(cfg: any, factory: UntypedPluginFactory): TaskEither<string, any> =>
76-
fromFailablePromise(() => factory.configurationSchema.parseAsync(cfg));
76+
liftZodParseResult(factory.configurationSchema.safeParse(cfg));
7777

7878
const initializePlugin =
7979
(pluginModulePath: string, pluginCfg: any): TaskEither<string, UntypedPlugin> =>
@@ -87,7 +87,7 @@ const initializePlugin =
8787
validatePluginCfg(pluginCfg, pluginFactory)),
8888
TE.chain(({ pluginFactory, typedPluginCfg }) =>
8989
pluginFactory.initialize(typedPluginCfg))
90-
)
90+
);
9191

9292
export const initializePlugins =
9393
(cfg: Configuration): TaskEither<string, Record<string, UntypedPlugin>> => {
@@ -101,16 +101,18 @@ export const initializePlugins =
101101
return optionalPath === undefined ?
102102
path.join(dir, name) :
103103
path.resolve(optionalPath)
104-
}
104+
};
105105

106106
const resolveModulePathAndInitializePlugin =
107107
(pluginName: string, pluginCfg: {
108108
path?: string | undefined;
109109
config?: any;
110110
}): TaskEither<string, UntypedPlugin> =>
111-
TE.chain
112-
((modulePath: string) => initializePlugin(modulePath, pluginCfg ?? {}))
113-
(TE.fromIO(resolvePluginModulePath(pluginName, pluginCfg.path)))
111+
pipe(
112+
TE.fromIO(resolvePluginModulePath(pluginName, pluginCfg.path)),
113+
TE.chain
114+
((modulePath: string) => initializePlugin(modulePath, pluginCfg.config ?? {}))
115+
);
114116

115117
const Applicative =
116118
TE.getApplicativeTaskValidation(T.ApplyPar,
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { z } from 'zod';
2+
import * as PL from '../../plugin/pluginLoader';
3+
import { pipe } from 'fp-ts/function';
4+
import * as TE from 'fp-ts/TaskEither';
5+
6+
export const configurationSchema =
7+
PL.configurationSchema.extend({
8+
address: z.string().default('127.0.0.1'),
9+
port: z.number().default(3001),
10+
});
11+
12+
export type Configuration = z.infer<typeof configurationSchema>;
13+
14+
const mkPluginDir = (name: string) =>
15+
`${__dirname}/../../../plugins/${name}/server`
16+
17+
export const defaultConfiguration: Configuration =
18+
configurationSchema.parse({
19+
plugins: {
20+
SimplePreimagePlugin: {
21+
path: mkPluginDir("simplePreimage"),
22+
config: {
23+
roles: {}
24+
}
25+
},
26+
MerkleMembershipsPlugin: {
27+
path: mkPluginDir("merkleMemberships"),
28+
config: {
29+
trees: []
30+
}
31+
}
32+
}
33+
});
34+
35+
export const readConfigurationFallback = pipe(
36+
PL._readConfiguration<Configuration>(configurationSchema.safeParse)(),
37+
TE.orElse((error) => {
38+
console.warn(`unable to read configuration: ${error}, use default`);
39+
return TE.right(defaultConfiguration);
40+
}),
41+
TE.tap((cfg) =>
42+
TE.fromIO(() => console.info("configuration", cfg)))
43+
);

src/library/tools/pluginServer/index.ts

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,13 @@ import express, { Request, Response } from 'express';
22
import bodyParser from 'body-parser';
33
import { JsonProof } from 'o1js';
44
import { pipe } from 'fp-ts/lib/function';
5-
import {
6-
Configuration,
7-
configurationSchema,
8-
initializePlugins,
9-
readConfiguration
10-
} from '../../plugin/pluginLoader';
5+
import { initializePlugins } from '../../plugin/pluginLoader';
116
import * as TE from 'fp-ts/TaskEither';
127
import * as T from 'fp-ts/Task';
138
import * as E from 'fp-ts/Either';
14-
import path from 'path';
159
import { installCustomRoutes, verifyProof } from '../../plugin/utils';
1610
import { Either } from 'fp-ts/Either';
17-
18-
const address = "127.0.0.1";
19-
const port = 3001;
20-
21-
const defaultConfiguration: Configuration =
22-
configurationSchema.parse({
23-
pluginDefaultRoot: path.join(process.cwd(), 'dist/src/plugins'),
24-
plugins: {
25-
SimplePreimagePlugin: { config: { roles: {} } },
26-
MerkleMembershipsPlugin: { config: { trees: [] } }
27-
}
28-
});
29-
30-
const readConfigurationFallback = pipe(
31-
readConfiguration(),
32-
TE.orElse((error) => {
33-
console.warn(`unable to read configuration: ${error}, use default`);
34-
return TE.right(defaultConfiguration);
35-
}),
36-
TE.tap((cfg) =>
37-
TE.fromIO(() => console.info("configuration", cfg)))
38-
);
11+
import { readConfigurationFallback } from './config';
3912

4013
interface VerifyProofData {
4114
plugin: string;
@@ -50,7 +23,7 @@ const main =
5023
TE.tap((_) => TE.fromIO(() => console.info("initializing plugins"))),
5124
TE.bind('activePlugins', ({ cfg }) => initializePlugins(cfg)),
5225
TE.bind('app', (_) => TE.fromIO(express)),
53-
TE.tap(({ app, activePlugins }) => pipe
26+
TE.tap(({ app, activePlugins, cfg }) => pipe
5427
(
5528
TE.fromIO(() => {
5629
app.use(bodyParser.json());
@@ -74,14 +47,14 @@ const main =
7447
T.map((_) => { })
7548
)();
7649
})
77-
.listen(port, address, () =>
78-
console.log(`Server is running on http://${address}:${port}`));
50+
.listen(cfg.port, cfg.address, () =>
51+
console.log(`Server is running on http://${cfg.address}:${cfg.port}`));
7952
}))
8053
)
8154
),
8255
TE.tapError(
8356
(error) => (): Promise<Either<string, never>> => {
84-
console.error("unhandled error", error);
57+
console.error(`unhandled error: ${error}`);
8558
process.exit(1);
8659
}
8760
)

0 commit comments

Comments
 (0)