@reventlessdev/reventless-aws 3.0.0-alpha.248 → 3.0.0-alpha.249
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 +8 -0
- package/package.json +13 -12
- package/rescript.json +1 -0
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res +11 -29
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +2 -3
- package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res +1 -2
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res +2 -3
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res +1 -2
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +1 -2
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +5 -7
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +1 -2
- package/src/adapter/Runtime/HeartbeatEntryPoint.res +3 -4
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res +1 -2
- package/src/adapter/Runtime/PgMigrationEntryPoint.res +1 -2
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +3 -4
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +2 -3
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +4 -5
- package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res +2 -3
- package/src/adapter/Upload/Upload_Presign_S3_Ops.res +2 -5
- package/src/components/Api/AppSync_Adapter.res +1 -6
- package/src/util/Util_Bundle.res +24 -50
- package/src/util/Util_Bundle.res.mjs +20 -20
- package/src/util/Util_LocalConfig.res +7 -14
- package/src/util/Util_LocalConfig.res.mjs +8 -8
- package/src/util/Util_SQS_Runtime.res +1 -5
- package/src/util/Util_StaticBundle.res +12 -29
- package/src/util/Util_StaticBundle.res.mjs +11 -11
- package/tests/ExtensionPointEntryPoint_OpsTest.res +1 -2
- package/tests/PgChangeFeedRelay_IntegrationTest.res +1 -2
- package/tests/PgMigrationEntryPoint_IntegrationTest.res +1 -2
- package/tests/PgPipeline_IntegrationTest.res +1 -2
- package/tests/TaskBucketEntryPoint_OpsTest.res +2 -3
- package/tests/Util_BundleResolveTest.res +12 -18
- package/tests/Util_BundleResolveTest.res.mjs +8 -8
- package/tests/Util_StaticBundleTest.res +28 -35
- package/tests/Util_StaticBundleTest.res.mjs +31 -31
package/src/util/Util_Bundle.res
CHANGED
|
@@ -1,38 +1,11 @@
|
|
|
1
|
-
// Node.js path bindings
|
|
2
|
-
@module("path") external dirname: string => string = "dirname"
|
|
3
|
-
@module("path") external join2: (string, string) => string = "join"
|
|
4
|
-
@module("path") external relative: (string, string) => string = "relative"
|
|
5
|
-
|
|
6
|
-
// Node.js fs bindings
|
|
7
|
-
@module("fs") external existsSync: string => bool = "existsSync"
|
|
8
|
-
@module("fs") external readFileSync: (string, string) => string = "readFileSync"
|
|
9
|
-
type dirent
|
|
10
|
-
@module("fs") external readdirSync: (string, {"withFileTypes": bool}) => array<dirent> = "readdirSync"
|
|
11
|
-
@send external isDirectory: dirent => bool = "isDirectory"
|
|
12
|
-
@get external direntName: dirent => string = "name"
|
|
13
|
-
|
|
14
|
-
// Node.js crypto bindings
|
|
15
|
-
type hashObj
|
|
16
|
-
@module("crypto") external createHash: string => hashObj = "createHash"
|
|
17
|
-
@send external update: (hashObj, string) => hashObj = "update"
|
|
18
|
-
@send external digest: (hashObj, string) => string = "digest"
|
|
19
|
-
|
|
20
1
|
// URL global
|
|
21
2
|
type urlObj
|
|
22
3
|
@new external newURL: string => urlObj = "URL"
|
|
23
4
|
@get external pathname: urlObj => string = "pathname"
|
|
24
5
|
|
|
25
|
-
// module.createRequire
|
|
26
|
-
type requireFn
|
|
27
|
-
@module("module") external createRequire: string => requireFn = "createRequire"
|
|
28
|
-
@send external requireResolve: (requireFn, string) => string = "resolve"
|
|
29
|
-
|
|
30
|
-
// process.cwd
|
|
31
|
-
@val @scope("process") external cwd: unit => string = "cwd"
|
|
32
|
-
|
|
33
6
|
// Module-level state: cache populated by getModuleSpecifier
|
|
34
7
|
let packageRootCache: dict<string> = Dict.make()
|
|
35
|
-
let localRequire:
|
|
8
|
+
let localRequire: NodeModule.require = NodeModule.createRequire(%raw("import.meta.url"))
|
|
36
9
|
|
|
37
10
|
/**
|
|
38
11
|
* Convert an import.meta.url file URL to an npm module specifier.
|
|
@@ -44,26 +17,26 @@ let getModuleSpecifier = (importMetaUrl: string): string => {
|
|
|
44
17
|
importMetaUrl
|
|
45
18
|
} else {
|
|
46
19
|
let filePath = newURL(importMetaUrl)->pathname
|
|
47
|
-
let dirRef = ref(dirname(filePath))
|
|
20
|
+
let dirRef = ref(NodePath.dirname(filePath))
|
|
48
21
|
let resultRef: ref<option<string>> = ref(None)
|
|
49
22
|
while dirRef.contents != "/" && resultRef.contents->Option.isNone {
|
|
50
23
|
let dir = dirRef.contents
|
|
51
|
-
let pkgPath =
|
|
52
|
-
if existsSync(pkgPath) {
|
|
53
|
-
let pkgText = readFileSync(pkgPath
|
|
24
|
+
let pkgPath = NodePath.join([dir, "package.json"])
|
|
25
|
+
if NodeFs.existsSync(pkgPath) {
|
|
26
|
+
let pkgText = NodeFs.readFileSync(pkgPath)
|
|
54
27
|
switch pkgText->JSON.parseOrThrow->JSON.Decode.object {
|
|
55
28
|
| Some(obj) =>
|
|
56
29
|
switch obj->Dict.get("name")->Option.flatMap(JSON.Decode.string) {
|
|
57
30
|
| Some(pkgName) =>
|
|
58
31
|
packageRootCache->Dict.set(pkgName, dir)
|
|
59
|
-
let relPath = relative(dir, filePath)
|
|
32
|
+
let relPath = NodePath.relative(dir, filePath)
|
|
60
33
|
resultRef := Some(pkgName ++ "/" ++ relPath)
|
|
61
|
-
| None => dirRef := dirname(dir)
|
|
34
|
+
| None => dirRef := NodePath.dirname(dir)
|
|
62
35
|
}
|
|
63
|
-
| None => dirRef := dirname(dir)
|
|
36
|
+
| None => dirRef := NodePath.dirname(dir)
|
|
64
37
|
}
|
|
65
38
|
} else {
|
|
66
|
-
dirRef := dirname(dir)
|
|
39
|
+
dirRef := NodePath.dirname(dir)
|
|
67
40
|
}
|
|
68
41
|
}
|
|
69
42
|
switch resultRef.contents {
|
|
@@ -116,8 +89,12 @@ let resolvePackageRoot = (~fromPulumiProject: bool=false, packageName: string):
|
|
|
116
89
|
| Some(cachedRoot) => cachedRoot
|
|
117
90
|
| None =>
|
|
118
91
|
let request = packageName ++ "/package.json"
|
|
119
|
-
let viaFramework = () => dirname(localRequire->requireResolve(request))
|
|
120
|
-
let viaPulumiProject = () =>
|
|
92
|
+
let viaFramework = () => NodePath.dirname(localRequire->NodeModule.requireResolve(request))
|
|
93
|
+
let viaPulumiProject = () =>
|
|
94
|
+
NodePath.dirname(
|
|
95
|
+
NodeModule.createRequire(NodeProcess.cwd() ++ "/index.js")
|
|
96
|
+
->NodeModule.requireResolve(request),
|
|
97
|
+
)
|
|
121
98
|
let (preferred, fallback) = fromPulumiProject
|
|
122
99
|
? (viaPulumiProject, viaFramework)
|
|
123
100
|
: (viaFramework, viaPulumiProject)
|
|
@@ -133,7 +110,7 @@ let resolvePackageRoot = (~fromPulumiProject: bool=false, packageName: string):
|
|
|
133
110
|
* Compute a SHA256 hash of a string, returned as base64.
|
|
134
111
|
*/
|
|
135
112
|
let hashString = (str: string): string =>
|
|
136
|
-
createHash("sha256")->
|
|
113
|
+
NodeCrypto.createHash("sha256")->NodeCrypto.hashUpdate(str)->NodeCrypto.hashDigest("base64")
|
|
137
114
|
|
|
138
115
|
// ── ESM self-containment loader (Option C) ──────────────────────────────────
|
|
139
116
|
// Deployed Lambda entry points are ESM (`.mjs`) and statically/dynamically import
|
|
@@ -213,28 +190,23 @@ let isSkippedDir = (n: string) =>
|
|
|
213
190
|
n == ".git" ||
|
|
214
191
|
n == "coverage"
|
|
215
192
|
|
|
216
|
-
// Reads file as a string for content hashing; Buffer would be slightly more
|
|
217
|
-
// efficient but utf-8 keeps the hash stable across platforms and matches what
|
|
218
|
-
// Lambda will execute.
|
|
219
|
-
@module("fs") external readFileAsString: (string, string) => string = "readFileSync"
|
|
220
|
-
|
|
221
193
|
let rec walkDir = (
|
|
222
194
|
~dir: string,
|
|
223
195
|
~prefix: string,
|
|
224
196
|
~assets: dict<Pulumi.Archive.assetOrArchive>,
|
|
225
197
|
~paths: array<(string, string)>,
|
|
226
198
|
) => {
|
|
227
|
-
let entries = readdirSync(dir, {
|
|
199
|
+
let entries = NodeFs.readdirSync(dir, {withFileTypes: true})
|
|
228
200
|
entries->Array.forEach(entry => {
|
|
229
|
-
let entryName = entry->direntName
|
|
230
|
-
if entry->isDirectory {
|
|
201
|
+
let entryName = entry->NodeFs.direntName
|
|
202
|
+
if entry->NodeFs.isDirectory {
|
|
231
203
|
if !isSkippedDir(entryName) {
|
|
232
204
|
let newPrefix = prefix == "" ? entryName : prefix ++ "/" ++ entryName
|
|
233
|
-
walkDir(~dir=
|
|
205
|
+
walkDir(~dir=NodePath.join([dir, entryName]), ~prefix=newPrefix, ~assets, ~paths)
|
|
234
206
|
}
|
|
235
207
|
} else if entryName == "package.json" || entryName->String.endsWith(".mjs") || entryName->String.endsWith(".js") {
|
|
236
208
|
let relPath = prefix == "" ? entryName : prefix ++ "/" ++ entryName
|
|
237
|
-
let absPath =
|
|
209
|
+
let absPath = NodePath.join([dir, entryName])
|
|
238
210
|
assets->Dict.set(
|
|
239
211
|
relPath,
|
|
240
212
|
Pulumi.Asset.fileAsset(absPath)->Pulumi.Archive.assetToAssetOrArchive,
|
|
@@ -256,9 +228,11 @@ let createFilteredPackageArchive = (packageRoot: string): (Pulumi.Archive.t, str
|
|
|
256
228
|
walkDir(~dir=packageRoot, ~prefix="", ~assets, ~paths)
|
|
257
229
|
// Sort so the hash is stable across filesystem traversal order.
|
|
258
230
|
paths->Array.sort(((a, _), (b, _)) => String.compare(a, b))
|
|
231
|
+
// Read as a string rather than a Buffer: slightly less efficient, but utf-8
|
|
232
|
+
// keeps the hash stable across platforms and matches what Lambda executes.
|
|
259
233
|
let combined =
|
|
260
234
|
paths
|
|
261
|
-
->Array.map(((relPath, absPath)) => `${relPath}:${
|
|
235
|
+
->Array.map(((relPath, absPath)) => `${relPath}:${NodeFs.readFileSync(absPath)}`)
|
|
262
236
|
->Array.join("\n---\n")
|
|
263
237
|
(Pulumi.Archive.assetArchive(assets), hashString(combined))
|
|
264
238
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
import * as Crypto from "crypto";
|
|
6
|
-
import * as Module from "module";
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodepath from "node:path";
|
|
7
5
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
8
6
|
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
7
|
+
import * as Nodecrypto from "node:crypto";
|
|
8
|
+
import * as Nodemodule from "node:module";
|
|
9
9
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
10
10
|
import * as Pulumi from "@pulumi/pulumi";
|
|
11
11
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
@@ -13,35 +13,35 @@ import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js
|
|
|
13
13
|
|
|
14
14
|
let packageRootCache = {};
|
|
15
15
|
|
|
16
|
-
let localRequire =
|
|
16
|
+
let localRequire = Nodemodule.createRequire(import.meta.url);
|
|
17
17
|
|
|
18
18
|
function getModuleSpecifier(importMetaUrl) {
|
|
19
19
|
if (!importMetaUrl.startsWith("file://")) {
|
|
20
20
|
return importMetaUrl;
|
|
21
21
|
}
|
|
22
22
|
let filePath = new URL(importMetaUrl).pathname;
|
|
23
|
-
let dirRef =
|
|
23
|
+
let dirRef = Nodepath.dirname(filePath);
|
|
24
24
|
let resultRef;
|
|
25
25
|
while (dirRef !== "/" && Stdlib_Option.isNone(resultRef)) {
|
|
26
26
|
let dir = dirRef;
|
|
27
|
-
let pkgPath =
|
|
28
|
-
if (
|
|
29
|
-
let pkgText =
|
|
27
|
+
let pkgPath = Nodepath.join(dir, "package.json");
|
|
28
|
+
if (Nodefs.existsSync(pkgPath)) {
|
|
29
|
+
let pkgText = Nodefs.readFileSync(pkgPath, "utf8");
|
|
30
30
|
let obj = Stdlib_JSON.Decode.object(JSON.parse(pkgText));
|
|
31
31
|
if (obj !== undefined) {
|
|
32
32
|
let pkgName = Stdlib_Option.flatMap(obj["name"], Stdlib_JSON.Decode.string);
|
|
33
33
|
if (pkgName !== undefined) {
|
|
34
34
|
packageRootCache[pkgName] = dir;
|
|
35
|
-
let relPath =
|
|
35
|
+
let relPath = Nodepath.relative(dir, filePath);
|
|
36
36
|
resultRef = pkgName + "/" + relPath;
|
|
37
37
|
} else {
|
|
38
|
-
dirRef =
|
|
38
|
+
dirRef = Nodepath.dirname(dir);
|
|
39
39
|
}
|
|
40
40
|
} else {
|
|
41
|
-
dirRef =
|
|
41
|
+
dirRef = Nodepath.dirname(dir);
|
|
42
42
|
}
|
|
43
43
|
} else {
|
|
44
|
-
dirRef =
|
|
44
|
+
dirRef = Nodepath.dirname(dir);
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
let specifier = resultRef;
|
|
@@ -69,8 +69,8 @@ function resolvePackageRoot(fromPulumiProjectOpt, packageName) {
|
|
|
69
69
|
return cachedRoot;
|
|
70
70
|
}
|
|
71
71
|
let request = packageName + "/package.json";
|
|
72
|
-
let viaFramework = () =>
|
|
73
|
-
let viaPulumiProject = () =>
|
|
72
|
+
let viaFramework = () => Nodepath.dirname(localRequire.resolve(request));
|
|
73
|
+
let viaPulumiProject = () => Nodepath.dirname(Nodemodule.createRequire(process.cwd() + "/index.js").resolve(request));
|
|
74
74
|
let match = fromPulumiProject ? [
|
|
75
75
|
viaPulumiProject,
|
|
76
76
|
viaFramework
|
|
@@ -89,7 +89,7 @@ function resolvePackageRoot(fromPulumiProjectOpt, packageName) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function hashString(str) {
|
|
92
|
-
return
|
|
92
|
+
return Nodecrypto.createHash("sha256").update(str).digest("base64");
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
let registerHookFileName = "register-hook.mjs";
|
|
@@ -139,7 +139,7 @@ function isSkippedDir(n) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function walkDir(dir, prefix, assets, paths) {
|
|
142
|
-
let entries =
|
|
142
|
+
let entries = Nodefs.readdirSync(dir, {
|
|
143
143
|
withFileTypes: true
|
|
144
144
|
});
|
|
145
145
|
entries.forEach(entry => {
|
|
@@ -149,13 +149,13 @@ function walkDir(dir, prefix, assets, paths) {
|
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
let newPrefix = prefix === "" ? entryName : prefix + "/" + entryName;
|
|
152
|
-
return walkDir(
|
|
152
|
+
return walkDir(Nodepath.join(dir, entryName), newPrefix, assets, paths);
|
|
153
153
|
}
|
|
154
154
|
if (!(entryName === "package.json" || entryName.endsWith(".mjs") || entryName.endsWith(".js"))) {
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
157
|
let relPath = prefix === "" ? entryName : prefix + "/" + entryName;
|
|
158
|
-
let absPath =
|
|
158
|
+
let absPath = Nodepath.join(dir, entryName);
|
|
159
159
|
assets[relPath] = new (Pulumi.asset.FileAsset)(absPath);
|
|
160
160
|
paths.push([
|
|
161
161
|
relPath,
|
|
@@ -169,7 +169,7 @@ function createFilteredPackageArchive(packageRoot) {
|
|
|
169
169
|
let paths = [];
|
|
170
170
|
walkDir(packageRoot, "", assets, paths);
|
|
171
171
|
paths.sort((param, param$1) => Primitive_string.compare(param[0], param$1[0]));
|
|
172
|
-
let combined = paths.map(param => param[0] + `:` +
|
|
172
|
+
let combined = paths.map(param => param[0] + `:` + Nodefs.readFileSync(param[1], "utf8")).join("\n---\n");
|
|
173
173
|
return [
|
|
174
174
|
new (Pulumi.asset.AssetArchive)(assets),
|
|
175
175
|
hashString(combined)
|
|
@@ -19,13 +19,6 @@
|
|
|
19
19
|
// ignored. Not a full YAML parser — only this subset is supported by
|
|
20
20
|
// design (no nesting, no arrays, no multi-line scalars).
|
|
21
21
|
|
|
22
|
-
@module("fs") external existsSync: string => bool = "existsSync"
|
|
23
|
-
@module("fs") external readFileSync: (string, string) => string = "readFileSync"
|
|
24
|
-
@module("path") external pathJoin: (string, string) => string = "join"
|
|
25
|
-
@module("path") external pathDirname: string => string = "dirname"
|
|
26
|
-
@val @scope("process") external processCwd: unit => string = "cwd"
|
|
27
|
-
@val external processEnv: Dict.t<string> = "process.env"
|
|
28
|
-
|
|
29
22
|
let _filename = "Pulumi.local.yaml"
|
|
30
23
|
let _projectFile = "Pulumi.yaml"
|
|
31
24
|
let _cache: ref<option<Dict.t<string>>> = ref(None)
|
|
@@ -35,15 +28,15 @@ let _cache: ref<option<Dict.t<string>>> = ref(None)
|
|
|
35
28
|
// find Pulumi.yaml, then read Pulumi.local.yaml next to it.
|
|
36
29
|
let _findSidecar = (): option<string> => {
|
|
37
30
|
let rec find = dir => {
|
|
38
|
-
if existsSync(
|
|
39
|
-
let candidate =
|
|
40
|
-
existsSync(candidate) ? Some(candidate) : None
|
|
31
|
+
if NodeFs.existsSync(NodePath.join([dir, _projectFile])) {
|
|
32
|
+
let candidate = NodePath.join([dir, _filename])
|
|
33
|
+
NodeFs.existsSync(candidate) ? Some(candidate) : None
|
|
41
34
|
} else {
|
|
42
|
-
let parent =
|
|
35
|
+
let parent = NodePath.dirname(dir)
|
|
43
36
|
parent == dir ? None : find(parent)
|
|
44
37
|
}
|
|
45
38
|
}
|
|
46
|
-
find(
|
|
39
|
+
find(NodeProcess.cwd())
|
|
47
40
|
}
|
|
48
41
|
|
|
49
42
|
let _stripQuotes = (s: string): string => {
|
|
@@ -88,7 +81,7 @@ let _load = (): Dict.t<string> =>
|
|
|
88
81
|
| Some(d) => d
|
|
89
82
|
| None =>
|
|
90
83
|
let d = switch _findSidecar() {
|
|
91
|
-
| Some(path) => _parse(readFileSync(path
|
|
84
|
+
| Some(path) => _parse(NodeFs.readFileSync(path))
|
|
92
85
|
| None => Dict.make()
|
|
93
86
|
}
|
|
94
87
|
_cache := Some(d)
|
|
@@ -113,7 +106,7 @@ let _envVarName = (key: string): string => {
|
|
|
113
106
|
}
|
|
114
107
|
|
|
115
108
|
let get = (key: string): option<string> =>
|
|
116
|
-
switch Dict.get(
|
|
109
|
+
switch Dict.get(NodeProcess.env, _envVarName(key)) {
|
|
117
110
|
| Some(v) if v !== "" => Some(v)
|
|
118
111
|
| _ => Dict.get(_load(), key)
|
|
119
112
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodepath from "node:path";
|
|
5
5
|
|
|
6
6
|
let _filename = "Pulumi.local.yaml";
|
|
7
7
|
|
|
@@ -15,15 +15,15 @@ function _findSidecar() {
|
|
|
15
15
|
let _dir = process.cwd();
|
|
16
16
|
while (true) {
|
|
17
17
|
let dir = _dir;
|
|
18
|
-
if (
|
|
19
|
-
let candidate =
|
|
20
|
-
if (
|
|
18
|
+
if (Nodefs.existsSync(Nodepath.join(dir, _projectFile))) {
|
|
19
|
+
let candidate = Nodepath.join(dir, _filename);
|
|
20
|
+
if (Nodefs.existsSync(candidate)) {
|
|
21
21
|
return candidate;
|
|
22
22
|
} else {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
let parent =
|
|
26
|
+
let parent = Nodepath.dirname(dir);
|
|
27
27
|
if (parent === dir) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
@@ -71,7 +71,7 @@ function _load() {
|
|
|
71
71
|
return d;
|
|
72
72
|
}
|
|
73
73
|
let path = _findSidecar();
|
|
74
|
-
let d$1 = path !== undefined ? _parse(
|
|
74
|
+
let d$1 = path !== undefined ? _parse(Nodefs.readFileSync(path, "utf8")) : ({});
|
|
75
75
|
_cache.contents = d$1;
|
|
76
76
|
return d$1;
|
|
77
77
|
}
|
|
@@ -109,4 +109,4 @@ export {
|
|
|
109
109
|
_envVarName,
|
|
110
110
|
get,
|
|
111
111
|
}
|
|
112
|
-
/* fs Not a pure module */
|
|
112
|
+
/* node:fs Not a pure module */
|
|
@@ -13,10 +13,6 @@ let toResolvedQueue = ({id, name, urn}: ReventlessCore.Adapter.resolvedResource)
|
|
|
13
13
|
arn: urn,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
@module("node:crypto") external _createHash: string => 'h = "createHash"
|
|
17
|
-
@send external _update: ('h, string) => 'h = "update"
|
|
18
|
-
@send external _digest: ('h, string) => string = "digest"
|
|
19
|
-
|
|
20
16
|
/** Returns `id` unchanged if ≤ 128 chars; otherwise its SHA-256 hex digest (64 chars).
|
|
21
17
|
SQS FIFO MessageGroupId is limited to 128 characters. Using a hash instead of
|
|
22
18
|
truncation avoids false-grouping of distinct keys that share a long prefix. */
|
|
@@ -24,7 +20,7 @@ let safeGroupId = (id: string): string =>
|
|
|
24
20
|
if id->String.length <= 128 {
|
|
25
21
|
id
|
|
26
22
|
} else {
|
|
27
|
-
|
|
23
|
+
NodeCrypto.createHash("sha256")->NodeCrypto.hashUpdate(id)->NodeCrypto.hashDigest("hex")
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
let sendMessage = (queue, ~delay=?, messageBody) =>
|
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
let log = ReventlessCore.Logger.fromEnv()
|
|
2
2
|
|
|
3
|
-
@module("path") external join2: (string, string) => string = "join"
|
|
4
|
-
@module("path") external relative: (string, string) => string = "relative"
|
|
5
|
-
|
|
6
|
-
@module("fs") external existsSync: string => bool = "existsSync"
|
|
7
|
-
@module("fs") external readFileSync: string => Js.TypedArray2.Uint8Array.t = "readFileSync"
|
|
8
|
-
@module("fs") external readFileSyncUtf8: (string, string) => string = "readFileSync"
|
|
9
|
-
type dirent
|
|
10
|
-
@module("fs")
|
|
11
|
-
external readdirSync: (string, {"withFileTypes": bool}) => array<dirent> = "readdirSync"
|
|
12
|
-
@send external isDirectory: dirent => bool = "isDirectory"
|
|
13
|
-
@get external direntName: dirent => string = "name"
|
|
14
|
-
|
|
15
|
-
type hashObj
|
|
16
|
-
@module("crypto") external createHash: string => hashObj = "createHash"
|
|
17
|
-
@send external updateBuffer: (hashObj, Js.TypedArray2.Uint8Array.t) => hashObj = "update"
|
|
18
|
-
@send external digest: (hashObj, string) => string = "digest"
|
|
19
|
-
|
|
20
3
|
type fileEntry = {
|
|
21
4
|
relativePath: string,
|
|
22
5
|
absolutePath: string,
|
|
@@ -29,22 +12,22 @@ let toForwardSlashes = (p: string): string => p->String.replaceAll("\\", "/")
|
|
|
29
12
|
let isHidden = (name: string): bool => name->String.startsWith(".")
|
|
30
13
|
|
|
31
14
|
let rec walkInto = (~dir: string, ~prefix: string, acc: array<fileEntry>): unit => {
|
|
32
|
-
let entries = readdirSync(dir, {
|
|
15
|
+
let entries = NodeFs.readdirSync(dir, {withFileTypes: true})
|
|
33
16
|
entries->Array.forEach(entry => {
|
|
34
|
-
let entryName = entry->direntName
|
|
17
|
+
let entryName = entry->NodeFs.direntName
|
|
35
18
|
if isHidden(entryName) {
|
|
36
19
|
()
|
|
37
|
-
} else if entry->isDirectory {
|
|
20
|
+
} else if entry->NodeFs.isDirectory {
|
|
38
21
|
let nextPrefix = prefix == "" ? entryName : prefix ++ "/" ++ entryName
|
|
39
|
-
walkInto(~dir=
|
|
22
|
+
walkInto(~dir=NodePath.join([dir, entryName]), ~prefix=nextPrefix, acc)
|
|
40
23
|
} else {
|
|
41
|
-
let absolutePath =
|
|
24
|
+
let absolutePath = NodePath.join([dir, entryName])
|
|
42
25
|
let relativePath = prefix == "" ? entryName : prefix ++ "/" ++ entryName
|
|
43
|
-
let bytes =
|
|
26
|
+
let bytes = NodeFs.readFileSyncBuffer(absolutePath)
|
|
44
27
|
let contentHash =
|
|
45
|
-
createHash("sha256")
|
|
46
|
-
->
|
|
47
|
-
->
|
|
28
|
+
NodeCrypto.createHash("sha256")
|
|
29
|
+
->NodeCrypto.hashUpdateBuffer(bytes)
|
|
30
|
+
->NodeCrypto.hashDigest("hex")
|
|
48
31
|
acc->Array.push({
|
|
49
32
|
relativePath: relativePath->toForwardSlashes,
|
|
50
33
|
absolutePath,
|
|
@@ -60,7 +43,7 @@ let rec walkInto = (~dir: string, ~prefix: string, acc: array<fileEntry>): unit
|
|
|
60
43
|
* relative S3 key, content hash, and a Pulumi FileAsset. Skips dotfiles.
|
|
61
44
|
*/
|
|
62
45
|
let walk = (assetsDir: string): array<fileEntry> => {
|
|
63
|
-
if !existsSync(assetsDir) {
|
|
46
|
+
if !NodeFs.existsSync(assetsDir) {
|
|
64
47
|
JsError.throwWithMessage(
|
|
65
48
|
`Util_StaticBundle.walk: assetsDir does not exist: ${assetsDir}`,
|
|
66
49
|
)
|
|
@@ -78,10 +61,10 @@ let walk = (assetsDir: string): array<fileEntry> => {
|
|
|
78
61
|
* re-serialised) so formatting/key order the author chose is preserved.
|
|
79
62
|
*/
|
|
80
63
|
let readJsonFileVerbatim = (~path: string, ~label: string): string => {
|
|
81
|
-
if !existsSync(path) {
|
|
64
|
+
if !NodeFs.existsSync(path) {
|
|
82
65
|
JsError.throwWithMessage(`${label}: file does not exist: ${path}`)
|
|
83
66
|
}
|
|
84
|
-
let content =
|
|
67
|
+
let content = NodeFs.readFileSync(path)
|
|
85
68
|
try {
|
|
86
69
|
let _ = JSON.parseOrThrow(content)
|
|
87
70
|
content
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodepath from "node:path";
|
|
5
|
+
import * as Nodecrypto from "node:crypto";
|
|
6
6
|
import * as Pulumi from "@pulumi/pulumi";
|
|
7
7
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
8
8
|
import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
|
|
@@ -18,7 +18,7 @@ function isHidden(name) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function walkInto(dir, prefix, acc) {
|
|
21
|
-
let entries =
|
|
21
|
+
let entries = Nodefs.readdirSync(dir, {
|
|
22
22
|
withFileTypes: true
|
|
23
23
|
});
|
|
24
24
|
entries.forEach(entry => {
|
|
@@ -28,12 +28,12 @@ function walkInto(dir, prefix, acc) {
|
|
|
28
28
|
}
|
|
29
29
|
if (entry.isDirectory()) {
|
|
30
30
|
let nextPrefix = prefix === "" ? entryName : prefix + "/" + entryName;
|
|
31
|
-
return walkInto(
|
|
31
|
+
return walkInto(Nodepath.join(dir, entryName), nextPrefix, acc);
|
|
32
32
|
}
|
|
33
|
-
let absolutePath =
|
|
33
|
+
let absolutePath = Nodepath.join(dir, entryName);
|
|
34
34
|
let relativePath = prefix === "" ? entryName : prefix + "/" + entryName;
|
|
35
|
-
let bytes =
|
|
36
|
-
let contentHash =
|
|
35
|
+
let bytes = Nodefs.readFileSync(absolutePath);
|
|
36
|
+
let contentHash = Nodecrypto.createHash("sha256").update(bytes).digest("hex");
|
|
37
37
|
acc.push({
|
|
38
38
|
relativePath: relativePath.replaceAll("\\", "/"),
|
|
39
39
|
absolutePath: absolutePath,
|
|
@@ -44,7 +44,7 @@ function walkInto(dir, prefix, acc) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function walk(assetsDir) {
|
|
47
|
-
if (!
|
|
47
|
+
if (!Nodefs.existsSync(assetsDir)) {
|
|
48
48
|
Stdlib_JsError.throwWithMessage(`Util_StaticBundle.walk: assetsDir does not exist: ` + assetsDir);
|
|
49
49
|
}
|
|
50
50
|
let acc = [];
|
|
@@ -53,10 +53,10 @@ function walk(assetsDir) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function readJsonFileVerbatim(path, label) {
|
|
56
|
-
if (!
|
|
56
|
+
if (!Nodefs.existsSync(path)) {
|
|
57
57
|
Stdlib_JsError.throwWithMessage(label + `: file does not exist: ` + path);
|
|
58
58
|
}
|
|
59
|
-
let content =
|
|
59
|
+
let content = Nodefs.readFileSync(path, "utf8");
|
|
60
60
|
try {
|
|
61
61
|
JSON.parse(content);
|
|
62
62
|
return content;
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
open JestGlobals
|
|
11
11
|
|
|
12
|
-
@val @scope("process") external processEnv: dict<string> = "env"
|
|
13
12
|
|
|
14
13
|
describe("ExtensionPointEntryPoint_Ops.parseHandlerConfig", () => {
|
|
15
14
|
testSync("reads the builder's field names", () => {
|
|
@@ -26,7 +25,7 @@ describe("ExtensionPointEntryPoint_Ops.parseHandlerConfig", () => {
|
|
|
26
25
|
|
|
27
26
|
describe("ExtensionPointEntryPoint_Ops.makeCallbackSpec", () => {
|
|
28
27
|
testSync("resolves publishToAggregates queue URLs via env vars", () => {
|
|
29
|
-
|
|
28
|
+
NodeProcess.env->Dict.set("EP_TEST_PRODUCT_QUEUE", "https://sqs/product")
|
|
30
29
|
let spec = ExtensionPointEntryPoint_Ops.makeCallbackSpec({
|
|
31
30
|
queueUrl: "https://sqs/ep",
|
|
32
31
|
publishToAggregates: Dict.fromArray([("Product", "EP_TEST_PRODUCT_QUEUE")]),
|
|
@@ -17,7 +17,6 @@ open JestGlobals
|
|
|
17
17
|
open ReventlessCore
|
|
18
18
|
open Reventless
|
|
19
19
|
|
|
20
|
-
@val external processEnv: dict<string> = "process.env"
|
|
21
20
|
let opts: Pulumi.CustomResourceOptions.t = {}
|
|
22
21
|
|
|
23
22
|
let jsonObj = pairs => JSON.Encode.object(Dict.fromArray(pairs))
|
|
@@ -35,7 +34,7 @@ let capturingSendBatch = sink => async jsons => sink := sink.contents->Array.con
|
|
|
35
34
|
let idOf = json =>
|
|
36
35
|
json->JSON.Decode.object->Option.flatMap(o => o->Dict.get("id"))->Option.flatMap(JSON.Decode.string)
|
|
37
36
|
|
|
38
|
-
switch
|
|
37
|
+
switch NodeProcess.env->Dict.get("PG_URL") {
|
|
39
38
|
| None =>
|
|
40
39
|
testSync("Postgres relay integration (skipped — set PG_URL to run)", () =>
|
|
41
40
|
expect(true)->toBe(true)
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
open JestGlobals
|
|
16
16
|
|
|
17
|
-
@val external processEnv: dict<string> = "process.env"
|
|
18
17
|
|
|
19
18
|
// Drive the real ReScript `runMigration` with the pool injected — the guard
|
|
20
19
|
// rejects a HANDLER_CONFIG with no pgConnection; the real fields below are
|
|
@@ -46,7 +45,7 @@ describe("PgMigrationEntryPoint.runMigration", () => {
|
|
|
46
45
|
expect(threw)->toBe(true)
|
|
47
46
|
})
|
|
48
47
|
|
|
49
|
-
switch
|
|
48
|
+
switch NodeProcess.env->Dict.get("PG_URL") {
|
|
50
49
|
| None =>
|
|
51
50
|
testSync("live migration (skipped — set PG_URL to run)", () => expect(true)->toBe(true))
|
|
52
51
|
| Some(url) =>
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
open JestGlobals
|
|
16
16
|
open ReventlessCore
|
|
17
17
|
|
|
18
|
-
@val external processEnv: dict<string> = "process.env"
|
|
19
18
|
|
|
20
19
|
// --- Fixtures: one classic source, one read model, one projection mapping ---
|
|
21
20
|
|
|
@@ -94,7 +93,7 @@ let asSqsEvent = (bodies: array<JSON.t>): PulumiAws.Lambda.CallbackFunction.even
|
|
|
94
93
|
),
|
|
95
94
|
})
|
|
96
95
|
|
|
97
|
-
switch
|
|
96
|
+
switch NodeProcess.env->Dict.get("PG_URL") {
|
|
98
97
|
| None =>
|
|
99
98
|
testSync("Postgres pipeline integration (skipped — set PG_URL to run)", () =>
|
|
100
99
|
expect(true)->toBe(true)
|
|
@@ -11,7 +11,6 @@ open JestGlobals
|
|
|
11
11
|
let str = JSON.Encode.string
|
|
12
12
|
let obj = pairs => JSON.Encode.object(Dict.fromArray(pairs))
|
|
13
13
|
|
|
14
|
-
@val @scope("process") external processEnv: dict<string> = "env"
|
|
15
14
|
|
|
16
15
|
describe("TaskBucketEntryPoint_Ops.parseHandlerConfig", () => {
|
|
17
16
|
testSync("empty raw config decodes to empty defaults", () => {
|
|
@@ -46,8 +45,8 @@ describe("TaskBucketEntryPoint_Ops.parseHandlerConfig", () => {
|
|
|
46
45
|
|
|
47
46
|
describe("TaskBucketEntryPoint_Ops.buildPublishCommands", () => {
|
|
48
47
|
testSync("resolves queue URLs via env vars, skipping unset or empty ones", () => {
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
NodeProcess.env->Dict.set("TB_TEST_QUEUE_A", "https://sqs/a.fifo")
|
|
49
|
+
NodeProcess.env->Dict.set("TB_TEST_QUEUE_EMPTY", "")
|
|
51
50
|
let map = Dict.fromArray([
|
|
52
51
|
("AggA", "TB_TEST_QUEUE_A"),
|
|
53
52
|
("AggEmpty", "TB_TEST_QUEUE_EMPTY"),
|
|
@@ -1,43 +1,37 @@
|
|
|
1
1
|
open JestGlobals
|
|
2
2
|
|
|
3
|
-
@module("fs") external mkdtempSync: string => string = "mkdtempSync"
|
|
4
|
-
@module("fs") external mkdirSync: (string, {"recursive": bool}) => unit = "mkdirSync"
|
|
5
|
-
@module("fs") external writeFileSync: (string, string) => unit = "writeFileSync"
|
|
6
|
-
@module("fs") external rmSync: (string, {"recursive": bool, "force": bool}) => unit = "rmSync"
|
|
7
|
-
@module("fs") external realpathSync: string => string = "realpathSync"
|
|
8
|
-
@module("path") external join2: (string, string) => string = "join"
|
|
9
|
-
@module("os") external tmpdir: unit => string = "tmpdir"
|
|
10
|
-
@val @scope("process") external chdir: string => unit = "chdir"
|
|
11
|
-
@val @scope("process") external cwd: unit => string = "cwd"
|
|
12
|
-
|
|
13
3
|
// A Pulumi project that pins a package the framework does not depend on: the
|
|
14
4
|
// shape of a host-shell bundle, which is the platform's deploy input rather
|
|
15
5
|
// than one of reventless-aws's own dependencies. realpath because macOS hands
|
|
16
6
|
// out /var/... symlinks for tmpdir while require.resolve reports /private/var.
|
|
17
7
|
let makeProject = (pkgName: string): (string, string) => {
|
|
18
|
-
let project =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
let project =
|
|
9
|
+
NodeFs.realpathSync(NodeFs.mkdtempSync(NodePath.join([NodeOs.tmpdir(), "pulumi-project-"])))
|
|
10
|
+
let pkgDir = NodePath.join([NodePath.join([project, "node_modules"]), pkgName])
|
|
11
|
+
NodeFs.mkdirSync(pkgDir, {recursive: true})
|
|
12
|
+
NodeFs.writeFileSync(
|
|
13
|
+
NodePath.join([pkgDir, "package.json"]),
|
|
14
|
+
`{"name":"","version":"9.9.9"}`,
|
|
15
|
+
)
|
|
22
16
|
(project, pkgDir)
|
|
23
17
|
}
|
|
24
18
|
|
|
25
19
|
describe("Util_Bundle.resolvePackageRoot", () => {
|
|
26
20
|
let pkgName = "pinned-by-the-project"
|
|
27
21
|
let (project, pkgDir) = makeProject(pkgName)
|
|
28
|
-
let originalCwd = cwd()
|
|
22
|
+
let originalCwd = NodeProcess.cwd()
|
|
29
23
|
// The framework fast path: what getModuleSpecifier would have cached from
|
|
30
24
|
// walking reventless-aws's own tree.
|
|
31
25
|
let frameworkRoot = "/resolved/from/the/framework"
|
|
32
26
|
|
|
33
27
|
beforeAll(() => {
|
|
34
|
-
chdir(project)
|
|
28
|
+
NodeProcess.chdir(project)
|
|
35
29
|
Util_Bundle.packageRootCache->Dict.set(pkgName, frameworkRoot)
|
|
36
30
|
})
|
|
37
31
|
|
|
38
32
|
afterAll(() => {
|
|
39
|
-
chdir(originalCwd)
|
|
40
|
-
rmSync(project, {
|
|
33
|
+
NodeProcess.chdir(originalCwd)
|
|
34
|
+
NodeFs.rmSync(project, {recursive: true, force: true})
|
|
41
35
|
})
|
|
42
36
|
|
|
43
37
|
testSync("framework-rooted by default", () =>
|