@meetploy/cli 1.14.1 → 1.15.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/index.js +103 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -183,6 +183,19 @@ function validatePloyConfig(config, configFile = "ploy.yaml", options = {}) {
|
|
|
183
183
|
validatedConfig.out = validateRelativePath(config.out, "out", configFile);
|
|
184
184
|
validatedConfig.base = validateRelativePath(config.base, "base", configFile);
|
|
185
185
|
validatedConfig.main = validateRelativePath(config.main, "main", configFile);
|
|
186
|
+
if (config.env !== void 0) {
|
|
187
|
+
if (typeof config.env !== "object" || config.env === null) {
|
|
188
|
+
throw new Error(`'env' in ${configFile} must be a map of KEY: value`);
|
|
189
|
+
}
|
|
190
|
+
for (const [key, value] of Object.entries(config.env)) {
|
|
191
|
+
if (!BINDING_NAME_REGEX.test(key)) {
|
|
192
|
+
throw new Error(`Invalid env key '${key}' in ${configFile}. Env keys must be uppercase with underscores (e.g., FOO, MY_VAR)`);
|
|
193
|
+
}
|
|
194
|
+
if (typeof value !== "string") {
|
|
195
|
+
throw new Error(`Env key '${key}' in ${configFile} must have a string value`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
186
199
|
validateBindings(config.db, "db", configFile);
|
|
187
200
|
validateBindings(config.queue, "queue", configFile);
|
|
188
201
|
validateBindings(config.cache, "cache", configFile);
|
|
@@ -263,7 +276,50 @@ function readAndValidatePloyConfigSync(projectDir, configPath, validationOptions
|
|
|
263
276
|
return validatePloyConfig(config, configFile, validationOptions);
|
|
264
277
|
}
|
|
265
278
|
function hasBindings(config) {
|
|
266
|
-
return !!(config.db ?? config.queue ?? config.cache ?? config.state ?? config.workflow ?? config.ai ?? config.auth);
|
|
279
|
+
return !!(config.env ?? config.db ?? config.queue ?? config.cache ?? config.state ?? config.workflow ?? config.ai ?? config.auth);
|
|
280
|
+
}
|
|
281
|
+
function parseDotEnv(content) {
|
|
282
|
+
const result = {};
|
|
283
|
+
for (const line of content.split("\n")) {
|
|
284
|
+
const trimmed = line.trim();
|
|
285
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const eqIndex = trimmed.indexOf("=");
|
|
289
|
+
if (eqIndex === -1) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
293
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
294
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
295
|
+
value = value.slice(1, -1);
|
|
296
|
+
}
|
|
297
|
+
result[key] = value;
|
|
298
|
+
}
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
function loadDotEnvSync(projectDir) {
|
|
302
|
+
const envPath = join(projectDir, ".env");
|
|
303
|
+
if (!existsSync(envPath)) {
|
|
304
|
+
return {};
|
|
305
|
+
}
|
|
306
|
+
const content = readFileSync(envPath, "utf-8");
|
|
307
|
+
return parseDotEnv(content);
|
|
308
|
+
}
|
|
309
|
+
function resolveEnvVars(configEnv, dotEnv, processEnv) {
|
|
310
|
+
const result = {};
|
|
311
|
+
for (const [key, value] of Object.entries(configEnv)) {
|
|
312
|
+
if (value.startsWith("$")) {
|
|
313
|
+
const refName = value.slice(1);
|
|
314
|
+
const resolved = dotEnv[refName] ?? processEnv[refName];
|
|
315
|
+
if (resolved !== void 0) {
|
|
316
|
+
result[key] = resolved;
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
result[key] = value;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
267
323
|
}
|
|
268
324
|
function getWorkerEntryPoint(projectDir, config) {
|
|
269
325
|
if (config.main) {
|
|
@@ -306,10 +362,13 @@ __export(cli_exports, {
|
|
|
306
362
|
getWorkerEntryPoint: () => getWorkerEntryPoint,
|
|
307
363
|
hasBindings: () => hasBindings,
|
|
308
364
|
isPnpmWorkspace: () => isPnpmWorkspace,
|
|
365
|
+
loadDotEnvSync: () => loadDotEnvSync,
|
|
366
|
+
parseDotEnv: () => parseDotEnv,
|
|
309
367
|
readAndValidatePloyConfig: () => readAndValidatePloyConfig,
|
|
310
368
|
readAndValidatePloyConfigSync: () => readAndValidatePloyConfigSync,
|
|
311
369
|
readPloyConfig: () => readPloyConfig,
|
|
312
370
|
readPloyConfigSync: () => readPloyConfigSync,
|
|
371
|
+
resolveEnvVars: () => resolveEnvVars,
|
|
313
372
|
validatePloyConfig: () => validatePloyConfig
|
|
314
373
|
});
|
|
315
374
|
var init_cli = __esm({
|
|
@@ -1035,7 +1094,7 @@ export async function executeWorkflow<TInput, TOutput, TEnv>(
|
|
|
1035
1094
|
`;
|
|
1036
1095
|
}
|
|
1037
1096
|
});
|
|
1038
|
-
function generateWrapperCode(config, mockServiceUrl) {
|
|
1097
|
+
function generateWrapperCode(config, mockServiceUrl, envVars) {
|
|
1039
1098
|
const imports = [];
|
|
1040
1099
|
const bindings = [];
|
|
1041
1100
|
if (config.db) {
|
|
@@ -1125,6 +1184,11 @@ function generateWrapperCode(config, mockServiceUrl) {
|
|
|
1125
1184
|
}
|
|
1126
1185
|
}
|
|
1127
1186
|
}` : "";
|
|
1187
|
+
const envVarsEntries = envVars && Object.keys(envVars).length > 0 ? Object.entries(envVars).map(([key, value]) => ` ${JSON.stringify(key)}: ${JSON.stringify(value)}`).join(",\n") : "";
|
|
1188
|
+
const envVarsCode = envVarsEntries ? `
|
|
1189
|
+
injectedEnv.vars = {
|
|
1190
|
+
${envVarsEntries}
|
|
1191
|
+
};` : "";
|
|
1128
1192
|
return `${imports.join("\n")}
|
|
1129
1193
|
|
|
1130
1194
|
const ployBindings = {
|
|
@@ -1133,7 +1197,7 @@ ${bindings.join("\n")}
|
|
|
1133
1197
|
|
|
1134
1198
|
export default {
|
|
1135
1199
|
async fetch(request, env, ctx) {
|
|
1136
|
-
const injectedEnv = { ...env, ...ployBindings }
|
|
1200
|
+
const injectedEnv = { ...env, ...ployBindings };${envVarsCode}
|
|
1137
1201
|
${workflowHandlerCode}
|
|
1138
1202
|
${queueHandlerCode}
|
|
1139
1203
|
|
|
@@ -1146,7 +1210,7 @@ export default {
|
|
|
1146
1210
|
|
|
1147
1211
|
async scheduled(event, env, ctx) {
|
|
1148
1212
|
if (userWorker.scheduled) {
|
|
1149
|
-
const injectedEnv = { ...env, ...ployBindings }
|
|
1213
|
+
const injectedEnv = { ...env, ...ployBindings };${envVarsCode}
|
|
1150
1214
|
return userWorker.scheduled(event, injectedEnv, ctx);
|
|
1151
1215
|
}
|
|
1152
1216
|
}
|
|
@@ -1201,8 +1265,8 @@ function createRuntimePlugin(_config) {
|
|
|
1201
1265
|
};
|
|
1202
1266
|
}
|
|
1203
1267
|
async function bundleWorker(options) {
|
|
1204
|
-
const { projectDir, tempDir, entryPoint, config, mockServiceUrl } = options;
|
|
1205
|
-
const wrapperCode = generateWrapperCode(config, mockServiceUrl);
|
|
1268
|
+
const { projectDir, tempDir, entryPoint, config, mockServiceUrl, envVars } = options;
|
|
1269
|
+
const wrapperCode = generateWrapperCode(config, mockServiceUrl, envVars);
|
|
1206
1270
|
const wrapperPath = join(tempDir, "wrapper.ts");
|
|
1207
1271
|
writeFileSync(wrapperPath, wrapperCode);
|
|
1208
1272
|
const bundlePath = join(tempDir, "worker.bundle.js");
|
|
@@ -1412,6 +1476,20 @@ var init_watcher = __esm({
|
|
|
1412
1476
|
}
|
|
1413
1477
|
});
|
|
1414
1478
|
|
|
1479
|
+
// ../emulator/dist/config/env.js
|
|
1480
|
+
function resolveEnvVars2(projectDir, config) {
|
|
1481
|
+
if (!config.env) {
|
|
1482
|
+
return {};
|
|
1483
|
+
}
|
|
1484
|
+
const dotEnv = loadDotEnvSync(projectDir);
|
|
1485
|
+
return resolveEnvVars(config.env, dotEnv, process.env);
|
|
1486
|
+
}
|
|
1487
|
+
var init_env = __esm({
|
|
1488
|
+
"../emulator/dist/config/env.js"() {
|
|
1489
|
+
init_cli();
|
|
1490
|
+
}
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1415
1493
|
// ../emulator/dist/config/ploy-config.js
|
|
1416
1494
|
function readPloyConfig2(projectDir, configPath) {
|
|
1417
1495
|
const config = readPloyConfigSync(projectDir, configPath);
|
|
@@ -3093,6 +3171,7 @@ var init_emulator = __esm({
|
|
|
3093
3171
|
"../emulator/dist/emulator.js"() {
|
|
3094
3172
|
init_bundler();
|
|
3095
3173
|
init_watcher();
|
|
3174
|
+
init_env();
|
|
3096
3175
|
init_ploy_config2();
|
|
3097
3176
|
init_workerd_config();
|
|
3098
3177
|
init_mock_server();
|
|
@@ -3110,6 +3189,7 @@ var init_emulator = __esm({
|
|
|
3110
3189
|
workerdProcess = null;
|
|
3111
3190
|
fileWatcher = null;
|
|
3112
3191
|
queueProcessor = null;
|
|
3192
|
+
resolvedEnvVars = {};
|
|
3113
3193
|
constructor(options = {}) {
|
|
3114
3194
|
const port = options.port ?? 8787;
|
|
3115
3195
|
this.options = {
|
|
@@ -3127,6 +3207,10 @@ var init_emulator = __esm({
|
|
|
3127
3207
|
try {
|
|
3128
3208
|
this.config = readPloyConfig2(this.projectDir, this.options.configPath);
|
|
3129
3209
|
debug(`Loaded config: ${JSON.stringify(this.config)}`, this.options.verbose);
|
|
3210
|
+
this.resolvedEnvVars = resolveEnvVars2(this.projectDir, this.config);
|
|
3211
|
+
if (Object.keys(this.resolvedEnvVars).length > 0) {
|
|
3212
|
+
debug(`Resolved env vars: ${Object.keys(this.resolvedEnvVars).join(", ")}`, this.options.verbose);
|
|
3213
|
+
}
|
|
3130
3214
|
this.tempDir = ensureTempDir(this.projectDir);
|
|
3131
3215
|
ensureDataDir(this.projectDir);
|
|
3132
3216
|
debug(`Temp dir: ${this.tempDir}`, this.options.verbose);
|
|
@@ -3174,6 +3258,9 @@ var init_emulator = __esm({
|
|
|
3174
3258
|
}
|
|
3175
3259
|
success(`Emulator running at http://${this.options.host}:${String(this.options.port)}`);
|
|
3176
3260
|
log(` Dashboard: http://${this.options.host}:${String(this.mockServer.port)}`);
|
|
3261
|
+
if (Object.keys(this.resolvedEnvVars).length > 0) {
|
|
3262
|
+
log(` Env vars: ${Object.keys(this.resolvedEnvVars).join(", ")}`);
|
|
3263
|
+
}
|
|
3177
3264
|
if (this.config.db) {
|
|
3178
3265
|
log(` DB bindings: ${Object.keys(this.config.db).join(", ")}`);
|
|
3179
3266
|
}
|
|
@@ -3202,7 +3289,8 @@ var init_emulator = __esm({
|
|
|
3202
3289
|
tempDir: this.tempDir,
|
|
3203
3290
|
entryPoint,
|
|
3204
3291
|
config: this.config,
|
|
3205
|
-
mockServiceUrl
|
|
3292
|
+
mockServiceUrl,
|
|
3293
|
+
envVars: this.resolvedEnvVars
|
|
3206
3294
|
});
|
|
3207
3295
|
}
|
|
3208
3296
|
async startWorkerd(configPath) {
|
|
@@ -3228,9 +3316,7 @@ var init_emulator = __esm({
|
|
|
3228
3316
|
let stderrOutput = "";
|
|
3229
3317
|
this.workerdProcess.stdout?.on("data", (data) => {
|
|
3230
3318
|
const output = data.toString();
|
|
3231
|
-
|
|
3232
|
-
process.stdout.write(output);
|
|
3233
|
-
}
|
|
3319
|
+
log(`[workerd stdout] ${output.trim()}`);
|
|
3234
3320
|
if (!started && (output.includes("Listening") || output.includes("running"))) {
|
|
3235
3321
|
started = true;
|
|
3236
3322
|
resolve(void 0);
|
|
@@ -5166,6 +5252,12 @@ async function updateTsConfigInclude(cwd, outputPath) {
|
|
|
5166
5252
|
function generateEnvType(config) {
|
|
5167
5253
|
const imports = [];
|
|
5168
5254
|
const properties = [];
|
|
5255
|
+
if (config.env && Object.keys(config.env).length > 0) {
|
|
5256
|
+
const varProps = Object.keys(config.env).map((key) => ` ${key}: string;`).join("\n");
|
|
5257
|
+
properties.push(` vars: {
|
|
5258
|
+
${varProps}
|
|
5259
|
+
};`);
|
|
5260
|
+
}
|
|
5169
5261
|
if (config.ai) {
|
|
5170
5262
|
properties.push(" AI_URL: string;");
|
|
5171
5263
|
properties.push(" AI_TOKEN: string;");
|
|
@@ -5241,7 +5333,7 @@ async function typesCommand(options = {}) {
|
|
|
5241
5333
|
console.error("Error: ploy.yaml not found in current directory");
|
|
5242
5334
|
process.exit(1);
|
|
5243
5335
|
}
|
|
5244
|
-
const hasBindings2 = config.ai || config.db || config.queue || config.cache || config.state || config.workflow;
|
|
5336
|
+
const hasBindings2 = config.env || config.ai || config.db || config.queue || config.cache || config.state || config.workflow;
|
|
5245
5337
|
if (!hasBindings2) {
|
|
5246
5338
|
console.log("No bindings found in ploy.yaml. Generating empty Env.");
|
|
5247
5339
|
}
|