@eide/foir-cli 0.8.0 → 0.9.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/cli.js +29 -28
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4880,7 +4880,7 @@ import { resolve as resolve4 } from "path";
|
|
|
4880
4880
|
function zeroCounts() {
|
|
4881
4881
|
return { created: 0, updated: 0, deleted: 0 };
|
|
4882
4882
|
}
|
|
4883
|
-
async function reconcileConfig(client, configId, manifest) {
|
|
4883
|
+
async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
4884
4884
|
const summary = {
|
|
4885
4885
|
models: zeroCounts(),
|
|
4886
4886
|
operations: zeroCounts(),
|
|
@@ -4901,7 +4901,13 @@ async function reconcileConfig(client, configId, manifest) {
|
|
|
4901
4901
|
await reconcileAuthProviders(client, manifest.authProviders ?? [], summary);
|
|
4902
4902
|
await reconcilePlacements(client, configId, manifest.placements ?? [], summary);
|
|
4903
4903
|
await reconcileProfileSchema(client, manifest, summary);
|
|
4904
|
-
await reconcileApiKeys(
|
|
4904
|
+
await reconcileApiKeys(
|
|
4905
|
+
client,
|
|
4906
|
+
manifest.key,
|
|
4907
|
+
manifest.apiKeys ?? [],
|
|
4908
|
+
summary,
|
|
4909
|
+
options.rotateKeys ?? false
|
|
4910
|
+
);
|
|
4905
4911
|
return summary;
|
|
4906
4912
|
}
|
|
4907
4913
|
async function reconcileModels(client, configId, models, summary) {
|
|
@@ -5242,7 +5248,7 @@ async function reconcileProfileSchema(client, manifest, summary) {
|
|
|
5242
5248
|
});
|
|
5243
5249
|
summary.profileSchemaUpdated = true;
|
|
5244
5250
|
}
|
|
5245
|
-
async function reconcileApiKeys(client, configKey, apiKeys, summary) {
|
|
5251
|
+
async function reconcileApiKeys(client, configKey, apiKeys, summary, rotateKeys) {
|
|
5246
5252
|
if (apiKeys.length === 0) return;
|
|
5247
5253
|
const existing = await client.identity.listApiKeys({ limit: 200 });
|
|
5248
5254
|
const existingByName = new Map(
|
|
@@ -5264,8 +5270,10 @@ async function reconcileApiKeys(client, configKey, apiKeys, summary) {
|
|
|
5264
5270
|
updateScopes: true
|
|
5265
5271
|
});
|
|
5266
5272
|
}
|
|
5267
|
-
|
|
5268
|
-
|
|
5273
|
+
if (rotateKeys) {
|
|
5274
|
+
const rotated = await client.identity.rotateApiKey(existingKey.id);
|
|
5275
|
+
rawKey = rotated?.apiKey?.rawKey;
|
|
5276
|
+
}
|
|
5269
5277
|
} else {
|
|
5270
5278
|
const result = await client.identity.createApiKey({
|
|
5271
5279
|
name: key.name,
|
|
@@ -5603,23 +5611,6 @@ function syncEnvVar(envPath, key, value) {
|
|
|
5603
5611
|
`, "utf-8");
|
|
5604
5612
|
return "written";
|
|
5605
5613
|
}
|
|
5606
|
-
function writeEnvVar(envPath, key, value) {
|
|
5607
|
-
let content = "";
|
|
5608
|
-
if (existsSync4(envPath)) {
|
|
5609
|
-
content = readFileSync(envPath, "utf-8");
|
|
5610
|
-
const regex = new RegExp(`^${key}=`, "m");
|
|
5611
|
-
if (regex.test(content)) {
|
|
5612
|
-
return false;
|
|
5613
|
-
}
|
|
5614
|
-
}
|
|
5615
|
-
if (content && !content.endsWith("\n")) {
|
|
5616
|
-
content += "\n";
|
|
5617
|
-
}
|
|
5618
|
-
content += `${key}=${value}
|
|
5619
|
-
`;
|
|
5620
|
-
writeFileSync2(envPath, content, "utf-8");
|
|
5621
|
-
return true;
|
|
5622
|
-
}
|
|
5623
5614
|
function printSummary(summary) {
|
|
5624
5615
|
const lines = [];
|
|
5625
5616
|
const fmt = (label, c) => {
|
|
@@ -5645,7 +5636,11 @@ function printSummary(summary) {
|
|
|
5645
5636
|
}
|
|
5646
5637
|
}
|
|
5647
5638
|
function registerPushCommand(program2, globalOpts) {
|
|
5648
|
-
program2.command("push").description("Push foir.config.ts to the platform").option("--config <path>", "Path to config file (default: auto-discover)").option("--force", "Force reinstall (delete and recreate)", false).option(
|
|
5639
|
+
program2.command("push").description("Push foir.config.ts to the platform").option("--config <path>", "Path to config file (default: auto-discover)").option("--force", "Force reinstall (delete and recreate)", false).option(
|
|
5640
|
+
"--rotate-keys",
|
|
5641
|
+
"Rotate existing API keys and rewrite their values in .env",
|
|
5642
|
+
false
|
|
5643
|
+
).option("--env <path>", "Path to .env file (default: .env)").action(
|
|
5649
5644
|
withErrorHandler(
|
|
5650
5645
|
globalOpts,
|
|
5651
5646
|
async (opts) => {
|
|
@@ -5685,7 +5680,9 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5685
5680
|
}
|
|
5686
5681
|
const configId = applyResult.id;
|
|
5687
5682
|
console.log(chalk6.dim("Reconciling resources..."));
|
|
5688
|
-
const summary = await reconcileConfig(client, configId, config2
|
|
5683
|
+
const summary = await reconcileConfig(client, configId, config2, {
|
|
5684
|
+
rotateKeys: opts.rotateKeys ?? false
|
|
5685
|
+
});
|
|
5689
5686
|
console.log();
|
|
5690
5687
|
console.log(chalk6.green("\u2713 Config applied successfully"));
|
|
5691
5688
|
console.log(` Config ID: ${chalk6.cyan(configId)}`);
|
|
@@ -5724,14 +5721,18 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5724
5721
|
if (envWrites.length > 0) {
|
|
5725
5722
|
console.log();
|
|
5726
5723
|
for (const { key, value, label } of envWrites) {
|
|
5727
|
-
const
|
|
5728
|
-
if (
|
|
5724
|
+
const result = syncEnvVar(envPath, key, value);
|
|
5725
|
+
if (result === "unchanged") {
|
|
5729
5726
|
console.log(
|
|
5730
|
-
chalk6.
|
|
5727
|
+
chalk6.dim(` ${label}: ${key} already up to date in ${envPath}, skipped`)
|
|
5728
|
+
);
|
|
5729
|
+
} else if (result === "replaced") {
|
|
5730
|
+
console.log(
|
|
5731
|
+
chalk6.yellow(`\u27F3 ${label}`) + chalk6.dim(` \u2192 ${key} updated in ${envPath}`)
|
|
5731
5732
|
);
|
|
5732
5733
|
} else {
|
|
5733
5734
|
console.log(
|
|
5734
|
-
chalk6.
|
|
5735
|
+
chalk6.green(`\u2713 ${label}`) + chalk6.dim(` \u2192 ${key} written to ${envPath}`)
|
|
5735
5736
|
);
|
|
5736
5737
|
}
|
|
5737
5738
|
}
|