@reventlessdev/reventless-spec 3.0.0-alpha.88 → 3.0.0-alpha.90
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 +14 -0
- package/package.json +5 -3
- package/rescript.json +2 -1
- package/scripts/generate-currency.mjs +215 -0
- package/scripts/iso-4217-list-one.xml +1956 -0
- package/src/PackageVersion.res +7 -13
- package/src/generator/Config.res +4 -4
- package/src/generator/Discovery.res +12 -12
- package/src/generator/Generator_Node.res +12 -47
- package/src/generator/Pairing.res +12 -12
- package/src/generator/PlatformGenerator.res +12 -13
- package/src/generator/PlatformManifests.res +9 -9
- package/src/generator/PluginGenerator.res +10 -11
- package/src/semantic/Currency.res +598 -0
- package/src/semantic/Currency.res.mjs +743 -0
- package/src/semantic/DateRange.res +148 -0
- package/src/semantic/DateRange.res.mjs +74 -0
- package/src/semantic/Money.res +196 -0
- package/src/semantic/Money.res.mjs +138 -0
- package/src/semantic/Semantic.res +11 -0
- package/src/semantic/Semantic.res.mjs +3 -1
package/src/PackageVersion.res
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
@module("node:fs") external readFileSync: (string, string) => string = "readFileSync"
|
|
2
|
-
@module("node:fs") external existsSync: string => bool = "existsSync"
|
|
3
|
-
@module("node:url") external fileURLToPath: string => string = "fileURLToPath"
|
|
4
|
-
@module("node:path") external dirname: string => string = "dirname"
|
|
5
|
-
@module("node:path") external join: (string, string) => string = "join"
|
|
6
|
-
|
|
7
1
|
let readVersion = (path: string) =>
|
|
8
|
-
readFileSync(path
|
|
2
|
+
NodeFs.readFileSync(path)
|
|
9
3
|
->JSON.parseOrThrow
|
|
10
4
|
->JSON.Decode.object
|
|
11
5
|
->Option.flatMap(o => o->Dict.get("version"))
|
|
@@ -16,11 +10,11 @@ let fromCwd = () => readVersion("./package.json")
|
|
|
16
10
|
|
|
17
11
|
let findVersion = dir => {
|
|
18
12
|
let rec find = dir => {
|
|
19
|
-
let candidate = join(dir, "package.json")
|
|
20
|
-
if existsSync(candidate) {
|
|
13
|
+
let candidate = NodePath.join([dir, "package.json"])
|
|
14
|
+
if NodeFs.existsSync(candidate) {
|
|
21
15
|
readVersion(candidate)
|
|
22
16
|
} else {
|
|
23
|
-
let parent = dirname(dir)
|
|
17
|
+
let parent = NodePath.dirname(dir)
|
|
24
18
|
if parent == dir {
|
|
25
19
|
"0.0.0"
|
|
26
20
|
} else {
|
|
@@ -31,7 +25,7 @@ let findVersion = dir => {
|
|
|
31
25
|
find(dir)
|
|
32
26
|
}
|
|
33
27
|
|
|
34
|
-
let fromModuleUrl = (url: string) => findVersion(url->fileURLToPath->dirname)
|
|
28
|
+
let fromModuleUrl = (url: string) => findVersion(url->NodeUrl.fileURLToPath->NodePath.dirname)
|
|
35
29
|
|
|
36
30
|
/** Detect the caller's file via V8 Structured Stack Trace API and read the
|
|
37
31
|
version from the nearest package.json. Skips frames from framework packages
|
|
@@ -65,9 +59,9 @@ let fromCaller = () =>
|
|
|
65
59
|
switch callerFile() {
|
|
66
60
|
| Some(file) =>
|
|
67
61
|
if file->String.startsWith("file://") {
|
|
68
|
-
findVersion(file->fileURLToPath->dirname)
|
|
62
|
+
findVersion(file->NodeUrl.fileURLToPath->NodePath.dirname)
|
|
69
63
|
} else {
|
|
70
|
-
findVersion(file->dirname)
|
|
64
|
+
findVersion(file->NodePath.dirname)
|
|
71
65
|
}
|
|
72
66
|
| None => fromCwd()
|
|
73
67
|
}
|
package/src/generator/Config.res
CHANGED
|
@@ -29,7 +29,7 @@ type config = {
|
|
|
29
29
|
let packageNameToPluginName = PluginName.fromPackageName
|
|
30
30
|
|
|
31
31
|
let readJson = (path: string): option<JSON.t> =>
|
|
32
|
-
try Some(
|
|
32
|
+
try Some(NodeFs.readFileSync(path)->JSON.parseOrThrow) catch {
|
|
33
33
|
| _ => None
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -80,12 +80,12 @@ let getComponentRuntime = (json: JSON.t): dict<runtimeHints> => {
|
|
|
80
80
|
|
|
81
81
|
let read = (~srcDir: string): config => {
|
|
82
82
|
// Read package.json `name` from the parent of srcDir
|
|
83
|
-
let packageJsonPath =
|
|
83
|
+
let packageJsonPath = NodePath.join([NodePath.dirname(srcDir), "package.json"])
|
|
84
84
|
let packageJsonName = readJson(packageJsonPath)->Option.flatMap(j => getStrField(j, "name"))
|
|
85
85
|
|
|
86
86
|
// Read plugin.json from srcDir (optional)
|
|
87
|
-
let pluginJsonPath =
|
|
88
|
-
let pluginJson = if
|
|
87
|
+
let pluginJsonPath = NodePath.join([srcDir, "plugin.json"])
|
|
88
|
+
let pluginJson = if NodeFs.existsSync(pluginJsonPath) {
|
|
89
89
|
readJson(pluginJsonPath)
|
|
90
90
|
} else {
|
|
91
91
|
None
|
|
@@ -122,8 +122,8 @@ let collectFiles = (
|
|
|
122
122
|
~acc: array<discoveredFile>,
|
|
123
123
|
): unit =>
|
|
124
124
|
Generator_Node.readDir(dir)->Array.forEach(entry => {
|
|
125
|
-
if entry->
|
|
126
|
-
let filename = entry->
|
|
125
|
+
if entry->NodeFs.isFile {
|
|
126
|
+
let filename = entry->NodeFs.direntName
|
|
127
127
|
let relPath = if relDir === "" {filename} else {relDir ++ "/" ++ filename}
|
|
128
128
|
if !isExcluded(relPath, exclude) {
|
|
129
129
|
switch stemOf(filename) {
|
|
@@ -144,26 +144,26 @@ let rec walkDir = (
|
|
|
144
144
|
~acc: array<discoveredFile>,
|
|
145
145
|
): unit =>
|
|
146
146
|
Generator_Node.readDir(dir)->Array.forEach(entry => {
|
|
147
|
-
let entryName = entry->
|
|
147
|
+
let entryName = entry->NodeFs.direntName
|
|
148
148
|
let relPath = if relDir === "" {entryName} else {relDir ++ "/" ++ entryName}
|
|
149
149
|
|
|
150
150
|
if isExcluded(relPath, exclude) {
|
|
151
151
|
()
|
|
152
|
-
} else if entry->
|
|
152
|
+
} else if entry->NodeFs.isDirectory {
|
|
153
153
|
if isAlwaysExcludedDir(entryName) {
|
|
154
154
|
()
|
|
155
155
|
} else {
|
|
156
156
|
switch folderToComponentType(entryName) {
|
|
157
157
|
| Some(ExtensionPoint) =>
|
|
158
|
-
let epDir =
|
|
158
|
+
let epDir = NodePath.join([dir, entryName])
|
|
159
159
|
let children = Generator_Node.readDir(epDir)
|
|
160
|
-
let hasSubDirs = children->Array.some(e => e->
|
|
160
|
+
let hasSubDirs = children->Array.some(e => e->NodeFs.isDirectory)
|
|
161
161
|
if hasSubDirs {
|
|
162
162
|
// Each subfolder is a named EP group
|
|
163
163
|
children->Array.forEach(child => {
|
|
164
|
-
if child->
|
|
165
|
-
let groupName = child->
|
|
166
|
-
let groupDir =
|
|
164
|
+
if child->NodeFs.isDirectory {
|
|
165
|
+
let groupName = child->NodeFs.direntName
|
|
166
|
+
let groupDir = NodePath.join([epDir, groupName])
|
|
167
167
|
let groupRelDir = relPath ++ "/" ++ groupName
|
|
168
168
|
collectFiles(
|
|
169
169
|
~dir=groupDir,
|
|
@@ -189,7 +189,7 @@ let rec walkDir = (
|
|
|
189
189
|
| Some(ct) =>
|
|
190
190
|
// Recurse into component type folder, collecting files at any depth
|
|
191
191
|
walkDir(
|
|
192
|
-
~dir=
|
|
192
|
+
~dir=NodePath.join([dir, entryName]),
|
|
193
193
|
~relDir=relPath,
|
|
194
194
|
~parentComponentType=Some(ct),
|
|
195
195
|
~epGroup=None,
|
|
@@ -199,7 +199,7 @@ let rec walkDir = (
|
|
|
199
199
|
| None =>
|
|
200
200
|
// Chapter folder or other — recurse inheriting parent context
|
|
201
201
|
walkDir(
|
|
202
|
-
~dir=
|
|
202
|
+
~dir=NodePath.join([dir, entryName]),
|
|
203
203
|
~relDir=relPath,
|
|
204
204
|
~parentComponentType,
|
|
205
205
|
~epGroup,
|
|
@@ -208,7 +208,7 @@ let rec walkDir = (
|
|
|
208
208
|
)
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
-
} else if entry->
|
|
211
|
+
} else if entry->NodeFs.isFile {
|
|
212
212
|
switch parentComponentType {
|
|
213
213
|
| None => ()
|
|
214
214
|
| Some(ct) =>
|
|
@@ -1,49 +1,14 @@
|
|
|
1
|
-
// Node
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type dirent
|
|
15
|
-
@send external isDirectory: dirent => bool = "isDirectory"
|
|
16
|
-
@send external isFile: dirent => bool = "isFile"
|
|
17
|
-
@get external direntName: dirent => string = "name"
|
|
18
|
-
|
|
19
|
-
type readdirOptions = {withFileTypes: bool}
|
|
20
|
-
|
|
21
|
-
@module("node:fs")
|
|
22
|
-
external readdirSyncRaw: (string, readdirOptions) => array<dirent> = "readdirSync"
|
|
23
|
-
|
|
24
|
-
let readDir = (dir: string): array<dirent> =>
|
|
25
|
-
try readdirSyncRaw(dir, {withFileTypes: true}) catch {
|
|
1
|
+
// What remains of the generator's own Node bindings after they moved to
|
|
2
|
+
// `@reventlessdev/rescript-node`: one helper, which is not a binding.
|
|
3
|
+
//
|
|
4
|
+
// The generator walks directories that may legitimately not exist — an
|
|
5
|
+
// `Extension/` folder is optional, and so is every other component folder — and
|
|
6
|
+
// it treats "absent" and "empty" the same way. `readdirSync` throws on absent,
|
|
7
|
+
// so every walk would otherwise carry its own try/catch. This does not belong in
|
|
8
|
+
// the bindings package: a binding that swallows an error is a policy, and the
|
|
9
|
+
// policy is the generator's.
|
|
10
|
+
|
|
11
|
+
let readDir = (dir: string): array<NodeFs.dirent> =>
|
|
12
|
+
try NodeFs.readdirSync(dir, {withFileTypes: true}) catch {
|
|
26
13
|
| _ => []
|
|
27
14
|
}
|
|
28
|
-
|
|
29
|
-
// ── Path ─────────────────────────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
@module("node:path") @variadic
|
|
32
|
-
external join: array<string> => string = "join"
|
|
33
|
-
|
|
34
|
-
@module("node:path") @variadic
|
|
35
|
-
external resolve: array<string> => string = "resolve"
|
|
36
|
-
|
|
37
|
-
@module("node:path")
|
|
38
|
-
external dirname: string => string = "dirname"
|
|
39
|
-
|
|
40
|
-
@module("node:path")
|
|
41
|
-
external basename: string => string = "basename"
|
|
42
|
-
|
|
43
|
-
// ── Process ──────────────────────────────────────────────────────────────────
|
|
44
|
-
|
|
45
|
-
@val @scope("process")
|
|
46
|
-
external argv: array<string> = "argv"
|
|
47
|
-
|
|
48
|
-
@val @scope("process")
|
|
49
|
-
external cwd: unit => string = "cwd"
|
|
@@ -89,12 +89,12 @@ let findEventMappings = (~srcDir: string): Dict.t<string> => {
|
|
|
89
89
|
}
|
|
90
90
|
let rec walk = (dir: string, segments: array<string>) =>
|
|
91
91
|
Generator_Node.readDir(dir)->Array.forEach(entry => {
|
|
92
|
-
let name = entry->
|
|
93
|
-
if entry->
|
|
92
|
+
let name = entry->NodeFs.direntName
|
|
93
|
+
if entry->NodeFs.isDirectory {
|
|
94
94
|
if name !== "Plugin" && name !== "tests" && name !== "lib" {
|
|
95
|
-
walk(
|
|
95
|
+
walk(NodePath.join([dir, name]), Array.concat(segments, [name]))
|
|
96
96
|
}
|
|
97
|
-
} else if entry->
|
|
97
|
+
} else if entry->NodeFs.isFile {
|
|
98
98
|
if name->String.endsWith("_Mappings.res") && parentDirIsAggregate(segments) {
|
|
99
99
|
let stem = name->String.slice(~start=0, ~end=name->String.length - 4)
|
|
100
100
|
// "_Mappings" = 9 chars
|
|
@@ -112,7 +112,7 @@ let findEventMappings = (~srcDir: string): Dict.t<string> => {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
})
|
|
115
|
-
if
|
|
115
|
+
if NodeFs.existsSync(srcDir) {
|
|
116
116
|
walk(srcDir, [])
|
|
117
117
|
}
|
|
118
118
|
dict
|
|
@@ -126,7 +126,7 @@ let sortedStems = (stems: array<string>): array<string> =>
|
|
|
126
126
|
// or None for `let targetName = None` or when the line is absent.
|
|
127
127
|
let extractTargetName = (filePath: string): option<string> => {
|
|
128
128
|
try {
|
|
129
|
-
let content =
|
|
129
|
+
let content = NodeFs.readFileSync(filePath)
|
|
130
130
|
let result = ref(None)
|
|
131
131
|
content->String.split("\n")->Array.forEach(line => {
|
|
132
132
|
let trimmed = line->String.trimStart
|
|
@@ -151,7 +151,7 @@ let extractTargetName = (filePath: string): option<string> => {
|
|
|
151
151
|
// into the opt-in behavior — the safe default is the attribute being absent.
|
|
152
152
|
let hasFileAttribute = (filePath: string, ~attr: string): bool => {
|
|
153
153
|
try {
|
|
154
|
-
let content =
|
|
154
|
+
let content = NodeFs.readFileSync(filePath)
|
|
155
155
|
let found = ref(false)
|
|
156
156
|
content->String.split("\n")->Array.forEach(line => {
|
|
157
157
|
let trimmed = line->String.trimStart
|
|
@@ -187,7 +187,7 @@ let hasSystemCallableAttribute = (filePath: string): bool =>
|
|
|
187
187
|
// with an explicit name override.
|
|
188
188
|
let effectiveSpecName = (filePath: string, ~stem: string): string => {
|
|
189
189
|
try {
|
|
190
|
-
let content =
|
|
190
|
+
let content = NodeFs.readFileSync(filePath)
|
|
191
191
|
let name = ref(None)
|
|
192
192
|
content->String.split("\n")->Array.forEach(line => {
|
|
193
193
|
let trimmed = line->String.trimStart
|
|
@@ -347,7 +347,7 @@ let resolve = (discovered: array<Discovery.discoveredFile>, ~srcDir: string): re
|
|
|
347
347
|
| Some(behavior) =>
|
|
348
348
|
let isAsync = switch Dict.get(aggregateSpecRelPaths, spec) {
|
|
349
349
|
| None => false
|
|
350
|
-
| Some(relPath) => hasAsyncAttribute(
|
|
350
|
+
| Some(relPath) => hasAsyncAttribute(NodePath.join([srcDir, relPath]))
|
|
351
351
|
}
|
|
352
352
|
Some({
|
|
353
353
|
spec,
|
|
@@ -397,7 +397,7 @@ let resolve = (discovered: array<Discovery.discoveredFile>, ~srcDir: string): re
|
|
|
397
397
|
stems->Array.forEach(stem => {
|
|
398
398
|
let target = switch Dict.get(relPaths, stem) {
|
|
399
399
|
| None => None
|
|
400
|
-
| Some(relPath) => extractTargetName(
|
|
400
|
+
| Some(relPath) => extractTargetName(NodePath.join([srcDir, relPath]))
|
|
401
401
|
}
|
|
402
402
|
dict->Dict.set(stem, target)
|
|
403
403
|
})
|
|
@@ -426,7 +426,7 @@ let resolve = (discovered: array<Discovery.discoveredFile>, ~srcDir: string): re
|
|
|
426
426
|
switch Dict.get(stateChangeSliceRelPaths, stem) {
|
|
427
427
|
| None => ()
|
|
428
428
|
| Some(relPath) =>
|
|
429
|
-
if hasAsyncAttribute(
|
|
429
|
+
if hasAsyncAttribute(NodePath.join([srcDir, relPath])) {
|
|
430
430
|
d->Dict.set(stem, true)
|
|
431
431
|
}
|
|
432
432
|
}
|
|
@@ -440,7 +440,7 @@ let resolve = (discovered: array<Discovery.discoveredFile>, ~srcDir: string): re
|
|
|
440
440
|
switch Dict.get(relPaths, stem) {
|
|
441
441
|
| None => ()
|
|
442
442
|
| Some(relPath) =>
|
|
443
|
-
let filePath =
|
|
443
|
+
let filePath = NodePath.join([srcDir, relPath])
|
|
444
444
|
if hasSystemCallableAttribute(filePath) {
|
|
445
445
|
names->Array.push(effectiveSpecName(filePath, ~stem))
|
|
446
446
|
}
|
|
@@ -11,12 +11,11 @@
|
|
|
11
11
|
// its head comment states the resolution order and why each arm exists; add a
|
|
12
12
|
// fourth arm there, not here.
|
|
13
13
|
|
|
14
|
-
@val external processExit: int => unit = "process.exit"
|
|
15
14
|
@module("yaml") external parseYaml: string => JSON.t = "parse"
|
|
16
15
|
|
|
17
16
|
let fail = (message: string) => {
|
|
18
17
|
Console.error("generate-platform: " ++ message)
|
|
19
|
-
|
|
18
|
+
NodeProcess.exit(1)
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
let asObject = (json: JSON.t): option<dict<JSON.t>> => json->JSON.Decode.object
|
|
@@ -24,17 +23,17 @@ let stringAt = (obj: dict<JSON.t>, field: string): option<string> =>
|
|
|
24
23
|
obj->Dict.get(field)->Option.flatMap(JSON.Decode.string)
|
|
25
24
|
|
|
26
25
|
let () = {
|
|
27
|
-
let manifestArg =
|
|
26
|
+
let manifestArg = NodeProcess.argv->Array.get(2)->Option.getOr("")
|
|
28
27
|
if manifestArg == "" {
|
|
29
28
|
Console.error("Usage: generate-platform <deploy-manifest.yaml>")
|
|
30
|
-
|
|
29
|
+
NodeProcess.exit(1)
|
|
31
30
|
} else {
|
|
32
|
-
let manifestPath =
|
|
33
|
-
if !
|
|
31
|
+
let manifestPath = NodePath.resolve([manifestArg])
|
|
32
|
+
if !NodeFs.existsSync(manifestPath) {
|
|
34
33
|
fail(`${manifestPath} not found`)
|
|
35
34
|
}
|
|
36
|
-
let manifestDir =
|
|
37
|
-
let deployManifest = try
|
|
35
|
+
let manifestDir = NodePath.dirname(manifestPath)
|
|
36
|
+
let deployManifest = try NodeFs.readFileSync(manifestPath)->parseYaml catch {
|
|
38
37
|
| _ => {
|
|
39
38
|
fail(`could not parse ${manifestPath} as YAML`)
|
|
40
39
|
JSON.Null
|
|
@@ -68,8 +67,8 @@ let () = {
|
|
|
68
67
|
switch (platformPath, plugins) {
|
|
69
68
|
| (Some(platformPath), Some(plugins)) => {
|
|
70
69
|
let pluginManifests = plugins->Array.flatMap(((pluginName, pluginPath)) => {
|
|
71
|
-
let pluginDir =
|
|
72
|
-
if !
|
|
70
|
+
let pluginDir = NodePath.resolve([manifestDir, pluginPath])
|
|
71
|
+
if !NodeFs.existsSync(pluginDir) {
|
|
73
72
|
fail(`plugin "${pluginName}" points at ${pluginDir}, which does not exist`)
|
|
74
73
|
}
|
|
75
74
|
switch PlatformManifests.resolve(~pluginDir) {
|
|
@@ -94,7 +93,7 @@ let () = {
|
|
|
94
93
|
Console.log(
|
|
95
94
|
`Read: ${pluginName} — ${path} (via ${PlatformManifests.describeVia(via)})`,
|
|
96
95
|
)
|
|
97
|
-
let manifest = try
|
|
96
|
+
let manifest = try NodeFs.readFileSync(path)
|
|
98
97
|
->JSON.parseOrThrow
|
|
99
98
|
->S.parseOrThrow(CapabilityManifest.schema) catch {
|
|
100
99
|
| _ => {
|
|
@@ -110,13 +109,13 @@ let () = {
|
|
|
110
109
|
switch PlatformCodegen.render(pluginManifests) {
|
|
111
110
|
| Error(message) => fail(message)
|
|
112
111
|
| Ok(source) => {
|
|
113
|
-
let outputPath =
|
|
112
|
+
let outputPath = NodePath.resolve([
|
|
114
113
|
manifestDir,
|
|
115
114
|
platformPath,
|
|
116
115
|
"src",
|
|
117
116
|
"PlatformCapabilities.res",
|
|
118
117
|
])
|
|
119
|
-
|
|
118
|
+
NodeFs.writeFileSync(outputPath, source)
|
|
120
119
|
Console.log("Generated: " ++ outputPath)
|
|
121
120
|
}
|
|
122
121
|
}
|
|
@@ -52,9 +52,9 @@ type fileSystem = {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
let nodeFileSystem: fileSystem = {
|
|
55
|
-
exists:
|
|
55
|
+
exists: NodeFs.existsSync,
|
|
56
56
|
readJson: path =>
|
|
57
|
-
try Some(
|
|
57
|
+
try Some(NodeFs.readFileSync(path)->JSON.parseOrThrow) catch {
|
|
58
58
|
| _ => None
|
|
59
59
|
},
|
|
60
60
|
}
|
|
@@ -69,7 +69,7 @@ let describeVia = (via: via): string =>
|
|
|
69
69
|
let asObject = (json: JSON.t): option<dict<JSON.t>> => json->JSON.Decode.object
|
|
70
70
|
|
|
71
71
|
let packageJsonAt = (~fs: fileSystem, ~dir: string): option<dict<JSON.t>> =>
|
|
72
|
-
fs.readJson(
|
|
72
|
+
fs.readJson(NodePath.join([dir, "package.json"]))->Option.flatMap(asObject)
|
|
73
73
|
|
|
74
74
|
let scriptsOf = (pkg: dict<JSON.t>): array<string> =>
|
|
75
75
|
pkg
|
|
@@ -129,11 +129,11 @@ let dependencyNames = (pkg: dict<JSON.t>): array<string> => {
|
|
|
129
129
|
may be anywhere, and it is `src/capabilities.json` that is wanted. */
|
|
130
130
|
let resolvePackageDir = (~fs: fileSystem, ~fromDir: string, ~name: string): option<string> => {
|
|
131
131
|
let rec search = dir => {
|
|
132
|
-
let candidate =
|
|
133
|
-
if fs.exists(
|
|
132
|
+
let candidate = NodePath.join([dir, "node_modules", name])
|
|
133
|
+
if fs.exists(NodePath.join([candidate, "package.json"])) {
|
|
134
134
|
Some(candidate)
|
|
135
135
|
} else {
|
|
136
|
-
let parent =
|
|
136
|
+
let parent = NodePath.dirname(dir)
|
|
137
137
|
parent == dir ? None : search(parent)
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -152,7 +152,7 @@ let fromDependencies = (~fs: fileSystem, ~pluginDir: string, ~pkg: dict<JSON.t>)
|
|
|
152
152
|
switch resolvePackageDir(~fs, ~fromDir=pluginDir, ~name) {
|
|
153
153
|
| None => ()
|
|
154
154
|
| Some(packageDir) => {
|
|
155
|
-
let candidate =
|
|
155
|
+
let candidate = NodePath.join([packageDir, "src", "capabilities.json"])
|
|
156
156
|
if fs.exists(candidate) {
|
|
157
157
|
found->Array.push({path: candidate, via: Dependency(name)})
|
|
158
158
|
} else if packageJsonAt(~fs, ~dir=packageDir)->Option.mapOr(false, emitsCapabilities) {
|
|
@@ -177,7 +177,7 @@ let fromDependencies = (~fs: fileSystem, ~pluginDir: string, ~pkg: dict<JSON.t>)
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
let resolve = (~fs: fileSystem=nodeFileSystem, ~pluginDir: string): t => {
|
|
180
|
-
let direct =
|
|
180
|
+
let direct = NodePath.join([pluginDir, "src", "capabilities.json"])
|
|
181
181
|
if fs.exists(direct) {
|
|
182
182
|
Manifests([{path: direct, via: Composition}])
|
|
183
183
|
} else {
|
|
@@ -186,7 +186,7 @@ let resolve = (~fs: fileSystem=nodeFileSystem, ~pluginDir: string): t => {
|
|
|
186
186
|
| Some(pkg) =>
|
|
187
187
|
switch generatedSrcDir(pkg) {
|
|
188
188
|
| Some(srcDir) => {
|
|
189
|
-
let expected =
|
|
189
|
+
let expected = NodePath.resolve([pluginDir, srcDir, "capabilities.json"])
|
|
190
190
|
if fs.exists(expected) {
|
|
191
191
|
Manifests([{path: expected, via: Generated(srcDir)}])
|
|
192
192
|
} else {
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
// Usage: generate-plugin <srcDir>
|
|
3
3
|
// generate-plugin --aws <Namespace> <srcDir>
|
|
4
4
|
|
|
5
|
-
@val external processExit: int => unit = "process.exit"
|
|
6
5
|
|
|
7
6
|
let () = {
|
|
8
|
-
let argv2 =
|
|
9
|
-
let argv3 =
|
|
10
|
-
let argv4 =
|
|
7
|
+
let argv2 = NodeProcess.argv->Array.get(2)->Option.getOr("")
|
|
8
|
+
let argv3 = NodeProcess.argv->Array.get(3)->Option.getOr("")
|
|
9
|
+
let argv4 = NodeProcess.argv->Array.get(4)->Option.getOr("")
|
|
11
10
|
|
|
12
11
|
let (variant, srcDirArg) = if argv2 === "--aws" {
|
|
13
12
|
if argv3 !== "" && argv4 !== "" {
|
|
@@ -27,10 +26,10 @@ let () = {
|
|
|
27
26
|
}
|
|
28
27
|
// Exit non-zero on a usage error so `prebuild` (and CI) actually fail
|
|
29
28
|
// instead of continuing green with no Plugin.res generated.
|
|
30
|
-
|
|
29
|
+
NodeProcess.exit(1)
|
|
31
30
|
} else {
|
|
32
31
|
// Resolve to absolute path (handles relative paths and trailing slashes)
|
|
33
|
-
let srcDir =
|
|
32
|
+
let srcDir = NodePath.resolve([srcDirArg])
|
|
34
33
|
|
|
35
34
|
let config = {...Config.read(~srcDir), variant}
|
|
36
35
|
let discovered = Discovery.scan(~srcDir, ~exclude=config.exclude)
|
|
@@ -39,19 +38,19 @@ let () = {
|
|
|
39
38
|
|
|
40
39
|
let outputDir = switch variant {
|
|
41
40
|
| Config.Composition => srcDir
|
|
42
|
-
| Config.Aws(_) =>
|
|
41
|
+
| Config.Aws(_) => NodePath.join([NodeProcess.cwd(), "src"])
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
let pluginPath =
|
|
46
|
-
|
|
44
|
+
let pluginPath = NodePath.join([outputDir, "Plugin.res"])
|
|
45
|
+
NodeFs.writeFileSync(pluginPath, source)
|
|
47
46
|
Console.log("Generated: " ++ pluginPath)
|
|
48
47
|
|
|
49
48
|
switch variant {
|
|
50
49
|
| Config.Composition => ()
|
|
51
50
|
| Config.Aws(_) =>
|
|
52
51
|
let mainSource = Codegen.renderMain(~config)
|
|
53
|
-
let mainPath =
|
|
54
|
-
|
|
52
|
+
let mainPath = NodePath.join([outputDir, "Main.res"])
|
|
53
|
+
NodeFs.writeFileSync(mainPath, mainSource)
|
|
55
54
|
Console.log("Generated: " ++ mainPath)
|
|
56
55
|
}
|
|
57
56
|
}
|