effortless-aws 0.1.1 → 0.2.0
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/dist/{chunk-I5TS7O5S.js → chunk-7JVA4742.js} +149 -2
- package/dist/cli/index.js +142 -76
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/wrap-http.js +25 -43
- package/dist/runtime/wrap-table-stream.js +47 -74
- package/package.json +1 -1
|
@@ -99,6 +99,21 @@ var createTableClient = (tableName) => {
|
|
|
99
99
|
};
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
+
// src/runtime/platform-types.ts
|
|
103
|
+
var ENV_PLATFORM_TABLE = "EFF_PLATFORM_TABLE";
|
|
104
|
+
var DEFAULT_TTL_SECONDS = 7 * 24 * 60 * 60;
|
|
105
|
+
var truncateForStorage = (value, maxLength = 4096) => {
|
|
106
|
+
if (value === void 0 || value === null) return value;
|
|
107
|
+
const str = typeof value === "string" ? value : JSON.stringify(value);
|
|
108
|
+
if (str.length <= maxLength) return value;
|
|
109
|
+
return str.slice(0, maxLength) + "...[truncated]";
|
|
110
|
+
};
|
|
111
|
+
var dateBucket = (date = /* @__PURE__ */ new Date()) => date.toISOString().slice(0, 10);
|
|
112
|
+
var computeTtl = (ttlSeconds = DEFAULT_TTL_SECONDS) => Math.floor(Date.now() / 1e3) + ttlSeconds;
|
|
113
|
+
|
|
114
|
+
// src/runtime/handler-utils.ts
|
|
115
|
+
import { randomUUID } from "crypto";
|
|
116
|
+
|
|
102
117
|
// src/runtime/ssm-client.ts
|
|
103
118
|
import { SSM } from "@aws-sdk/client-ssm";
|
|
104
119
|
var client = null;
|
|
@@ -120,6 +135,89 @@ var getParameters = async (names) => {
|
|
|
120
135
|
return map;
|
|
121
136
|
};
|
|
122
137
|
|
|
138
|
+
// src/runtime/platform-client.ts
|
|
139
|
+
import { DynamoDB as DynamoDB2 } from "@aws-sdk/client-dynamodb";
|
|
140
|
+
import { marshall as marshall2, unmarshall as unmarshall2 } from "@aws-sdk/util-dynamodb";
|
|
141
|
+
var createPlatformClient = () => {
|
|
142
|
+
const tableName = process.env[ENV_PLATFORM_TABLE];
|
|
143
|
+
if (!tableName) return void 0;
|
|
144
|
+
let client2 = null;
|
|
145
|
+
const getClient2 = () => client2 ??= new DynamoDB2({});
|
|
146
|
+
const appendToList = async (handlerName, handlerType, listAttr, entry) => {
|
|
147
|
+
const sk = `EXEC#${dateBucket()}`;
|
|
148
|
+
try {
|
|
149
|
+
await getClient2().updateItem({
|
|
150
|
+
TableName: tableName,
|
|
151
|
+
Key: marshall2({ pk: `HANDLER#${handlerName}`, sk }),
|
|
152
|
+
UpdateExpression: "SET #list = list_append(if_not_exists(#list, :empty), :entry), #type = :type, #hn = :hn, #ht = :ht, #ttl = :ttl",
|
|
153
|
+
ExpressionAttributeNames: {
|
|
154
|
+
"#list": listAttr,
|
|
155
|
+
"#type": "type",
|
|
156
|
+
"#hn": "handlerName",
|
|
157
|
+
"#ht": "handlerType",
|
|
158
|
+
"#ttl": "ttl"
|
|
159
|
+
},
|
|
160
|
+
ExpressionAttributeValues: marshall2(
|
|
161
|
+
{
|
|
162
|
+
":entry": [entry],
|
|
163
|
+
":empty": [],
|
|
164
|
+
":type": "execution-log",
|
|
165
|
+
":hn": handlerName,
|
|
166
|
+
":ht": handlerType,
|
|
167
|
+
":ttl": computeTtl()
|
|
168
|
+
},
|
|
169
|
+
{ removeUndefinedValues: true }
|
|
170
|
+
)
|
|
171
|
+
});
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.error("[effortless] Failed to write platform record:", err);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
tableName,
|
|
178
|
+
async appendExecution(handlerName, handlerType, entry) {
|
|
179
|
+
await appendToList(handlerName, handlerType, "executions", entry);
|
|
180
|
+
},
|
|
181
|
+
async appendError(handlerName, handlerType, entry) {
|
|
182
|
+
await appendToList(handlerName, handlerType, "errors", entry);
|
|
183
|
+
},
|
|
184
|
+
async get(pk, sk) {
|
|
185
|
+
const result = await getClient2().getItem({
|
|
186
|
+
TableName: tableName,
|
|
187
|
+
Key: marshall2({ pk, sk })
|
|
188
|
+
});
|
|
189
|
+
return result.Item ? unmarshall2(result.Item) : void 0;
|
|
190
|
+
},
|
|
191
|
+
async query(pk, skPrefix) {
|
|
192
|
+
const names = { "#pk": "pk" };
|
|
193
|
+
const values = { ":pk": pk };
|
|
194
|
+
let keyCondition = "#pk = :pk";
|
|
195
|
+
if (skPrefix) {
|
|
196
|
+
names["#sk"] = "sk";
|
|
197
|
+
values[":sk"] = skPrefix;
|
|
198
|
+
keyCondition += " AND begins_with(#sk, :sk)";
|
|
199
|
+
}
|
|
200
|
+
const result = await getClient2().query({
|
|
201
|
+
TableName: tableName,
|
|
202
|
+
KeyConditionExpression: keyCondition,
|
|
203
|
+
ExpressionAttributeNames: names,
|
|
204
|
+
ExpressionAttributeValues: marshall2(values, { removeUndefinedValues: true })
|
|
205
|
+
});
|
|
206
|
+
return (result.Items ?? []).map((item) => unmarshall2(item));
|
|
207
|
+
},
|
|
208
|
+
async put(entity) {
|
|
209
|
+
try {
|
|
210
|
+
await getClient2().putItem({
|
|
211
|
+
TableName: tableName,
|
|
212
|
+
Item: marshall2(entity, { removeUndefinedValues: true })
|
|
213
|
+
});
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error("[effortless] Failed to write platform record:", err);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
|
|
123
221
|
// src/runtime/handler-utils.ts
|
|
124
222
|
var ENV_TABLE_PREFIX = "EFF_TABLE_";
|
|
125
223
|
var ENV_PARAM_PREFIX = "EFF_PARAM_";
|
|
@@ -155,9 +253,58 @@ var buildParams = async (params) => {
|
|
|
155
253
|
}
|
|
156
254
|
return result;
|
|
157
255
|
};
|
|
256
|
+
var createHandlerRuntime = (handler, handlerType) => {
|
|
257
|
+
const platform = createPlatformClient();
|
|
258
|
+
const handlerName = process.env.EFF_HANDLER ?? "unknown";
|
|
259
|
+
let ctx = null;
|
|
260
|
+
let resolvedDeps;
|
|
261
|
+
let resolvedParams = null;
|
|
262
|
+
const getDeps = () => resolvedDeps ??= buildDeps(handler.deps);
|
|
263
|
+
const getParams = async () => {
|
|
264
|
+
if (resolvedParams !== null) return resolvedParams;
|
|
265
|
+
resolvedParams = await buildParams(handler.params);
|
|
266
|
+
return resolvedParams;
|
|
267
|
+
};
|
|
268
|
+
const getCtx = async () => {
|
|
269
|
+
if (ctx !== null) return ctx;
|
|
270
|
+
if (handler.context) {
|
|
271
|
+
const params = await getParams();
|
|
272
|
+
ctx = params ? await handler.context({ params }) : await handler.context();
|
|
273
|
+
}
|
|
274
|
+
return ctx;
|
|
275
|
+
};
|
|
276
|
+
const commonArgs = async () => {
|
|
277
|
+
const args = {};
|
|
278
|
+
if (handler.context) args.ctx = await getCtx();
|
|
279
|
+
const deps = getDeps();
|
|
280
|
+
if (deps) args.deps = deps;
|
|
281
|
+
const params = await getParams();
|
|
282
|
+
if (params) args.params = params;
|
|
283
|
+
return args;
|
|
284
|
+
};
|
|
285
|
+
const logExecution = (startTime, input, output) => {
|
|
286
|
+
platform?.appendExecution(handlerName, handlerType, {
|
|
287
|
+
id: randomUUID(),
|
|
288
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
289
|
+
ms: Date.now() - startTime,
|
|
290
|
+
in: input,
|
|
291
|
+
out: truncateForStorage(output)
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
const logError = (startTime, input, error) => {
|
|
295
|
+
platform?.appendError(handlerName, handlerType, {
|
|
296
|
+
id: randomUUID(),
|
|
297
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
298
|
+
ms: Date.now() - startTime,
|
|
299
|
+
in: input,
|
|
300
|
+
err: error instanceof Error ? error.message : String(error)
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
return { commonArgs, logExecution, logError, handlerName };
|
|
304
|
+
};
|
|
158
305
|
|
|
159
306
|
export {
|
|
160
307
|
createTableClient,
|
|
161
|
-
|
|
162
|
-
|
|
308
|
+
truncateForStorage,
|
|
309
|
+
createHandlerRuntime
|
|
163
310
|
};
|
package/dist/cli/index.js
CHANGED
|
@@ -69937,15 +69937,39 @@ var waitForTableActive = (tableName) => Effect_exports.gen(function* () {
|
|
|
69937
69937
|
}
|
|
69938
69938
|
return yield* Effect_exports.fail(new Error(`Timeout waiting for table ${tableName} to become active`));
|
|
69939
69939
|
});
|
|
69940
|
+
var ensureTimeToLive = (tableName, attributeName) => Effect_exports.gen(function* () {
|
|
69941
|
+
const current = yield* dynamodb_exports.make("describe_time_to_live", {
|
|
69942
|
+
TableName: tableName
|
|
69943
|
+
});
|
|
69944
|
+
const status2 = current.TimeToLiveDescription?.TimeToLiveStatus;
|
|
69945
|
+
const currentAttr = current.TimeToLiveDescription?.AttributeName;
|
|
69946
|
+
if (status2 === "ENABLED" && currentAttr === attributeName) {
|
|
69947
|
+
return;
|
|
69948
|
+
}
|
|
69949
|
+
if (status2 === "ENABLING") {
|
|
69950
|
+
yield* Effect_exports.logInfo(`TTL is being enabled on ${tableName}, waiting...`);
|
|
69951
|
+
yield* Effect_exports.sleep(5e3);
|
|
69952
|
+
return;
|
|
69953
|
+
}
|
|
69954
|
+
yield* Effect_exports.logInfo(`Enabling TTL on ${tableName} (attribute: ${attributeName})`);
|
|
69955
|
+
yield* dynamodb_exports.make("update_time_to_live", {
|
|
69956
|
+
TableName: tableName,
|
|
69957
|
+
TimeToLiveSpecification: {
|
|
69958
|
+
Enabled: true,
|
|
69959
|
+
AttributeName: attributeName
|
|
69960
|
+
}
|
|
69961
|
+
});
|
|
69962
|
+
});
|
|
69940
69963
|
var ensureTable = (input) => Effect_exports.gen(function* () {
|
|
69941
|
-
const { name, pk, sk, billingMode = "PAY_PER_REQUEST", streamView = "NEW_AND_OLD_IMAGES", tags: tags2 } = input;
|
|
69964
|
+
const { name, pk, sk, billingMode = "PAY_PER_REQUEST", streamView = "NEW_AND_OLD_IMAGES", tags: tags2, ttlAttribute } = input;
|
|
69942
69965
|
const existingTable = yield* dynamodb_exports.make("describe_table", { TableName: name }).pipe(
|
|
69943
|
-
Effect_exports.map((
|
|
69966
|
+
Effect_exports.map((result2) => result2.Table),
|
|
69944
69967
|
Effect_exports.catchIf(
|
|
69945
69968
|
(error4) => error4 instanceof dynamodb_exports.DynamoDBError && error4.cause.name === "ResourceNotFoundException",
|
|
69946
69969
|
() => Effect_exports.succeed(void 0)
|
|
69947
69970
|
)
|
|
69948
69971
|
);
|
|
69972
|
+
let result;
|
|
69949
69973
|
if (!existingTable) {
|
|
69950
69974
|
yield* Effect_exports.logInfo(`Creating table ${name}...`);
|
|
69951
69975
|
const keySchema = [
|
|
@@ -69967,34 +69991,40 @@ var ensureTable = (input) => Effect_exports.gen(function* () {
|
|
|
69967
69991
|
Tags: tags2 ? toAwsTagList(tags2) : void 0
|
|
69968
69992
|
});
|
|
69969
69993
|
const table3 = yield* waitForTableActive(name);
|
|
69970
|
-
|
|
69994
|
+
result = {
|
|
69971
69995
|
tableArn: table3.TableArn,
|
|
69972
69996
|
streamArn: table3.LatestStreamArn
|
|
69973
69997
|
};
|
|
69998
|
+
} else {
|
|
69999
|
+
yield* Effect_exports.logInfo(`Table ${name} already exists`);
|
|
70000
|
+
if (tags2) {
|
|
70001
|
+
yield* dynamodb_exports.make("tag_resource", {
|
|
70002
|
+
ResourceArn: existingTable.TableArn,
|
|
70003
|
+
Tags: toAwsTagList(tags2)
|
|
70004
|
+
});
|
|
70005
|
+
}
|
|
70006
|
+
if (!existingTable.StreamSpecification?.StreamEnabled) {
|
|
70007
|
+
yield* Effect_exports.logInfo(`Enabling stream on table ${name}...`);
|
|
70008
|
+
yield* dynamodb_exports.make("update_table", {
|
|
70009
|
+
TableName: name,
|
|
70010
|
+
StreamSpecification: streamViewToSpec(streamView)
|
|
70011
|
+
});
|
|
70012
|
+
const table3 = yield* waitForTableActive(name);
|
|
70013
|
+
result = {
|
|
70014
|
+
tableArn: table3.TableArn,
|
|
70015
|
+
streamArn: table3.LatestStreamArn
|
|
70016
|
+
};
|
|
70017
|
+
} else {
|
|
70018
|
+
result = {
|
|
70019
|
+
tableArn: existingTable.TableArn,
|
|
70020
|
+
streamArn: existingTable.LatestStreamArn
|
|
70021
|
+
};
|
|
70022
|
+
}
|
|
69974
70023
|
}
|
|
69975
|
-
|
|
69976
|
-
|
|
69977
|
-
yield* dynamodb_exports.make("tag_resource", {
|
|
69978
|
-
ResourceArn: existingTable.TableArn,
|
|
69979
|
-
Tags: toAwsTagList(tags2)
|
|
69980
|
-
});
|
|
69981
|
-
}
|
|
69982
|
-
if (!existingTable.StreamSpecification?.StreamEnabled) {
|
|
69983
|
-
yield* Effect_exports.logInfo(`Enabling stream on table ${name}...`);
|
|
69984
|
-
yield* dynamodb_exports.make("update_table", {
|
|
69985
|
-
TableName: name,
|
|
69986
|
-
StreamSpecification: streamViewToSpec(streamView)
|
|
69987
|
-
});
|
|
69988
|
-
const table3 = yield* waitForTableActive(name);
|
|
69989
|
-
return {
|
|
69990
|
-
tableArn: table3.TableArn,
|
|
69991
|
-
streamArn: table3.LatestStreamArn
|
|
69992
|
-
};
|
|
70024
|
+
if (ttlAttribute) {
|
|
70025
|
+
yield* ensureTimeToLive(name, ttlAttribute);
|
|
69993
70026
|
}
|
|
69994
|
-
return
|
|
69995
|
-
tableArn: existingTable.TableArn,
|
|
69996
|
-
streamArn: existingTable.LatestStreamArn
|
|
69997
|
-
};
|
|
70027
|
+
return result;
|
|
69998
70028
|
});
|
|
69999
70029
|
var ensureEventSourceMapping = (input) => Effect_exports.gen(function* () {
|
|
70000
70030
|
const { functionArn, streamArn, batchSize = 100, batchWindow, startingPosition = "LATEST" } = input;
|
|
@@ -70162,10 +70192,10 @@ var computeLockfileHash = (projectDir) => Effect_exports.gen(function* () {
|
|
|
70162
70192
|
if (prodDeps.length === 0) {
|
|
70163
70193
|
return yield* Effect_exports.fail(new Error("No production dependencies"));
|
|
70164
70194
|
}
|
|
70165
|
-
const { packages: allPackages } = collectTransitiveDeps(projectDir, prodDeps);
|
|
70195
|
+
const { packages: allPackages, resolvedPaths } = collectTransitiveDeps(projectDir, prodDeps);
|
|
70166
70196
|
const packageVersions = [];
|
|
70167
70197
|
for (const pkgName of Array.from(allPackages).sort()) {
|
|
70168
|
-
const pkgPath = findInPnpmStore(projectDir, pkgName) ?? getPackageRealPath(projectDir, pkgName);
|
|
70198
|
+
const pkgPath = resolvedPaths.get(pkgName) ?? findInPnpmStore(projectDir, pkgName) ?? getPackageRealPath(projectDir, pkgName);
|
|
70169
70199
|
if (pkgPath) {
|
|
70170
70200
|
const version = getPackageVersion(pkgPath);
|
|
70171
70201
|
if (version) {
|
|
@@ -70231,7 +70261,7 @@ var findInPnpmStore = (projectDir, pkgName) => {
|
|
|
70231
70261
|
}
|
|
70232
70262
|
return null;
|
|
70233
70263
|
};
|
|
70234
|
-
var collectTransitiveDeps = (projectDir, rootDeps, searchPath = path4.join(projectDir, "node_modules"), visited = /* @__PURE__ */ new Set(), warnings = []) => {
|
|
70264
|
+
var collectTransitiveDeps = (projectDir, rootDeps, searchPath = path4.join(projectDir, "node_modules"), visited = /* @__PURE__ */ new Set(), resolvedPaths = /* @__PURE__ */ new Map(), warnings = []) => {
|
|
70235
70265
|
const rootNodeModules = path4.join(projectDir, "node_modules");
|
|
70236
70266
|
for (const dep of rootDeps) {
|
|
70237
70267
|
if (visited.has(dep)) continue;
|
|
@@ -70262,44 +70292,63 @@ var collectTransitiveDeps = (projectDir, rootDeps, searchPath = path4.join(proje
|
|
|
70262
70292
|
continue;
|
|
70263
70293
|
}
|
|
70264
70294
|
visited.add(dep);
|
|
70295
|
+
resolvedPaths.set(dep, realPath2);
|
|
70265
70296
|
const pkgDeps = getPackageDeps(realPath2);
|
|
70266
70297
|
if (pkgDeps.length > 0) {
|
|
70267
70298
|
const isScoped = dep.startsWith("@");
|
|
70268
70299
|
const pkgNodeModules = isScoped ? path4.dirname(path4.dirname(realPath2)) : path4.dirname(realPath2);
|
|
70269
|
-
collectTransitiveDeps(projectDir, pkgDeps, pkgNodeModules, visited, warnings);
|
|
70300
|
+
collectTransitiveDeps(projectDir, pkgDeps, pkgNodeModules, visited, resolvedPaths, warnings);
|
|
70270
70301
|
}
|
|
70271
70302
|
}
|
|
70272
|
-
return { packages: visited, warnings };
|
|
70303
|
+
return { packages: visited, resolvedPaths, warnings };
|
|
70273
70304
|
};
|
|
70274
70305
|
var isAwsRuntime = (pkg) => pkg.startsWith("@aws-sdk/") || pkg.startsWith("@smithy/");
|
|
70275
70306
|
var collectLayerPackages = (projectDir, dependencies) => {
|
|
70276
|
-
if (dependencies.length === 0) return { packages: [], warnings: [] };
|
|
70277
|
-
const { packages, warnings } = collectTransitiveDeps(projectDir, dependencies);
|
|
70307
|
+
if (dependencies.length === 0) return { packages: [], resolvedPaths: /* @__PURE__ */ new Map(), warnings: [] };
|
|
70308
|
+
const { packages, resolvedPaths, warnings } = collectTransitiveDeps(projectDir, dependencies);
|
|
70278
70309
|
let changed = true;
|
|
70279
70310
|
while (changed) {
|
|
70280
70311
|
changed = false;
|
|
70281
70312
|
for (const pkg of [...packages]) {
|
|
70282
70313
|
if (isAwsRuntime(pkg)) continue;
|
|
70283
|
-
const
|
|
70284
|
-
|
|
70285
|
-
|
|
70286
|
-
|
|
70287
|
-
|
|
70288
|
-
|
|
70289
|
-
|
|
70290
|
-
|
|
70314
|
+
const pkgPaths = /* @__PURE__ */ new Set();
|
|
70315
|
+
const resolved = resolvedPaths.get(pkg);
|
|
70316
|
+
if (resolved) pkgPaths.add(resolved);
|
|
70317
|
+
const found = findPackagePath(projectDir, pkg);
|
|
70318
|
+
if (found) pkgPaths.add(found);
|
|
70319
|
+
if (pkgPaths.size === 0) continue;
|
|
70320
|
+
for (const pkgPath of pkgPaths) {
|
|
70321
|
+
const pkgDeps = getPackageDeps(pkgPath);
|
|
70322
|
+
for (const dep of pkgDeps) {
|
|
70323
|
+
if (!packages.has(dep) && !isAwsRuntime(dep)) {
|
|
70324
|
+
packages.add(dep);
|
|
70325
|
+
changed = true;
|
|
70326
|
+
let depPath = findPackagePath(projectDir, dep);
|
|
70327
|
+
if (!depPath) {
|
|
70328
|
+
const isScoped = pkg.startsWith("@");
|
|
70329
|
+
const parentNodeModules = isScoped ? path4.dirname(path4.dirname(pkgPath)) : path4.dirname(pkgPath);
|
|
70330
|
+
const depInParent = path4.join(parentNodeModules, dep);
|
|
70331
|
+
if (fsSync.existsSync(depInParent)) {
|
|
70332
|
+
try {
|
|
70333
|
+
depPath = fsSync.realpathSync(depInParent);
|
|
70334
|
+
} catch {
|
|
70335
|
+
}
|
|
70336
|
+
}
|
|
70337
|
+
}
|
|
70338
|
+
if (depPath) resolvedPaths.set(dep, depPath);
|
|
70339
|
+
}
|
|
70291
70340
|
}
|
|
70292
70341
|
}
|
|
70293
70342
|
}
|
|
70294
70343
|
}
|
|
70295
|
-
return { packages: Array.from(packages), warnings };
|
|
70344
|
+
return { packages: Array.from(packages), resolvedPaths, warnings };
|
|
70296
70345
|
};
|
|
70297
70346
|
var findPackagePath = (projectDir, pkgName) => {
|
|
70298
70347
|
const rootPath = getPackageRealPath(projectDir, pkgName);
|
|
70299
70348
|
if (rootPath) return rootPath;
|
|
70300
70349
|
return findInPnpmStore(projectDir, pkgName);
|
|
70301
70350
|
};
|
|
70302
|
-
var createLayerZip = (projectDir, packages) => Effect_exports.async((resume2) => {
|
|
70351
|
+
var createLayerZip = (projectDir, packages, resolvedPaths) => Effect_exports.async((resume2) => {
|
|
70303
70352
|
const chunks2 = [];
|
|
70304
70353
|
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
70305
70354
|
const addedPaths = /* @__PURE__ */ new Set();
|
|
@@ -70313,7 +70362,7 @@ var createLayerZip = (projectDir, packages) => Effect_exports.async((resume2) =>
|
|
|
70313
70362
|
})));
|
|
70314
70363
|
archive.on("error", (err) => resume2(Effect_exports.fail(err)));
|
|
70315
70364
|
for (const pkgName of packages) {
|
|
70316
|
-
const realPath2 = findPackagePath(projectDir, pkgName);
|
|
70365
|
+
const realPath2 = resolvedPaths?.get(pkgName) ?? findPackagePath(projectDir, pkgName);
|
|
70317
70366
|
if (typeof realPath2 === "string" && realPath2.length > 0 && !addedPaths.has(realPath2)) {
|
|
70318
70367
|
addedPaths.add(realPath2);
|
|
70319
70368
|
includedPackages.push(pkgName);
|
|
@@ -70371,13 +70420,13 @@ var ensureLayer = (config2) => Effect_exports.gen(function* () {
|
|
|
70371
70420
|
yield* Effect_exports.logInfo(`Layer ${layerName} with hash ${hash2} already exists (version ${existing.version})`);
|
|
70372
70421
|
return existing;
|
|
70373
70422
|
}
|
|
70374
|
-
const { packages: allPackages, warnings: layerWarnings } = yield* Effect_exports.sync(() => collectLayerPackages(config2.projectDir, dependencies));
|
|
70423
|
+
const { packages: allPackages, resolvedPaths, warnings: layerWarnings } = yield* Effect_exports.sync(() => collectLayerPackages(config2.projectDir, dependencies));
|
|
70375
70424
|
for (const warning of layerWarnings) {
|
|
70376
70425
|
yield* Effect_exports.logWarning(`[layer] ${warning}`);
|
|
70377
70426
|
}
|
|
70378
70427
|
yield* Effect_exports.logInfo(`Creating layer ${layerName} with ${allPackages.length} packages (hash: ${hash2})`);
|
|
70379
70428
|
yield* Effect_exports.logDebug(`Layer packages: ${allPackages.join(", ")}`);
|
|
70380
|
-
const { buffer: layerZip, includedPackages, skippedPackages } = yield* createLayerZip(config2.projectDir, allPackages);
|
|
70429
|
+
const { buffer: layerZip, includedPackages, skippedPackages } = yield* createLayerZip(config2.projectDir, allPackages, resolvedPaths);
|
|
70381
70430
|
if (skippedPackages.length > 0) {
|
|
70382
70431
|
yield* Effect_exports.logWarning(`Skipped ${skippedPackages.length} packages (not found): ${skippedPackages.slice(0, 10).join(", ")}${skippedPackages.length > 10 ? "..." : ""}`);
|
|
70383
70432
|
}
|
|
@@ -71083,6 +71132,31 @@ var mergeResolved = (deps, params) => {
|
|
|
71083
71132
|
if (Object.keys(env2).length === 0) return void 0;
|
|
71084
71133
|
return { depsEnv: env2, depsPermissions: permissions };
|
|
71085
71134
|
};
|
|
71135
|
+
var PLATFORM_PERMISSIONS = [
|
|
71136
|
+
"dynamodb:PutItem",
|
|
71137
|
+
"dynamodb:GetItem",
|
|
71138
|
+
"dynamodb:UpdateItem",
|
|
71139
|
+
"dynamodb:Query"
|
|
71140
|
+
];
|
|
71141
|
+
var ensurePlatformTable = (project2, stage, region) => Effect_exports.gen(function* () {
|
|
71142
|
+
const tableName = `${project2}-${stage}-platform`;
|
|
71143
|
+
const tagCtx = { project: project2, stage, handler: "platform" };
|
|
71144
|
+
yield* Effect_exports.logInfo(`Ensuring platform table: ${tableName}`);
|
|
71145
|
+
yield* ensureTable({
|
|
71146
|
+
name: tableName,
|
|
71147
|
+
pk: { name: "pk", type: "string" },
|
|
71148
|
+
sk: { name: "sk", type: "string" },
|
|
71149
|
+
billingMode: "PAY_PER_REQUEST",
|
|
71150
|
+
streamView: "NEW_AND_OLD_IMAGES",
|
|
71151
|
+
tags: makeTags(tagCtx, "dynamodb"),
|
|
71152
|
+
ttlAttribute: "ttl"
|
|
71153
|
+
}).pipe(
|
|
71154
|
+
Effect_exports.provide(
|
|
71155
|
+
clients_exports.makeClients({ dynamodb: { region } })
|
|
71156
|
+
)
|
|
71157
|
+
);
|
|
71158
|
+
return tableName;
|
|
71159
|
+
});
|
|
71086
71160
|
var deployHttpHandlers = (ctx) => Effect_exports.gen(function* () {
|
|
71087
71161
|
const results = [];
|
|
71088
71162
|
for (const { file: file6, exports } of ctx.handlers) {
|
|
@@ -71100,12 +71174,17 @@ var deployHttpHandlers = (ctx) => Effect_exports.gen(function* () {
|
|
|
71100
71174
|
resolveDeps(fn2.depsKeys, ctx.tableNameMap),
|
|
71101
71175
|
resolveParams(fn2.paramEntries, ctx.input.project, stage)
|
|
71102
71176
|
);
|
|
71177
|
+
const withPlatform = {
|
|
71178
|
+
depsEnv: { ...resolved?.depsEnv, ...ctx.platformEnv },
|
|
71179
|
+
depsPermissions: [...resolved?.depsPermissions ?? [], ...ctx.platformPermissions]
|
|
71180
|
+
};
|
|
71103
71181
|
const { exportName, functionArn, config: config2 } = yield* deployLambda({
|
|
71104
71182
|
input: deployInput,
|
|
71105
71183
|
fn: fn2,
|
|
71106
71184
|
...ctx.layerArn ? { layerArn: ctx.layerArn } : {},
|
|
71107
71185
|
...ctx.external.length > 0 ? { external: ctx.external } : {},
|
|
71108
|
-
|
|
71186
|
+
depsEnv: withPlatform.depsEnv,
|
|
71187
|
+
depsPermissions: withPlatform.depsPermissions
|
|
71109
71188
|
}).pipe(
|
|
71110
71189
|
Effect_exports.provide(
|
|
71111
71190
|
clients_exports.makeClients({
|
|
@@ -71151,12 +71230,17 @@ var deployTableHandlers = (ctx) => Effect_exports.gen(function* () {
|
|
|
71151
71230
|
resolveDeps(fn2.depsKeys, ctx.tableNameMap),
|
|
71152
71231
|
resolveParams(fn2.paramEntries, ctx.input.project, stage)
|
|
71153
71232
|
);
|
|
71233
|
+
const withPlatform = {
|
|
71234
|
+
depsEnv: { ...resolved?.depsEnv, ...ctx.platformEnv },
|
|
71235
|
+
depsPermissions: [...resolved?.depsPermissions ?? [], ...ctx.platformPermissions]
|
|
71236
|
+
};
|
|
71154
71237
|
const result = yield* deployTableFunction({
|
|
71155
71238
|
input: deployInput,
|
|
71156
71239
|
fn: fn2,
|
|
71157
71240
|
...ctx.layerArn ? { layerArn: ctx.layerArn } : {},
|
|
71158
71241
|
...ctx.external.length > 0 ? { external: ctx.external } : {},
|
|
71159
|
-
|
|
71242
|
+
depsEnv: withPlatform.depsEnv,
|
|
71243
|
+
depsPermissions: withPlatform.depsPermissions
|
|
71160
71244
|
}).pipe(
|
|
71161
71245
|
Effect_exports.provide(
|
|
71162
71246
|
clients_exports.makeClients({
|
|
@@ -71191,6 +71275,9 @@ var deployProject = (input) => Effect_exports.gen(function* () {
|
|
|
71191
71275
|
region: input.region,
|
|
71192
71276
|
projectDir: input.projectDir
|
|
71193
71277
|
});
|
|
71278
|
+
const stage = resolveStage(input.stage);
|
|
71279
|
+
const platformTableName = yield* ensurePlatformTable(input.project, stage, input.region);
|
|
71280
|
+
const platformEnv = { EFF_PLATFORM_TABLE: platformTableName };
|
|
71194
71281
|
let apiId;
|
|
71195
71282
|
let apiUrl;
|
|
71196
71283
|
if (totalHttpHandlers > 0) {
|
|
@@ -71221,14 +71308,18 @@ var deployProject = (input) => Effect_exports.gen(function* () {
|
|
|
71221
71308
|
input,
|
|
71222
71309
|
layerArn,
|
|
71223
71310
|
external,
|
|
71224
|
-
tableNameMap
|
|
71311
|
+
tableNameMap,
|
|
71312
|
+
platformEnv,
|
|
71313
|
+
platformPermissions: PLATFORM_PERMISSIONS
|
|
71225
71314
|
}) : [];
|
|
71226
71315
|
const tableResults = yield* deployTableHandlers({
|
|
71227
71316
|
handlers: tableHandlers,
|
|
71228
71317
|
input,
|
|
71229
71318
|
layerArn,
|
|
71230
71319
|
external,
|
|
71231
|
-
tableNameMap
|
|
71320
|
+
tableNameMap,
|
|
71321
|
+
platformEnv,
|
|
71322
|
+
platformPermissions: PLATFORM_PERMISSIONS
|
|
71232
71323
|
});
|
|
71233
71324
|
if (apiUrl) {
|
|
71234
71325
|
yield* Effect_exports.logInfo(`Deployment complete! API: ${apiUrl}`);
|
|
@@ -72105,31 +72196,6 @@ Deleted ${deleted} layer version(s).`);
|
|
|
72105
72196
|
);
|
|
72106
72197
|
})
|
|
72107
72198
|
).pipe(Command_exports.withDescription("Delete layer versions"));
|
|
72108
|
-
var findPackagePathForCopy = (projectDir, pkgName) => {
|
|
72109
|
-
const rootPath = path11.join(projectDir, "node_modules", pkgName);
|
|
72110
|
-
if (fs5.existsSync(rootPath)) {
|
|
72111
|
-
try {
|
|
72112
|
-
return fs5.realpathSync(rootPath);
|
|
72113
|
-
} catch {
|
|
72114
|
-
}
|
|
72115
|
-
}
|
|
72116
|
-
const pnpmDir = path11.join(projectDir, "node_modules", ".pnpm");
|
|
72117
|
-
if (!fs5.existsSync(pnpmDir)) return null;
|
|
72118
|
-
const pnpmPkgName = pkgName.replace("/", "+");
|
|
72119
|
-
try {
|
|
72120
|
-
const entries2 = fs5.readdirSync(pnpmDir);
|
|
72121
|
-
for (const entry of entries2) {
|
|
72122
|
-
if (entry.startsWith(pnpmPkgName + "@")) {
|
|
72123
|
-
const pkgPath = path11.join(pnpmDir, entry, "node_modules", pkgName);
|
|
72124
|
-
if (fs5.existsSync(pkgPath)) {
|
|
72125
|
-
return fs5.realpathSync(pkgPath);
|
|
72126
|
-
}
|
|
72127
|
-
}
|
|
72128
|
-
}
|
|
72129
|
-
} catch {
|
|
72130
|
-
}
|
|
72131
|
-
return null;
|
|
72132
|
-
};
|
|
72133
72199
|
var layersBuildCommand = Command_exports.make(
|
|
72134
72200
|
"build",
|
|
72135
72201
|
{ output: outputOption, verbose: verboseOption },
|
|
@@ -72160,7 +72226,7 @@ var layersBuildCommand = Command_exports.make(
|
|
|
72160
72226
|
);
|
|
72161
72227
|
yield* Console_exports.log(`
|
|
72162
72228
|
Lockfile hash: ${hash2}`);
|
|
72163
|
-
const { packages: allPackages, warnings: layerWarnings } = yield* Effect_exports.sync(() => collectLayerPackages(projectDir, prodDeps));
|
|
72229
|
+
const { packages: allPackages, resolvedPaths, warnings: layerWarnings } = yield* Effect_exports.sync(() => collectLayerPackages(projectDir, prodDeps));
|
|
72164
72230
|
if (layerWarnings.length > 0) {
|
|
72165
72231
|
yield* Console_exports.log(`
|
|
72166
72232
|
Warnings (${layerWarnings.length}):`);
|
|
@@ -72179,7 +72245,7 @@ Collected ${allPackages.length} packages for layer`);
|
|
|
72179
72245
|
let copied = 0;
|
|
72180
72246
|
let skipped = 0;
|
|
72181
72247
|
for (const pkgName of allPackages) {
|
|
72182
|
-
const srcPath =
|
|
72248
|
+
const srcPath = resolvedPaths.get(pkgName) ?? null;
|
|
72183
72249
|
if (!srcPath) {
|
|
72184
72250
|
skipped++;
|
|
72185
72251
|
if (verbose) {
|