@reventlessdev/reventless-spec 3.0.0-alpha.142 → 3.0.0-alpha.144
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/CHANGELOG.md +21 -0
- package/package.json +2 -2
- package/run-certify-trait.mjs +2 -1
- package/run-generator.mjs +2 -1
- package/run-graft-trait.mjs +2 -1
- package/run-platform-generator.mjs +2 -1
- package/run-trait-manifest.mjs +2 -1
- package/src/CliArgs.res +209 -0
- package/src/CliArgs.res.mjs +325 -0
- package/src/generator/CertifyTrait.res +96 -93
- package/src/generator/CertifyTrait.res.mjs +92 -75
- package/src/generator/GraftTrait.res +147 -148
- package/src/generator/GraftTrait.res.mjs +131 -128
- package/src/generator/PlatformGenerator.res +50 -31
- package/src/generator/PlatformGenerator.res.mjs +107 -76
- package/src/generator/PluginGenerator.res +29 -29
- package/src/generator/PluginGenerator.res.mjs +87 -55
- package/src/generator/TraitManifestCli.res +69 -68
- package/src/generator/TraitManifestCli.res.mjs +67 -51
- package/src/lifecycle/CheckLifecycleModel.res +203 -189
- package/src/lifecycle/CheckLifecycleModel.res.mjs +146 -141
- package/src/types/PrepareAccounts.res +38 -57
- package/src/types/PrepareAccounts.res.mjs +28 -82
|
@@ -62,77 +62,78 @@ let readPackageField = (packageJson: JSON.t, field: string, fallback: string) =>
|
|
|
62
62
|
->Option.flatMap(JSON.Decode.string)
|
|
63
63
|
->Option.getOr(fallback)
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
type args = {traitPackage: string, out: string}
|
|
66
|
+
|
|
67
|
+
let parseArgs = (argv: array<string>): result<args, string> =>
|
|
68
|
+
CliArgs.parse(~strings=["out"], argv)
|
|
69
|
+
->Result.flatMap(a => a->CliArgs.atMost(1))
|
|
70
|
+
->Result.flatMap(a =>
|
|
71
|
+
switch (a->CliArgs.positionals->Array.get(0), a->CliArgs.string("out")) {
|
|
72
|
+
| (None | Some(""), _) => Error("<trait-package> is required.")
|
|
73
|
+
| (Some(_), None) => Error("--out is required.")
|
|
74
|
+
| (Some(traitPackage), Some(out)) => Ok({traitPackage, out})
|
|
71
75
|
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
let cli: CliArgs.cli<args> = {bin: "trait-manifest", usage, parse: parseArgs}
|
|
79
|
+
|
|
80
|
+
let main = () =>
|
|
81
|
+
CliArgs.run(cli, async ({traitPackage, out}) => {
|
|
82
|
+
let base = moduleBase(traitPackage)
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
let packageJson = switch resolveFrom(`${traitPackage}/package.json`) {
|
|
85
|
+
| None =>
|
|
86
|
+
fail(
|
|
87
|
+
`${traitPackage} is not installed here. A manifest is derived from the trait, so ` ++ `the trait has to be resolvable.`,
|
|
88
|
+
)
|
|
89
|
+
JSON.Encode.null
|
|
90
|
+
| Some(path) => NodeFs.readFileSync(path)->JSON.parseOrThrow
|
|
77
91
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| Some(path) => NodeFs.readFileSync(path)->JSON.parseOrThrow
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// The trait's entry module, for what it needs. Absent is refused rather
|
|
92
|
-
// than defaulted to `[]`: "needs nothing" and "nobody said" are different
|
|
93
|
-
// claims, and a listing that could not tell them apart would quietly
|
|
94
|
-
// publish the second as the first.
|
|
95
|
-
let traitModule: traitExports = switch resolveFrom(`${traitPackage}/src/${base}.res.mjs`) {
|
|
96
|
-
| None =>
|
|
97
|
-
fail(
|
|
98
|
-
`${traitPackage} exports no ${base} module, so its capability needs cannot be read.\n` ++
|
|
99
|
-
` A trait states them as a value — an empty array if it brokers nothing — because ` ++ `an unstated need fails silently at run time.`,
|
|
100
|
-
)
|
|
101
|
-
%raw(`undefined`)
|
|
102
|
-
| Some(path) => await dynImport(NodeUrl.pathToFileURL(path)["href"])
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// The emitter is optional: a trait whose graft is all patches has nothing
|
|
106
|
-
// to write, and says so here rather than by failing when someone tries.
|
|
107
|
-
let scaffold: option<scaffoldExports> = switch resolveFrom(
|
|
108
|
-
`${traitPackage}/src/${base}_Scaffold.res.mjs`,
|
|
109
|
-
) {
|
|
110
|
-
| None => None
|
|
111
|
-
| Some(path) => Some(await dynImport(NodeUrl.pathToFileURL(path)["href"]))
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
let manifest: TraitManifest.t = {
|
|
115
|
-
trait: readPackageField(packageJson, "name", traitPackage),
|
|
116
|
-
version: readPackageField(packageJson, "version", "0.0.0"),
|
|
117
|
-
description: readPackageField(packageJson, "description", ""),
|
|
118
|
-
license: readPackageField(packageJson, "license", ""),
|
|
119
|
-
capabilities: traitModule.capabilityNeeds->Array.map(CapabilityNeed.toString),
|
|
120
|
-
config: switch scaffold {
|
|
121
|
-
| Some({configSchema}) => TraitManifest.configFieldsOf(configSchema)
|
|
122
|
-
| None => []
|
|
123
|
-
},
|
|
124
|
-
scaffolded: scaffold->Option.isSome,
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
NodeFs.writeFileSync(out, manifest->TraitManifest.render)
|
|
128
|
-
Console.log(
|
|
129
|
-
`trait-manifest: ${manifest.trait}@${manifest.version} — ` ++
|
|
130
|
-
`${manifest.capabilities->Array.length->Int.toString} capabilit(ies), ` ++
|
|
131
|
-
`${manifest.config->Array.length->Int.toString} config field(s)`,
|
|
92
|
+
|
|
93
|
+
// The trait's entry module, for what it needs. Absent is refused rather
|
|
94
|
+
// than defaulted to `[]`: "needs nothing" and "nobody said" are different
|
|
95
|
+
// claims, and a listing that could not tell them apart would quietly
|
|
96
|
+
// publish the second as the first.
|
|
97
|
+
let traitModule: traitExports = switch resolveFrom(`${traitPackage}/src/${base}.res.mjs`) {
|
|
98
|
+
| None =>
|
|
99
|
+
fail(
|
|
100
|
+
`${traitPackage} exports no ${base} module, so its capability needs cannot be read.\n` ++
|
|
101
|
+
` A trait states them as a value — an empty array if it brokers nothing — because ` ++ `an unstated need fails silently at run time.`,
|
|
132
102
|
)
|
|
133
|
-
|
|
103
|
+
%raw(`undefined`)
|
|
104
|
+
| Some(path) => await dynImport(NodeUrl.pathToFileURL(path)["href"])
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// The emitter is optional: a trait whose graft is all patches has nothing
|
|
108
|
+
// to write, and says so here rather than by failing when someone tries.
|
|
109
|
+
let scaffold: option<scaffoldExports> = switch resolveFrom(
|
|
110
|
+
`${traitPackage}/src/${base}_Scaffold.res.mjs`,
|
|
111
|
+
) {
|
|
112
|
+
| None => None
|
|
113
|
+
| Some(path) => Some(await dynImport(NodeUrl.pathToFileURL(path)["href"]))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let manifest: TraitManifest.t = {
|
|
117
|
+
trait: readPackageField(packageJson, "name", traitPackage),
|
|
118
|
+
version: readPackageField(packageJson, "version", "0.0.0"),
|
|
119
|
+
description: readPackageField(packageJson, "description", ""),
|
|
120
|
+
license: readPackageField(packageJson, "license", ""),
|
|
121
|
+
capabilities: traitModule.capabilityNeeds->Array.map(CapabilityNeed.toString),
|
|
122
|
+
config: switch scaffold {
|
|
123
|
+
| Some({configSchema}) => TraitManifest.configFieldsOf(configSchema)
|
|
124
|
+
| None => []
|
|
125
|
+
},
|
|
126
|
+
scaffolded: scaffold->Option.isSome,
|
|
134
127
|
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
128
|
|
|
138
|
-
|
|
129
|
+
NodeFs.writeFileSync(out, manifest->TraitManifest.render)
|
|
130
|
+
Console.log(
|
|
131
|
+
`trait-manifest: ${manifest.trait}@${manifest.version} — ` ++
|
|
132
|
+
`${manifest.capabilities->Array.length->Int.toString} capabilit(ies), ` ++
|
|
133
|
+
`${manifest.config->Array.length->Int.toString} config field(s)`,
|
|
134
|
+
)
|
|
135
|
+
Console.log(`Wrote: ${out}`)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// No top-level call: `../../run-trait-manifest.mjs` invokes [main], so a test
|
|
139
|
+
// can import this module.
|
|
@@ -6,6 +6,8 @@ import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
|
6
6
|
import * as Nodemodule from "node:module";
|
|
7
7
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
8
8
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
|
+
import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
|
|
10
|
+
import * as CliArgs$Reventless from "../CliArgs.res.mjs";
|
|
9
11
|
import * as TraitManifest$Reventless from "../components/TraitManifest.res.mjs";
|
|
10
12
|
import * as CapabilityNeed$Reventless from "../semantic/CapabilityNeed.res.mjs";
|
|
11
13
|
|
|
@@ -39,60 +41,72 @@ function readPackageField(packageJson, field, fallback) {
|
|
|
39
41
|
return Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(packageJson), o => o[field]), Stdlib_JSON.Decode.string), fallback);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
let
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (match$1 === undefined) {
|
|
60
|
-
return fail("--out is required.\n\n" + usage);
|
|
61
|
-
}
|
|
62
|
-
let base = moduleBase(match);
|
|
63
|
-
let path = resolveFrom(match + `/package.json`);
|
|
64
|
-
let packageJson = path !== undefined ? JSON.parse(Nodefs.readFileSync(path, "utf8")) : (fail(match + ` is not installed here. A manifest is derived from the trait, so the trait has to be resolvable.`), null);
|
|
65
|
-
let path$1 = resolveFrom(match + `/src/` + base + `.res.mjs`);
|
|
66
|
-
let traitModule = path$1 !== undefined ? await import(Nodeurl.pathToFileURL(path$1).href) : (fail(match + ` exports no ` + base + ` module, so its capability needs cannot be read.\n A trait states them as a value — an empty array if it brokers nothing — because an unstated need fails silently at run time.`), undefined);
|
|
67
|
-
let path$2 = resolveFrom(match + `/src/` + base + `_Scaffold.res.mjs`);
|
|
68
|
-
let scaffold = path$2 !== undefined ? await import(Nodeurl.pathToFileURL(path$2).href) : undefined;
|
|
69
|
-
let manifest_trait = readPackageField(packageJson, "name", match);
|
|
70
|
-
let manifest_version = readPackageField(packageJson, "version", "0.0.0");
|
|
71
|
-
let manifest_description = readPackageField(packageJson, "description", "");
|
|
72
|
-
let manifest_license = readPackageField(packageJson, "license", "");
|
|
73
|
-
let manifest_capabilities = traitModule.capabilityNeeds.map(CapabilityNeed$Reventless.toString);
|
|
74
|
-
let manifest_config = scaffold !== undefined ? TraitManifest$Reventless.configFieldsOf(scaffold.configSchema) : [];
|
|
75
|
-
let manifest_scaffolded = Stdlib_Option.isSome(scaffold);
|
|
76
|
-
let manifest = {
|
|
77
|
-
trait: manifest_trait,
|
|
78
|
-
version: manifest_version,
|
|
79
|
-
description: manifest_description,
|
|
80
|
-
license: manifest_license,
|
|
81
|
-
capabilities: manifest_capabilities,
|
|
82
|
-
config: manifest_config,
|
|
83
|
-
scaffolded: manifest_scaffolded
|
|
44
|
+
function parseArgs(argv) {
|
|
45
|
+
return Stdlib_Result.flatMap(Stdlib_Result.flatMap(CliArgs$Reventless.parse(["out"], undefined, undefined, undefined, argv), a => CliArgs$Reventless.atMost(a, 1)), a => {
|
|
46
|
+
let match = CliArgs$Reventless.positionals(a)[0];
|
|
47
|
+
let match$1 = CliArgs$Reventless.string(a, "out");
|
|
48
|
+
if (match !== undefined && match !== "") {
|
|
49
|
+
if (match$1 !== undefined) {
|
|
50
|
+
return {
|
|
51
|
+
TAG: "Ok",
|
|
52
|
+
_0: {
|
|
53
|
+
traitPackage: match,
|
|
54
|
+
out: match$1
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
} else {
|
|
58
|
+
return {
|
|
59
|
+
TAG: "Error",
|
|
60
|
+
_0: "--out is required."
|
|
84
61
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
return {
|
|
65
|
+
TAG: "Error",
|
|
66
|
+
_0: "<trait-package> is required."
|
|
67
|
+
};
|
|
89
68
|
}
|
|
90
|
-
}
|
|
91
|
-
console.log(usage);
|
|
92
|
-
process.exit(argv.length === 0 ? 1 : 0);
|
|
69
|
+
});
|
|
93
70
|
}
|
|
94
71
|
|
|
95
|
-
|
|
72
|
+
let cli = {
|
|
73
|
+
bin: "trait-manifest",
|
|
74
|
+
usage: usage,
|
|
75
|
+
parse: parseArgs
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
function main() {
|
|
79
|
+
return CliArgs$Reventless.run(cli, undefined, undefined, async param => {
|
|
80
|
+
let out = param.out;
|
|
81
|
+
let traitPackage = param.traitPackage;
|
|
82
|
+
let base = moduleBase(traitPackage);
|
|
83
|
+
let path = resolveFrom(traitPackage + `/package.json`);
|
|
84
|
+
let packageJson = path !== undefined ? JSON.parse(Nodefs.readFileSync(path, "utf8")) : (fail(traitPackage + ` is not installed here. A manifest is derived from the trait, so the trait has to be resolvable.`), null);
|
|
85
|
+
let path$1 = resolveFrom(traitPackage + `/src/` + base + `.res.mjs`);
|
|
86
|
+
let traitModule = path$1 !== undefined ? await import(Nodeurl.pathToFileURL(path$1).href) : (fail(traitPackage + ` exports no ` + base + ` module, so its capability needs cannot be read.\n A trait states them as a value — an empty array if it brokers nothing — because an unstated need fails silently at run time.`), undefined);
|
|
87
|
+
let path$2 = resolveFrom(traitPackage + `/src/` + base + `_Scaffold.res.mjs`);
|
|
88
|
+
let scaffold = path$2 !== undefined ? await import(Nodeurl.pathToFileURL(path$2).href) : undefined;
|
|
89
|
+
let manifest_trait = readPackageField(packageJson, "name", traitPackage);
|
|
90
|
+
let manifest_version = readPackageField(packageJson, "version", "0.0.0");
|
|
91
|
+
let manifest_description = readPackageField(packageJson, "description", "");
|
|
92
|
+
let manifest_license = readPackageField(packageJson, "license", "");
|
|
93
|
+
let manifest_capabilities = traitModule.capabilityNeeds.map(CapabilityNeed$Reventless.toString);
|
|
94
|
+
let manifest_config = scaffold !== undefined ? TraitManifest$Reventless.configFieldsOf(scaffold.configSchema) : [];
|
|
95
|
+
let manifest_scaffolded = Stdlib_Option.isSome(scaffold);
|
|
96
|
+
let manifest = {
|
|
97
|
+
trait: manifest_trait,
|
|
98
|
+
version: manifest_version,
|
|
99
|
+
description: manifest_description,
|
|
100
|
+
license: manifest_license,
|
|
101
|
+
capabilities: manifest_capabilities,
|
|
102
|
+
config: manifest_config,
|
|
103
|
+
scaffolded: manifest_scaffolded
|
|
104
|
+
};
|
|
105
|
+
Nodefs.writeFileSync(out, TraitManifest$Reventless.render(manifest), "utf8");
|
|
106
|
+
console.log(`trait-manifest: ` + manifest_trait + `@` + manifest_version + ` — ` + (manifest_capabilities.length.toString() + ` capabilit(ies), `) + (manifest_config.length.toString() + ` config field(s)`));
|
|
107
|
+
console.log(`Wrote: ` + out);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
96
110
|
|
|
97
111
|
export {
|
|
98
112
|
fail,
|
|
@@ -100,6 +114,8 @@ export {
|
|
|
100
114
|
moduleBase,
|
|
101
115
|
resolveFrom,
|
|
102
116
|
readPackageField,
|
|
117
|
+
parseArgs,
|
|
118
|
+
cli,
|
|
103
119
|
main,
|
|
104
120
|
}
|
|
105
|
-
/*
|
|
121
|
+
/* node:fs Not a pure module */
|