@taqueria/protocol 0.3.1 → 0.4.0-rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Alias.ts +38 -0
- package/Base.ts +105 -0
- package/Command.ts +24 -0
- package/Config.ts +155 -0
- package/Crypto.ts +3 -0
- package/EconomicalProtocolHash.ts +26 -0
- package/Environment.ts +36 -0
- package/EphemeralState.ts +208 -0
- package/Faucet.ts +46 -0
- package/HumanReadableIdentifier.ts +24 -0
- package/InstalledPlugin.ts +28 -0
- package/LoadedConfig.ts +45 -0
- package/NetworkConfig.ts +39 -0
- package/Operation.ts +70 -0
- package/Option.ts +56 -0
- package/ParsedOperation.ts +33 -0
- package/ParsedPluginInfo.ts +47 -0
- package/PersistentState.ts +67 -0
- package/PluginInfo.ts +67 -0
- package/PositionalArg.ts +49 -0
- package/Provisioner.ts +61 -0
- package/ProvisionerID.ts +25 -0
- package/Provisions.ts +70 -0
- package/PublicKeyHash.ts +28 -0
- package/README.md +87 -3
- package/RequestArgs.ts +76 -0
- package/SHA256.ts +40 -0
- package/SandboxAccountConfig.ts +35 -0
- package/SandboxConfig.ts +63 -0
- package/SanitizedAbsPath.ts +23 -0
- package/SanitizedArgs.ts +154 -0
- package/SanitizedPath.ts +26 -0
- package/SingleChar.ts +23 -0
- package/TaqError.ts +73 -0
- package/Task.ts +71 -0
- package/Timestamp.ts +25 -0
- package/Tz.ts +22 -0
- package/Url.ts +28 -0
- package/Verb.ts +23 -0
- package/VersionNumber.ts +23 -0
- package/i18n.ts +63 -0
- package/package.json +39 -32
- package/taqueria-protocol-types.ts +90 -608
- package/url-join.ts +0 -73
- package/url-parse.ts +0 -150
package/Alias.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import createType from '@taqueria/protocol/Base';
|
|
2
|
+
import * as SingleChar from '@taqueria/protocol/SingleChar';
|
|
3
|
+
import * as Verb from '@taqueria/protocol/Verb';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
export const rawSchema = z
|
|
7
|
+
.union([
|
|
8
|
+
Verb.rawSchema,
|
|
9
|
+
SingleChar.rawSchema,
|
|
10
|
+
], { description: 'Alias' });
|
|
11
|
+
|
|
12
|
+
export const internalSchema = z
|
|
13
|
+
.union([
|
|
14
|
+
Verb.schemas.schema,
|
|
15
|
+
SingleChar.schemas.schema,
|
|
16
|
+
], { description: 'Alias' });
|
|
17
|
+
|
|
18
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
19
|
+
type Input = z.infer<typeof internalSchema>;
|
|
20
|
+
|
|
21
|
+
const { schemas: generatedSchemas, factory } = createType<RawInput, Input>({
|
|
22
|
+
isStringLike: true,
|
|
23
|
+
rawSchema,
|
|
24
|
+
internalSchema,
|
|
25
|
+
parseErrMsg: (value: unknown) => `${value} is not a valid alias`,
|
|
26
|
+
unknownErrMsg: 'Something went wrong trying to parse an alias',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export type Alias = z.infer<typeof generatedSchemas.schema>;
|
|
30
|
+
|
|
31
|
+
export type t = Alias;
|
|
32
|
+
|
|
33
|
+
export const { create, of, make } = factory;
|
|
34
|
+
|
|
35
|
+
export const schemas = {
|
|
36
|
+
...generatedSchemas,
|
|
37
|
+
schema: generatedSchemas.schema.transform(val => val as Alias),
|
|
38
|
+
};
|
package/Base.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { toFutureParseErr, toFutureParseUnknownErr } from '@taqueria/protocol/TaqError';
|
|
2
|
+
import { FutureInstance, resolve } from 'fluture';
|
|
3
|
+
import { z, ZodError, ZodSchema } from 'zod';
|
|
4
|
+
|
|
5
|
+
type Future<L, R> = FutureInstance<L, R>;
|
|
6
|
+
|
|
7
|
+
type ErrMsg = string | ((value: unknown) => string);
|
|
8
|
+
|
|
9
|
+
interface CreateSchemaParams {
|
|
10
|
+
rawSchema: ZodSchema;
|
|
11
|
+
internalSchema?: ZodSchema;
|
|
12
|
+
transformer?: (value: unknown) => unknown;
|
|
13
|
+
isStringLike?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface CreateTypeParams extends CreateSchemaParams {
|
|
17
|
+
parseErrMsg: ErrMsg;
|
|
18
|
+
unknownErrMsg: ErrMsg;
|
|
19
|
+
}
|
|
20
|
+
export type Flatten<T> = { [k in keyof T]: T[k] };
|
|
21
|
+
|
|
22
|
+
export const createSchema = <I>(params: CreateSchemaParams) => {
|
|
23
|
+
const { rawSchema, isStringLike } = params;
|
|
24
|
+
const internalSchema = params.internalSchema ?? params.rawSchema;
|
|
25
|
+
const noop = (val: unknown) => val;
|
|
26
|
+
const transformer = params.transformer ?? noop;
|
|
27
|
+
|
|
28
|
+
const schema = isStringLike
|
|
29
|
+
? internalSchema
|
|
30
|
+
.transform((val: unknown) =>
|
|
31
|
+
transformer(val) as I & {
|
|
32
|
+
readonly __kind: 'generated' & z.infer<typeof internalSchema>;
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
: internalSchema
|
|
36
|
+
.transform((val: unknown) =>
|
|
37
|
+
transformer(val) as Flatten<
|
|
38
|
+
I & {
|
|
39
|
+
readonly __kind: 'generated' & z.infer<typeof internalSchema>;
|
|
40
|
+
}
|
|
41
|
+
>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
type GeneratedSchema = typeof schema;
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
rawSchema,
|
|
48
|
+
internalSchema,
|
|
49
|
+
schema,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// TODO:
|
|
54
|
+
// TypeScript appears to have a bug with default generic values
|
|
55
|
+
// For instance, I'd like to use this:
|
|
56
|
+
// export const createType = <R, I = R>(params: CreateTypeParams) => {
|
|
57
|
+
//
|
|
58
|
+
// However, I == unknown when having I default to R if no I was given.
|
|
59
|
+
// So, we need to require R and I explicitly
|
|
60
|
+
export const createType = <R, I>(params: CreateTypeParams) => {
|
|
61
|
+
const schemas = createSchema<I>(params);
|
|
62
|
+
const { parseErrMsg, unknownErrMsg } = params;
|
|
63
|
+
|
|
64
|
+
type T = z.infer<typeof schemas.schema>;
|
|
65
|
+
|
|
66
|
+
const internalOf = (input: unknown) => {
|
|
67
|
+
try {
|
|
68
|
+
return resolve<T>(schemas.schema.parse(input));
|
|
69
|
+
} catch (previous) {
|
|
70
|
+
const parseMsg = typeof parseErrMsg === 'string'
|
|
71
|
+
? parseErrMsg
|
|
72
|
+
: parseErrMsg(input);
|
|
73
|
+
|
|
74
|
+
const unknownMsg = typeof unknownErrMsg === 'string'
|
|
75
|
+
? unknownErrMsg
|
|
76
|
+
: unknownErrMsg(input);
|
|
77
|
+
|
|
78
|
+
if (previous instanceof ZodError) {
|
|
79
|
+
return toFutureParseErr<T>(previous, parseMsg, input);
|
|
80
|
+
}
|
|
81
|
+
return toFutureParseUnknownErr<T>(previous, unknownMsg, input);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const of = internalOf;
|
|
85
|
+
|
|
86
|
+
const make = (input: I) => internalOf(input);
|
|
87
|
+
|
|
88
|
+
const create = (input: R | I) => schemas.schema.parse(input) as T;
|
|
89
|
+
|
|
90
|
+
const from = (input: unknown) => schemas.schema.parse(input) as T;
|
|
91
|
+
|
|
92
|
+
const factory = {
|
|
93
|
+
make,
|
|
94
|
+
of,
|
|
95
|
+
create,
|
|
96
|
+
from,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
schemas,
|
|
101
|
+
factory,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export default createType;
|
package/Command.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import createType from '@taqueria/protocol/Base';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const rawSchema = z
|
|
5
|
+
.string({ description: 'Command' })
|
|
6
|
+
.min(1)
|
|
7
|
+
.regex(/^([A-Za-z-_ ]+ ?)((\[.+\] ?)|(\<.+\>) ?)*$/, 'Must be a command that can be interpreted using yargs');
|
|
8
|
+
|
|
9
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
10
|
+
|
|
11
|
+
const { schemas: generatedSchemas, factory } = createType<RawInput, RawInput>({
|
|
12
|
+
isStringLike: true,
|
|
13
|
+
rawSchema,
|
|
14
|
+
parseErrMsg: (value: unknown) => `${value} is an invalid command. Expected format is: taskName [optional] <required>`,
|
|
15
|
+
unknownErrMsg: 'Something went wrong when parsing the command',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export type Command = z.infer<typeof generatedSchemas.schema>;
|
|
19
|
+
export type t = Command;
|
|
20
|
+
export const { create, make, of } = factory;
|
|
21
|
+
export const schemas = {
|
|
22
|
+
...generatedSchemas,
|
|
23
|
+
schema: generatedSchemas.schema.transform(val => val as Command),
|
|
24
|
+
};
|
package/Config.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import createType, { Flatten } from '@taqueria/protocol/Base';
|
|
2
|
+
import * as Environment from '@taqueria/protocol/Environment';
|
|
3
|
+
import * as InstalledPlugin from '@taqueria/protocol/InstalledPlugin';
|
|
4
|
+
import * as NetworkConfig from '@taqueria/protocol/NetworkConfig';
|
|
5
|
+
import * as SandboxConfig from '@taqueria/protocol/SandboxConfig';
|
|
6
|
+
import * as Tz from '@taqueria/protocol/Tz';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
export const pluginsRawSchema = z.preprocess(
|
|
10
|
+
val => val ?? [],
|
|
11
|
+
z.array(
|
|
12
|
+
InstalledPlugin.rawSchema,
|
|
13
|
+
{ description: 'config.plugins' },
|
|
14
|
+
),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export const pluginsInternalSchema = z.preprocess(
|
|
18
|
+
val => val ?? [],
|
|
19
|
+
z.array(
|
|
20
|
+
InstalledPlugin.schemas.schema,
|
|
21
|
+
{ description: 'config.plugins' },
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const networkMap = z
|
|
26
|
+
.record(
|
|
27
|
+
z.union([
|
|
28
|
+
NetworkConfig.schemas.schema,
|
|
29
|
+
z.string({ description: 'config.network' })
|
|
30
|
+
.nonempty('Default network must reference the name of an existing network configuration.'),
|
|
31
|
+
]),
|
|
32
|
+
{ description: 'Network configurations' },
|
|
33
|
+
)
|
|
34
|
+
.optional();
|
|
35
|
+
|
|
36
|
+
const sandboxMap = z
|
|
37
|
+
.record(
|
|
38
|
+
z.union([
|
|
39
|
+
SandboxConfig.schemas.schema,
|
|
40
|
+
z.string({ description: 'config.sandbox' })
|
|
41
|
+
.min(1, 'Default sandbox must reference the name of an existing sandbox configuration.'),
|
|
42
|
+
]),
|
|
43
|
+
{ description: 'Sandbox configurations' },
|
|
44
|
+
)
|
|
45
|
+
.optional();
|
|
46
|
+
|
|
47
|
+
const environmentMap = z
|
|
48
|
+
.record(
|
|
49
|
+
z.union([
|
|
50
|
+
Environment.schemas.schema,
|
|
51
|
+
z.string().min(1, 'Default environment must reference the name of an existing environment.'),
|
|
52
|
+
]),
|
|
53
|
+
{ description: 'Environment configurations' },
|
|
54
|
+
)
|
|
55
|
+
.optional();
|
|
56
|
+
|
|
57
|
+
const accountsMap = z.preprocess(
|
|
58
|
+
(val: unknown) =>
|
|
59
|
+
val ?? {
|
|
60
|
+
'bob': '5_000_000_000',
|
|
61
|
+
'alice': '5_000_000_000',
|
|
62
|
+
'john': '5_000_000_000',
|
|
63
|
+
},
|
|
64
|
+
z.record(
|
|
65
|
+
z.union([Tz.rawSchema, z.number()]),
|
|
66
|
+
{ description: 'config.accounts' },
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const commonSchema = z.object({
|
|
71
|
+
language: z.preprocess(
|
|
72
|
+
val => val ?? 'en',
|
|
73
|
+
z.union([
|
|
74
|
+
z.literal('en'),
|
|
75
|
+
z.literal('fr'),
|
|
76
|
+
], { description: 'config.language' })
|
|
77
|
+
.optional(),
|
|
78
|
+
),
|
|
79
|
+
plugins: pluginsInternalSchema.optional(),
|
|
80
|
+
contractsDir: z
|
|
81
|
+
.preprocess(
|
|
82
|
+
(val: unknown) => val ?? 'contracts',
|
|
83
|
+
z.string({ description: 'config.contractsDir' })
|
|
84
|
+
.min(1, 'config.contractsDir must have a value'),
|
|
85
|
+
),
|
|
86
|
+
artifactsDir: z
|
|
87
|
+
.preprocess(
|
|
88
|
+
(val: unknown) => val ?? 'artifacts',
|
|
89
|
+
z.string({ description: 'config.artifactsDir' })
|
|
90
|
+
.min(1, 'config.artifactsDir must have a value'),
|
|
91
|
+
),
|
|
92
|
+
}).describe('config');
|
|
93
|
+
|
|
94
|
+
export const internalSchema = commonSchema.extend({
|
|
95
|
+
network: networkMap,
|
|
96
|
+
sandbox: sandboxMap,
|
|
97
|
+
environment: environmentMap,
|
|
98
|
+
accounts: accountsMap,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export const rawSchema = commonSchema.extend({
|
|
102
|
+
plugins: pluginsRawSchema.optional(),
|
|
103
|
+
network: z
|
|
104
|
+
.record(
|
|
105
|
+
z.union([
|
|
106
|
+
NetworkConfig.rawSchema,
|
|
107
|
+
z.string({ description: 'config.network' })
|
|
108
|
+
.min(1, 'Default network must reference the name of an existing network configuration.'),
|
|
109
|
+
]),
|
|
110
|
+
)
|
|
111
|
+
.optional(),
|
|
112
|
+
sandbox: z
|
|
113
|
+
.record(
|
|
114
|
+
z.union([
|
|
115
|
+
SandboxConfig.rawSchema,
|
|
116
|
+
z.string({ description: 'config.sandbox' })
|
|
117
|
+
.min(1, 'Default sandbox must reference the name of an existing sandbox configuration.'),
|
|
118
|
+
]),
|
|
119
|
+
)
|
|
120
|
+
.optional(),
|
|
121
|
+
environment: z
|
|
122
|
+
.record(
|
|
123
|
+
z.union([
|
|
124
|
+
Environment.rawSchema,
|
|
125
|
+
z.string({ description: 'config.environment' })
|
|
126
|
+
.min(1, 'Default environment must reference the name of an existing environment.'),
|
|
127
|
+
]),
|
|
128
|
+
)
|
|
129
|
+
.optional(),
|
|
130
|
+
accounts: z
|
|
131
|
+
.record(
|
|
132
|
+
z.union([Tz.rawSchema, z.number()]),
|
|
133
|
+
{ description: 'config.accounts' },
|
|
134
|
+
)
|
|
135
|
+
.optional(),
|
|
136
|
+
}).describe('config');
|
|
137
|
+
|
|
138
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
139
|
+
type Input = z.infer<typeof internalSchema>;
|
|
140
|
+
|
|
141
|
+
export const { schemas: generatedSchemas, factory } = createType<RawInput, Input>({
|
|
142
|
+
rawSchema,
|
|
143
|
+
internalSchema,
|
|
144
|
+
parseErrMsg: (value: unknown) => `${value} is not a configuration`,
|
|
145
|
+
unknownErrMsg: 'Something went wrong trying to parse your configuration',
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export const { create, of, make } = factory;
|
|
149
|
+
export type Config = z.infer<typeof generatedSchemas.schema>;
|
|
150
|
+
export type t = Config;
|
|
151
|
+
|
|
152
|
+
export const schemas = {
|
|
153
|
+
...generatedSchemas,
|
|
154
|
+
schema: generatedSchemas.schema.transform(val => val as Config),
|
|
155
|
+
};
|
package/Crypto.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import createType from '@taqueria/protocol/Base';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const rawSchema = z
|
|
5
|
+
.string({ description: 'Protocol hash' })
|
|
6
|
+
.refine(
|
|
7
|
+
value => (value.length === 51 && value[0] === 'P' && /[A-Za-z0-9]+/.test(value)),
|
|
8
|
+
value => ({ message: `${value} is an invalid hash for an economical protocol` }),
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
12
|
+
|
|
13
|
+
export const { schemas: generatedSchemas, factory } = createType<RawInput, RawInput>({
|
|
14
|
+
rawSchema,
|
|
15
|
+
parseErrMsg: (value: unknown) => `${value} is an invalid economical protocol hash`,
|
|
16
|
+
unknownErrMsg: 'Somethign went wrong trying to parse the economical protocol hash',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export type EconomicalPrototypeHash = z.infer<typeof generatedSchemas.schema>;
|
|
20
|
+
export type t = EconomicalPrototypeHash;
|
|
21
|
+
|
|
22
|
+
export const { create, of, make } = factory;
|
|
23
|
+
export const schemas = {
|
|
24
|
+
...generatedSchemas,
|
|
25
|
+
schema: generatedSchemas.schema.transform(val => val as EconomicalPrototypeHash),
|
|
26
|
+
};
|
package/Environment.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import createType, { Flatten } from '@taqueria/protocol/Base';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const rawSchema = z.object({
|
|
5
|
+
networks: z.array(
|
|
6
|
+
z.string({ description: 'Environment network' })
|
|
7
|
+
.min(1, 'Must reference the name of an existing network configuration'),
|
|
8
|
+
),
|
|
9
|
+
sandboxes: z.array(
|
|
10
|
+
z.string({ description: 'Environment sandbox' })
|
|
11
|
+
.min(1, 'Must reference the name of an existing sandbox configuration'),
|
|
12
|
+
),
|
|
13
|
+
storage: z.record(
|
|
14
|
+
z.any({ description: 'Environment storage value' }),
|
|
15
|
+
{ description: 'Environment storage' },
|
|
16
|
+
)
|
|
17
|
+
.optional(),
|
|
18
|
+
}).describe('Environment Config');
|
|
19
|
+
|
|
20
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
21
|
+
|
|
22
|
+
export const { schemas: generatedSchemas, factory } = createType<RawInput, RawInput>({
|
|
23
|
+
rawSchema,
|
|
24
|
+
parseErrMsg: (value: unknown) => `${value} is not an valid environment configuration`,
|
|
25
|
+
unknownErrMsg: 'Something went wrong trying to parse the environment configuration',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export type Environment = Flatten<z.infer<typeof generatedSchemas.schema>>;
|
|
29
|
+
export type t = Environment;
|
|
30
|
+
|
|
31
|
+
export const { create, make, of, from } = factory;
|
|
32
|
+
|
|
33
|
+
export const schemas = {
|
|
34
|
+
...generatedSchemas,
|
|
35
|
+
schema: generatedSchemas.schema.transform(val => val as Environment),
|
|
36
|
+
};
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import createType from '@taqueria/protocol/Base';
|
|
2
|
+
import * as Command from '@taqueria/protocol/Command';
|
|
3
|
+
import * as Config from '@taqueria/protocol/Config';
|
|
4
|
+
import type { i18n } from '@taqueria/protocol/i18n';
|
|
5
|
+
import * as InstalledPlugin from '@taqueria/protocol/InstalledPlugin';
|
|
6
|
+
import * as Option from '@taqueria/protocol/Option';
|
|
7
|
+
import * as ParsedOperation from '@taqueria/protocol/ParsedOperation';
|
|
8
|
+
import * as ParsedPluginInfo from '@taqueria/protocol/ParsedPluginInfo';
|
|
9
|
+
import { E_TaqError, TaqError } from '@taqueria/protocol/TaqError';
|
|
10
|
+
import * as Task from '@taqueria/protocol/Task';
|
|
11
|
+
import * as Verb from '@taqueria/protocol/Verb';
|
|
12
|
+
import { attemptP, FutureInstance as Future, mapRej, promise } from 'fluture';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
|
|
15
|
+
const eager = <T>(f: Future<TaqError, T>) =>
|
|
16
|
+
promise(
|
|
17
|
+
mapRej((err: TaqError) => new E_TaqError(err))(f),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const taskToPluginMap = z.record(
|
|
21
|
+
z.union([
|
|
22
|
+
InstalledPlugin.schemas.schema,
|
|
23
|
+
Task.schemas.schema,
|
|
24
|
+
], { description: 'Task/Plugin Mapping' }),
|
|
25
|
+
);
|
|
26
|
+
const operationToPluginMap = z.record(
|
|
27
|
+
z.union([
|
|
28
|
+
InstalledPlugin.schemas.schema,
|
|
29
|
+
ParsedOperation.schemas.schema,
|
|
30
|
+
], { description: 'Operation/Plugin Mapping' }),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const rawSchema = z.object({
|
|
34
|
+
build: z.string({ description: 'cache.build' }),
|
|
35
|
+
configHash: z.string({ description: 'cache.configHash' }),
|
|
36
|
+
tasks: taskToPluginMap,
|
|
37
|
+
operations: operationToPluginMap,
|
|
38
|
+
plugins: z.array(ParsedPluginInfo.schemas.schema, { description: 'cache.plugins' }),
|
|
39
|
+
}).describe('Ephemeral State');
|
|
40
|
+
|
|
41
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
42
|
+
|
|
43
|
+
export const { schemas: generatedSchemas, factory } = createType<RawInput, RawInput>({
|
|
44
|
+
rawSchema,
|
|
45
|
+
parseErrMsg: (value: unknown) => `${value} is not a valid representation of ephemeral state`,
|
|
46
|
+
unknownErrMsg: 'Something went wrong when parsing the ephemeral state',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export type EphemeralState = z.infer<typeof generatedSchemas.schema>;
|
|
50
|
+
export type t = EphemeralState;
|
|
51
|
+
export type TaskToPluginMap = z.infer<typeof taskToPluginMap>;
|
|
52
|
+
export type OpToPluginMap = z.infer<typeof operationToPluginMap>;
|
|
53
|
+
|
|
54
|
+
export const { create, of, make } = factory;
|
|
55
|
+
|
|
56
|
+
export const schemas = {
|
|
57
|
+
...generatedSchemas,
|
|
58
|
+
schema: generatedSchemas.schema.transform(val => val as EphemeralState),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Private functions
|
|
63
|
+
*/
|
|
64
|
+
type Counts = Record<Verb.t, ParsedPluginInfo.t[]>;
|
|
65
|
+
const getTaskCounts = (pluginInfo: ParsedPluginInfo.t[]): Counts => {
|
|
66
|
+
return pluginInfo.reduce(
|
|
67
|
+
(retval, pluginInfo) =>
|
|
68
|
+
pluginInfo.tasks === undefined
|
|
69
|
+
? {}
|
|
70
|
+
: pluginInfo.tasks.reduce(
|
|
71
|
+
(retval: Counts, task: Task.t) => {
|
|
72
|
+
const taskName = task.task;
|
|
73
|
+
const providers: ParsedPluginInfo.t[] = retval[taskName]
|
|
74
|
+
? [...retval[taskName], pluginInfo]
|
|
75
|
+
: [pluginInfo];
|
|
76
|
+
const mapping: Counts = {};
|
|
77
|
+
mapping[taskName] = providers.filter(provider => provider !== undefined);
|
|
78
|
+
return { ...retval, ...mapping };
|
|
79
|
+
},
|
|
80
|
+
retval,
|
|
81
|
+
),
|
|
82
|
+
{} as Counts,
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const getOperationCounts = (pluginInfo: ParsedPluginInfo.t[]): Counts => {
|
|
87
|
+
return pluginInfo.reduce(
|
|
88
|
+
(retval, pluginInfo) =>
|
|
89
|
+
pluginInfo.operations === undefined
|
|
90
|
+
? retval
|
|
91
|
+
: pluginInfo.operations.reduce(
|
|
92
|
+
(retval: Counts, operation: ParsedOperation.t) => {
|
|
93
|
+
const operationName = operation.operation;
|
|
94
|
+
const providers = retval[operationName]
|
|
95
|
+
? [...retval[operationName], pluginInfo]
|
|
96
|
+
: [pluginInfo];
|
|
97
|
+
const mapping: Counts = {};
|
|
98
|
+
mapping[operationName] = providers.filter(provider => provider !== undefined);
|
|
99
|
+
return { ...retval, ...mapping };
|
|
100
|
+
},
|
|
101
|
+
retval,
|
|
102
|
+
),
|
|
103
|
+
{} as Counts,
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const toChoices = (plugins: ParsedPluginInfo.t[]) =>
|
|
108
|
+
plugins.reduce(
|
|
109
|
+
(retval, pluginInfo) => {
|
|
110
|
+
return [...retval, pluginInfo.name as string, pluginInfo.alias as string];
|
|
111
|
+
},
|
|
112
|
+
[] as string[],
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const isComposite = (name: Verb.t, counts: Counts) => counts[name].length > 1;
|
|
116
|
+
|
|
117
|
+
const getInstalledPlugin = (config: Config.t, name: string) =>
|
|
118
|
+
config.plugins?.find(
|
|
119
|
+
(plugin: InstalledPlugin.t) => [`taqueria-plugin-${name}`, name].includes(plugin.name),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
export const mapTasksToPlugins = (config: Config.t, pluginInfo: ParsedPluginInfo.t[], i18n: i18n) => {
|
|
123
|
+
const taskCounts = getTaskCounts(pluginInfo);
|
|
124
|
+
return attemptP<TaqError, TaskToPluginMap>(async () =>
|
|
125
|
+
await pluginInfo.reduce(
|
|
126
|
+
async (retval, pluginInfo) =>
|
|
127
|
+
!pluginInfo.tasks
|
|
128
|
+
? Promise.resolve({} as TaskToPluginMap)
|
|
129
|
+
: await pluginInfo.tasks.reduce(
|
|
130
|
+
async (retval, { task }) => {
|
|
131
|
+
if (isComposite(task, taskCounts)) {
|
|
132
|
+
const command = await eager(Command.make(task));
|
|
133
|
+
const compositeTask = await eager(Task.make({
|
|
134
|
+
task,
|
|
135
|
+
command,
|
|
136
|
+
description: i18n.__('providedByMany'),
|
|
137
|
+
hidden: false,
|
|
138
|
+
options: [
|
|
139
|
+
await eager(Option.make({
|
|
140
|
+
flag: await eager(Verb.make('plugin')),
|
|
141
|
+
description: 'Specify which plugin should be used to execute this task',
|
|
142
|
+
choices: toChoices(taskCounts[task]),
|
|
143
|
+
required: true,
|
|
144
|
+
})),
|
|
145
|
+
],
|
|
146
|
+
handler: 'proxy',
|
|
147
|
+
}));
|
|
148
|
+
return { ...await retval, [task]: compositeTask };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Task is provided by just a single plugin
|
|
152
|
+
const installedPlugin = getInstalledPlugin(config, pluginInfo.name);
|
|
153
|
+
return installedPlugin
|
|
154
|
+
? { ...await retval, [task]: installedPlugin }
|
|
155
|
+
: retval;
|
|
156
|
+
},
|
|
157
|
+
retval,
|
|
158
|
+
),
|
|
159
|
+
Promise.resolve({} as TaskToPluginMap),
|
|
160
|
+
)
|
|
161
|
+
).pipe(mapRej(rej => rej as TaqError));
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export const mapOperationsToPlugins = (config: Config.t, pluginInfo: ParsedPluginInfo.t[], i18n: i18n) => {
|
|
165
|
+
const opCounts = getOperationCounts(pluginInfo);
|
|
166
|
+
return attemptP(async () =>
|
|
167
|
+
await pluginInfo.reduce(
|
|
168
|
+
async (retval, pluginInfo) =>
|
|
169
|
+
!pluginInfo.operations
|
|
170
|
+
? Promise.resolve({} as OpToPluginMap)
|
|
171
|
+
: await pluginInfo.operations.reduce(
|
|
172
|
+
async (retval, { operation }) => {
|
|
173
|
+
if (isComposite(operation, opCounts)) {
|
|
174
|
+
const command = await eager(Command.make(operation));
|
|
175
|
+
const compositeOp = await eager(ParsedOperation.make({
|
|
176
|
+
operation,
|
|
177
|
+
command,
|
|
178
|
+
description: i18n.__('providedByMany'),
|
|
179
|
+
options: [
|
|
180
|
+
await eager(Option.make({
|
|
181
|
+
flag: await eager(Verb.make('plugin')),
|
|
182
|
+
description: 'Specify which plugin should be used to execute this operation',
|
|
183
|
+
choices: toChoices(opCounts[operation]),
|
|
184
|
+
required: true,
|
|
185
|
+
})),
|
|
186
|
+
],
|
|
187
|
+
}));
|
|
188
|
+
return { ...await retval, [operation]: compositeOp };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Operation is provided by just a single plugin
|
|
192
|
+
const installedPlugin = getInstalledPlugin(config, pluginInfo.name);
|
|
193
|
+
return installedPlugin
|
|
194
|
+
? { ...await retval, [operation]: installedPlugin }
|
|
195
|
+
: retval;
|
|
196
|
+
},
|
|
197
|
+
retval,
|
|
198
|
+
),
|
|
199
|
+
Promise.resolve({} as OpToPluginMap),
|
|
200
|
+
)
|
|
201
|
+
).pipe(mapRej(rej => rej as TaqError));
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
export const getTasks = (pluginInfo: ParsedPluginInfo.t[]) =>
|
|
205
|
+
pluginInfo.reduce(
|
|
206
|
+
(retval: Task.t[], pluginInfo) => [...retval, ...(pluginInfo.tasks ?? [])],
|
|
207
|
+
[],
|
|
208
|
+
);
|
package/Faucet.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import createType, { Flatten } from '@taqueria/protocol/Base';
|
|
2
|
+
import * as PublicKeyHash from '@taqueria/protocol/PublicKeyHash';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
export const rawSchema = z.object({
|
|
6
|
+
pkh: z.string({ description: 'Faucet Public Key Hash' }).min(1),
|
|
7
|
+
mnemonic: z.array(
|
|
8
|
+
z.string({ description: 'Faucet Mnemonic Word' }).min(1),
|
|
9
|
+
{ description: 'Faucet Mnemonic' },
|
|
10
|
+
),
|
|
11
|
+
email: z.string({ description: 'Faucet E-mail' }).regex(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/),
|
|
12
|
+
password: z.string({ description: 'Faucet Password' }).min(1),
|
|
13
|
+
amount: z.string({ description: 'Faucet Account' }).min(1).regex(/^\d+$/),
|
|
14
|
+
activation_code: z.string({ description: 'Faucet Activation Code' }).min(1),
|
|
15
|
+
}).describe('Faucet');
|
|
16
|
+
|
|
17
|
+
const internalSchema = z.object({
|
|
18
|
+
pkh: PublicKeyHash.schemas.schema,
|
|
19
|
+
mnemonic: z.array(
|
|
20
|
+
z.string({ description: 'Faucet Mnemonic Word' }).nonempty().regex(/^[a-z]{2,}$/),
|
|
21
|
+
{ description: 'Faucet Mnemonic' },
|
|
22
|
+
),
|
|
23
|
+
email: z.string({ description: 'Faucet E-mail' }).regex(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/),
|
|
24
|
+
password: z.string({ description: 'Faucet Password' }).nonempty(),
|
|
25
|
+
amount: z.string({ description: 'Faucet Account' }).nonempty().regex(/^\d+$/),
|
|
26
|
+
activation_code: z.string({ description: 'Faucet Activation Code' }).nonempty(),
|
|
27
|
+
}).describe('Faucet');
|
|
28
|
+
|
|
29
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
30
|
+
type Input = z.infer<typeof internalSchema>;
|
|
31
|
+
|
|
32
|
+
export const { schemas: generatedSchemas, factory } = createType<RawInput, Input>({
|
|
33
|
+
rawSchema,
|
|
34
|
+
internalSchema,
|
|
35
|
+
parseErrMsg: (value: unknown) => `${value} is not a valid faucet configuration`,
|
|
36
|
+
unknownErrMsg: 'Something went wrong trying to parse the faucet',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export type Faucet = Flatten<z.infer<typeof generatedSchemas.schema>>;
|
|
40
|
+
export type t = Faucet;
|
|
41
|
+
export const { create, of, make } = factory;
|
|
42
|
+
|
|
43
|
+
export const schemas = {
|
|
44
|
+
...generatedSchemas,
|
|
45
|
+
schema: generatedSchemas.schema.transform(val => val as Faucet),
|
|
46
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import createType from '@taqueria/protocol/Base';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const rawSchema = z
|
|
5
|
+
.string({ description: 'Human Readable Identifier' })
|
|
6
|
+
.regex(/^[A-Za-z]+[A-Za-z0-9-_ ]*$/, 'Must be a valid human-readable identifier');
|
|
7
|
+
|
|
8
|
+
type RawInput = z.infer<typeof rawSchema>;
|
|
9
|
+
|
|
10
|
+
const { schemas: generatedSchemas, factory } = createType<RawInput, RawInput>({
|
|
11
|
+
isStringLike: true,
|
|
12
|
+
rawSchema,
|
|
13
|
+
parseErrMsg: (value: unknown) => `${value} is not a valid human-readable identifier`,
|
|
14
|
+
unknownErrMsg: 'Something went wrong trying to parse the human readable identifier',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type HumanReadableIdentifier = z.infer<typeof generatedSchemas.schema>;
|
|
18
|
+
export type t = HumanReadableIdentifier;
|
|
19
|
+
export const { create, of, make } = factory;
|
|
20
|
+
|
|
21
|
+
export const schemas = {
|
|
22
|
+
...generatedSchemas,
|
|
23
|
+
schema: generatedSchemas.schema.transform(val => val as HumanReadableIdentifier),
|
|
24
|
+
};
|