@rodyssey/cli 0.1.7 → 0.1.9
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/cli.js +91 -31
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2071,7 +2071,7 @@ var {
|
|
|
2071
2071
|
// package.json
|
|
2072
2072
|
var package_default = {
|
|
2073
2073
|
name: "@rodyssey/cli",
|
|
2074
|
-
version: "0.1.
|
|
2074
|
+
version: "0.1.9",
|
|
2075
2075
|
description: "Scaffold new projects from airconcepts templates",
|
|
2076
2076
|
repository: {
|
|
2077
2077
|
type: "git",
|
|
@@ -2211,7 +2211,7 @@ function storeSession(session) {
|
|
|
2211
2211
|
function resolveSessionToken(env) {
|
|
2212
2212
|
const token = process.env.CMS_TOKEN || getStoredSession(env)?.token;
|
|
2213
2213
|
if (!token) {
|
|
2214
|
-
throw new Error(`No CMS auth token found for [${env}]. Run \`ro
|
|
2214
|
+
throw new Error(`No CMS auth token found for [${env}]. Run \`ro auth login --env ${env}\` first.`);
|
|
2215
2215
|
}
|
|
2216
2216
|
return token;
|
|
2217
2217
|
}
|
|
@@ -2312,7 +2312,7 @@ async function me(options) {
|
|
|
2312
2312
|
const storedSession = getStoredSession(options.env);
|
|
2313
2313
|
if (!options.remote) {
|
|
2314
2314
|
if (!storedSession) {
|
|
2315
|
-
throw new Error(`No local CMS session found for [${options.env}]. Run \`ro
|
|
2315
|
+
throw new Error(`No local CMS session found for [${options.env}]. Run \`ro auth login --env ${options.env}\` first.`);
|
|
2316
2316
|
}
|
|
2317
2317
|
return {
|
|
2318
2318
|
env: storedSession.env,
|
|
@@ -2377,12 +2377,13 @@ function replaceInFiles(dir, filenames, search, replace) {
|
|
|
2377
2377
|
} catch {}
|
|
2378
2378
|
}
|
|
2379
2379
|
}
|
|
2380
|
-
function loadEnv(envName) {
|
|
2380
|
+
function loadEnv(envName, options = {}) {
|
|
2381
2381
|
const files = [];
|
|
2382
2382
|
if (envName) {
|
|
2383
2383
|
files.push(`.env.${envName}`);
|
|
2384
2384
|
}
|
|
2385
2385
|
files.push(".env");
|
|
2386
|
+
const loaded = {};
|
|
2386
2387
|
for (const file of files) {
|
|
2387
2388
|
if (!existsSync2(file))
|
|
2388
2389
|
continue;
|
|
@@ -2400,11 +2401,16 @@ function loadEnv(envName) {
|
|
|
2400
2401
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2401
2402
|
value = value.slice(1, -1);
|
|
2402
2403
|
}
|
|
2403
|
-
if (
|
|
2404
|
-
|
|
2404
|
+
if (loaded[key] === undefined) {
|
|
2405
|
+
loaded[key] = value;
|
|
2405
2406
|
}
|
|
2406
2407
|
}
|
|
2407
2408
|
}
|
|
2409
|
+
for (const [key, value] of Object.entries(loaded)) {
|
|
2410
|
+
if (options.override || process.env[key] === undefined) {
|
|
2411
|
+
process.env[key] = value;
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2408
2414
|
}
|
|
2409
2415
|
|
|
2410
2416
|
// src/create.ts
|
|
@@ -4142,7 +4148,59 @@ function isAffirmative(answer) {
|
|
|
4142
4148
|
const trimmed = answer.trim().toLowerCase();
|
|
4143
4149
|
return trimmed === "" || trimmed === "y" || trimmed === "yes";
|
|
4144
4150
|
}
|
|
4151
|
+
function isExplicitYes(answer) {
|
|
4152
|
+
const trimmed = answer.trim().toLowerCase();
|
|
4153
|
+
return trimmed === "y" || trimmed === "yes";
|
|
4154
|
+
}
|
|
4155
|
+
function assertDeployOptions(options) {
|
|
4156
|
+
if (options.deploy && options.skipDeploy) {
|
|
4157
|
+
console.error("❌ Error: Use either --deploy or --skip-deploy, not both.");
|
|
4158
|
+
process.exit(1);
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
async function maybeDeployProduction(options, webappId, deployToken) {
|
|
4162
|
+
const deployRequested = options.deploy === true;
|
|
4163
|
+
const deploySkipped = options.skipDeploy === true;
|
|
4164
|
+
if (deploySkipped) {
|
|
4165
|
+
console.log(`
|
|
4166
|
+
↷ Skipping production deploy.`);
|
|
4167
|
+
console.log(`Deploy later with:
|
|
4168
|
+
`);
|
|
4169
|
+
console.log(` ro app deploy -e production
|
|
4170
|
+
`);
|
|
4171
|
+
return;
|
|
4172
|
+
}
|
|
4173
|
+
let shouldDeploy = deployRequested;
|
|
4174
|
+
if (!shouldDeploy) {
|
|
4175
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
4176
|
+
console.log(`
|
|
4177
|
+
✨ Promotion complete! Deploy to production with:
|
|
4178
|
+
`);
|
|
4179
|
+
console.log(` ro app deploy -e production
|
|
4180
|
+
`);
|
|
4181
|
+
return;
|
|
4182
|
+
}
|
|
4183
|
+
const answer = await prompt(`
|
|
4184
|
+
Deploy to production now? (y/N): `);
|
|
4185
|
+
shouldDeploy = isExplicitYes(answer);
|
|
4186
|
+
}
|
|
4187
|
+
if (!shouldDeploy) {
|
|
4188
|
+
console.log(`
|
|
4189
|
+
✨ Promotion complete! Deploy to production with:
|
|
4190
|
+
`);
|
|
4191
|
+
console.log(` ro app deploy -e production
|
|
4192
|
+
`);
|
|
4193
|
+
return;
|
|
4194
|
+
}
|
|
4195
|
+
console.log(`
|
|
4196
|
+
\uD83D\uDE80 Deploying promoted webapp to production...`);
|
|
4197
|
+
loadEnv(PROD_ENV, { override: true });
|
|
4198
|
+
process.env.WEBAPP_ID = webappId;
|
|
4199
|
+
process.env.DEPLOY_TOKEN = deployToken;
|
|
4200
|
+
await deploy(PROD_ENV);
|
|
4201
|
+
}
|
|
4145
4202
|
async function promote(options) {
|
|
4203
|
+
assertDeployOptions(options);
|
|
4146
4204
|
loadEnv();
|
|
4147
4205
|
const webappId = process.env.WEBAPP_ID;
|
|
4148
4206
|
if (!webappId) {
|
|
@@ -4231,11 +4289,7 @@ ${JSON.stringify(payload, null, 2)}`);
|
|
|
4231
4289
|
});
|
|
4232
4290
|
console.log(`✅ Wrote WEBAPP_ID and DEPLOY_TOKEN to ${PROD_ENV_FILE}`);
|
|
4233
4291
|
console.log(`\uD83D\uDCCD Webapp ID: ${webappId}`);
|
|
4234
|
-
|
|
4235
|
-
✨ Promotion complete! Deploy to production with:
|
|
4236
|
-
`);
|
|
4237
|
-
console.log(` ro app deploy -e production
|
|
4238
|
-
`);
|
|
4292
|
+
await maybeDeployProduction(options, webappId, deployToken);
|
|
4239
4293
|
}
|
|
4240
4294
|
|
|
4241
4295
|
// src/upgrade-template.ts
|
|
@@ -4593,6 +4647,28 @@ function addConfigTargetOptions(command) {
|
|
|
4593
4647
|
function addConfigSetOptions(command) {
|
|
4594
4648
|
return addConfigTargetOptions(command).option("--title <title>", "Webapp title (pass the literal 'null' to clear)").option("--description <description>", "Webapp description (pass the literal 'null' to clear)").option("--cover-img <url>", "Cover image URL (pass the literal 'null' to clear)").option("--localization <json-or-file>", "Localization JSON object, path to a JSON file, or 'null' to clear").option("--details <json-or-file>", "Partial WebappDetails JSON or path to a JSON file. Sent as a delta — only include keys you want to change. Do NOT echo a full GET response here, or empty defaults like 'tags: []' will clobber real data.").option("--dry-run", "Print the request payload without sending it");
|
|
4595
4649
|
}
|
|
4650
|
+
function addAuthCommands(parent) {
|
|
4651
|
+
const auth = parent.command("auth").description("Authenticate with the CMS");
|
|
4652
|
+
auth.command("login").description("Log in to the CMS using a browser callback").option("-e, --env <environment>", "CMS environment (local | development | staging | production)", "development").option("--cms-url <url>", "CMS base URL. Defaults to the selected environment").option("--login-url <url>", "Full browser login URL. Defaults to <cms-url>/auth/cli-login").option("--token-url <url>", "Full token exchange URL. Defaults to <cms-url>/api/auth/cli-token").option("--callback-port <port>", "Local callback port. Defaults to a random free port", parseInt).option("--timeout <seconds>", "Seconds to wait for the browser callback", parseInt, 300).option("--no-open", "Print the login URL without opening a browser").action(async (options) => {
|
|
4653
|
+
const session = await login({
|
|
4654
|
+
env: options.env,
|
|
4655
|
+
cmsUrl: options.cmsUrl,
|
|
4656
|
+
loginUrl: options.loginUrl,
|
|
4657
|
+
tokenUrl: options.tokenUrl,
|
|
4658
|
+
callbackPort: options.callbackPort,
|
|
4659
|
+
open: options.open,
|
|
4660
|
+
timeoutMs: (options.timeout ?? 300) * 1000
|
|
4661
|
+
});
|
|
4662
|
+
console.log(`✅ Logged in to CMS [${session.env}]`);
|
|
4663
|
+
console.log(`\uD83D\uDCCD CMS URL: ${session.cmsUrl}`);
|
|
4664
|
+
});
|
|
4665
|
+
auth.command("me").description("Show the locally stored CMS login session").option("-e, --env <environment>", "CMS environment (local | development | staging | production)", "development").option("--remote", "Call the CMS /me endpoint instead of only reading the local session").option("--cms-url <url>", "CMS base URL for --remote. Defaults to the selected environment or stored session").option("--me-url <url>", "Full me endpoint URL for --remote. Defaults to <cms-url>/api/auth/me").action(async (options) => {
|
|
4666
|
+
const currentUser = await me(options);
|
|
4667
|
+
console.log(JSON.stringify(currentUser, null, 2));
|
|
4668
|
+
});
|
|
4669
|
+
return auth;
|
|
4670
|
+
}
|
|
4671
|
+
addAuthCommands(program);
|
|
4596
4672
|
app.command("create").argument("<project-name>", "Name of the project to create").option("-t, --template <template>", "Template to use (webapp | webapp-fullstack)").option("--auto", "Create a CMS webapp and write WEBAPP_ID/DEPLOY_TOKEN to .env").option("-e, --env <environment>", "CMS environment for --auto (local | development | staging | production)", "development").option("--cms-url <url>", "CMS base URL for --auto. Defaults to the selected environment").option("--create-url <url>", "Full CMS create endpoint for --auto. Defaults to <cms-url>/api/cli/webapps/create").description("Create a new project from a template").action(async (projectName, options) => {
|
|
4597
4673
|
let templateName;
|
|
4598
4674
|
if (options.template) {
|
|
@@ -4612,13 +4688,15 @@ app.command("create").argument("<project-name>", "Name of the project to create"
|
|
|
4612
4688
|
createUrl: options.createUrl
|
|
4613
4689
|
});
|
|
4614
4690
|
});
|
|
4615
|
-
app.command("promote").description("Promote the current webapp to production (creates a prod record with the same WEBAPP_ID)").option("--details <json-or-file>", "Full WebappDetails JSON object or path to a JSON file. Skips the source-pull and confirmation prompts when provided.").option("-y, --yes", "Auto-accept pulling the latest details from development").option("--cms-url <url>", "Production CMS base URL. Defaults to the production environment").option("--promote-url <url>", "Full CMS promote endpoint. Defaults to <cms-url>/api/cli/webapps/promote").option("--from <env>", "Source environment to pull details from (testing override). Defaults to development", "development").action(async (options) => {
|
|
4691
|
+
app.command("promote").description("Promote the current webapp to production (creates a prod record with the same WEBAPP_ID)").option("--details <json-or-file>", "Full WebappDetails JSON object or path to a JSON file. Skips the source-pull and confirmation prompts when provided.").option("-y, --yes", "Auto-accept pulling the latest details from development").option("--cms-url <url>", "Production CMS base URL. Defaults to the production environment").option("--promote-url <url>", "Full CMS promote endpoint. Defaults to <cms-url>/api/cli/webapps/promote").option("--from <env>", "Source environment to pull details from (testing override). Defaults to development", "development").option("--deploy", "Deploy to production immediately after promotion").option("--skip-deploy", "Do not ask to deploy after promotion").action(async (options) => {
|
|
4616
4692
|
await promote({
|
|
4617
4693
|
details: options.details,
|
|
4618
4694
|
yes: options.yes,
|
|
4619
4695
|
cmsUrl: options.cmsUrl,
|
|
4620
4696
|
promoteUrl: options.promoteUrl,
|
|
4621
|
-
from: options.from
|
|
4697
|
+
from: options.from,
|
|
4698
|
+
deploy: options.deploy,
|
|
4699
|
+
skipDeploy: options.skipDeploy
|
|
4622
4700
|
});
|
|
4623
4701
|
});
|
|
4624
4702
|
app.command("update-game-sdk").description("Download and update the GameSDK library, types, and documentation").action(async () => {
|
|
@@ -4627,24 +4705,6 @@ app.command("update-game-sdk").description("Download and update the GameSDK libr
|
|
|
4627
4705
|
app.command("deploy").description("Build and deploy the webapp to the server").option("-e, --env <environment>", "Target environment (local | development | staging | production)", "development").option("--host <host>", "Override the deploy host").option("--port <port>", "Override the deploy port", parseInt).action(async (options) => {
|
|
4628
4706
|
await deploy(options.env, { host: options.host, port: options.port });
|
|
4629
4707
|
});
|
|
4630
|
-
var auth = app.command("auth").description("Authenticate with the CMS");
|
|
4631
|
-
auth.command("login").description("Log in to the CMS using a browser callback").option("-e, --env <environment>", "CMS environment (local | development | staging | production)", "development").option("--cms-url <url>", "CMS base URL. Defaults to the selected environment").option("--login-url <url>", "Full browser login URL. Defaults to <cms-url>/auth/cli-login").option("--token-url <url>", "Full token exchange URL. Defaults to <cms-url>/api/auth/cli-token").option("--callback-port <port>", "Local callback port. Defaults to a random free port", parseInt).option("--timeout <seconds>", "Seconds to wait for the browser callback", parseInt, 300).option("--no-open", "Print the login URL without opening a browser").action(async (options) => {
|
|
4632
|
-
const session = await login({
|
|
4633
|
-
env: options.env,
|
|
4634
|
-
cmsUrl: options.cmsUrl,
|
|
4635
|
-
loginUrl: options.loginUrl,
|
|
4636
|
-
tokenUrl: options.tokenUrl,
|
|
4637
|
-
callbackPort: options.callbackPort,
|
|
4638
|
-
open: options.open,
|
|
4639
|
-
timeoutMs: (options.timeout ?? 300) * 1000
|
|
4640
|
-
});
|
|
4641
|
-
console.log(`✅ Logged in to CMS [${session.env}]`);
|
|
4642
|
-
console.log(`\uD83D\uDCCD CMS URL: ${session.cmsUrl}`);
|
|
4643
|
-
});
|
|
4644
|
-
auth.command("me").description("Show the locally stored CMS login session").option("-e, --env <environment>", "CMS environment (local | development | staging | production)", "development").option("--remote", "Call the CMS /me endpoint instead of only reading the local session").option("--cms-url <url>", "CMS base URL for --remote. Defaults to the selected environment or stored session").option("--me-url <url>", "Full me endpoint URL for --remote. Defaults to <cms-url>/api/auth/me").action(async (options) => {
|
|
4645
|
-
const currentUser = await me(options);
|
|
4646
|
-
console.log(JSON.stringify(currentUser, null, 2));
|
|
4647
|
-
});
|
|
4648
4708
|
var config = app.command("config").description("Manage webapp metadata config");
|
|
4649
4709
|
addConfigTargetOptions(config.command("get").description("Pull the current webapp metadata config from the CMS").option("--out <file>", "Write the config JSON to a file")).action(async (options) => {
|
|
4650
4710
|
await getWebappConfig(options);
|