@eide/foir-cli 0.3.3 → 0.4.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 +237 -27
- package/dist/lib/config-helpers.d.ts +12 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { config } from "dotenv";
|
|
5
|
-
import { resolve as
|
|
5
|
+
import { resolve as resolve7, dirname as dirname4 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
import { Command } from "commander";
|
|
@@ -300,13 +300,13 @@ function withErrorHandler(optsFn, fn) {
|
|
|
300
300
|
// src/commands/login.ts
|
|
301
301
|
async function findAvailablePort(start, end) {
|
|
302
302
|
for (let port = start; port <= end; port++) {
|
|
303
|
-
const available = await new Promise((
|
|
303
|
+
const available = await new Promise((resolve8) => {
|
|
304
304
|
const server = http.createServer();
|
|
305
305
|
server.listen(port, () => {
|
|
306
306
|
server.close();
|
|
307
|
-
|
|
307
|
+
resolve8(true);
|
|
308
308
|
});
|
|
309
|
-
server.on("error", () =>
|
|
309
|
+
server.on("error", () => resolve8(false));
|
|
310
310
|
});
|
|
311
311
|
if (available) return port;
|
|
312
312
|
}
|
|
@@ -344,7 +344,7 @@ async function loginAction(globalOpts) {
|
|
|
344
344
|
const state = crypto.randomBytes(16).toString("hex");
|
|
345
345
|
const port = await findAvailablePort(9876, 9900);
|
|
346
346
|
const redirectUri = `http://localhost:${port}/callback`;
|
|
347
|
-
const authCode = await new Promise((
|
|
347
|
+
const authCode = await new Promise((resolve8, reject) => {
|
|
348
348
|
let timeoutId;
|
|
349
349
|
const server = http.createServer((req, res) => {
|
|
350
350
|
const url = new URL(req.url, `http://localhost:${port}`);
|
|
@@ -383,7 +383,7 @@ async function loginAction(globalOpts) {
|
|
|
383
383
|
);
|
|
384
384
|
server.closeAllConnections();
|
|
385
385
|
server.close();
|
|
386
|
-
|
|
386
|
+
resolve8(code);
|
|
387
387
|
}
|
|
388
388
|
});
|
|
389
389
|
server.listen(port);
|
|
@@ -1860,7 +1860,14 @@ function createConfigsMethods(client) {
|
|
|
1860
1860
|
configData
|
|
1861
1861
|
})
|
|
1862
1862
|
);
|
|
1863
|
-
|
|
1863
|
+
const config2 = resp.config ?? null;
|
|
1864
|
+
if (!config2) return null;
|
|
1865
|
+
return {
|
|
1866
|
+
...config2,
|
|
1867
|
+
summary: resp.summary ?? null,
|
|
1868
|
+
provisionedApiKeys: resp.provisionedApiKeys ?? [],
|
|
1869
|
+
webhookSecret: resp.webhookSecret ?? null
|
|
1870
|
+
};
|
|
1864
1871
|
},
|
|
1865
1872
|
async deleteConfig(id) {
|
|
1866
1873
|
const resp = await client.deleteConfig(
|
|
@@ -4226,7 +4233,7 @@ Edit the files, then run:
|
|
|
4226
4233
|
|
|
4227
4234
|
// src/commands/push.ts
|
|
4228
4235
|
import chalk6 from "chalk";
|
|
4229
|
-
import { existsSync as existsSync4 } from "fs";
|
|
4236
|
+
import { existsSync as existsSync4, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
4230
4237
|
import { resolve as resolve4 } from "path";
|
|
4231
4238
|
var CONFIG_FILE_NAMES = [
|
|
4232
4239
|
"foir.config.ts",
|
|
@@ -4241,8 +4248,25 @@ function discoverConfigFile() {
|
|
|
4241
4248
|
}
|
|
4242
4249
|
return null;
|
|
4243
4250
|
}
|
|
4251
|
+
function writeEnvVar(envPath, key, value) {
|
|
4252
|
+
let content = "";
|
|
4253
|
+
if (existsSync4(envPath)) {
|
|
4254
|
+
content = readFileSync(envPath, "utf-8");
|
|
4255
|
+
const regex = new RegExp(`^${key}=`, "m");
|
|
4256
|
+
if (regex.test(content)) {
|
|
4257
|
+
return false;
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
if (content && !content.endsWith("\n")) {
|
|
4261
|
+
content += "\n";
|
|
4262
|
+
}
|
|
4263
|
+
content += `${key}=${value}
|
|
4264
|
+
`;
|
|
4265
|
+
writeFileSync2(envPath, content, "utf-8");
|
|
4266
|
+
return true;
|
|
4267
|
+
}
|
|
4244
4268
|
function registerPushCommand(program2, globalOpts) {
|
|
4245
|
-
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).action(
|
|
4269
|
+
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("--env <path>", "Path to .env file (default: .env)").action(
|
|
4246
4270
|
withErrorHandler(
|
|
4247
4271
|
globalOpts,
|
|
4248
4272
|
async (opts) => {
|
|
@@ -4279,18 +4303,203 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
4279
4303
|
);
|
|
4280
4304
|
}
|
|
4281
4305
|
console.log();
|
|
4282
|
-
console.log(chalk6.green("Config applied successfully
|
|
4283
|
-
console.log();
|
|
4306
|
+
console.log(chalk6.green("\u2713 Config applied successfully"));
|
|
4284
4307
|
console.log(` Config ID: ${chalk6.cyan(result.id)}`);
|
|
4285
4308
|
console.log(` Config Key: ${chalk6.cyan(result.key)}`);
|
|
4309
|
+
const summary = result.summary;
|
|
4310
|
+
if (summary) {
|
|
4311
|
+
console.log();
|
|
4312
|
+
const lines = [];
|
|
4313
|
+
if (summary.modelsCreated || summary.modelsUpdated) {
|
|
4314
|
+
lines.push(
|
|
4315
|
+
` Models: ${summary.modelsCreated ?? 0} created, ${summary.modelsUpdated ?? 0} updated`
|
|
4316
|
+
);
|
|
4317
|
+
}
|
|
4318
|
+
if (summary.operationsCreated || summary.operationsUpdated) {
|
|
4319
|
+
lines.push(
|
|
4320
|
+
` Operations: ${summary.operationsCreated ?? 0} created, ${summary.operationsUpdated ?? 0} updated`
|
|
4321
|
+
);
|
|
4322
|
+
}
|
|
4323
|
+
if (summary.hooksCreated || summary.hooksUpdated) {
|
|
4324
|
+
lines.push(
|
|
4325
|
+
` Hooks: ${summary.hooksCreated ?? 0} created, ${summary.hooksUpdated ?? 0} updated`
|
|
4326
|
+
);
|
|
4327
|
+
}
|
|
4328
|
+
if (summary.segmentsCreated || summary.segmentsUpdated) {
|
|
4329
|
+
lines.push(
|
|
4330
|
+
` Segments: ${summary.segmentsCreated ?? 0} created, ${summary.segmentsUpdated ?? 0} updated`
|
|
4331
|
+
);
|
|
4332
|
+
}
|
|
4333
|
+
if (summary.schedulesCreated || summary.schedulesUpdated) {
|
|
4334
|
+
lines.push(
|
|
4335
|
+
` Schedules: ${summary.schedulesCreated ?? 0} created, ${summary.schedulesUpdated ?? 0} updated`
|
|
4336
|
+
);
|
|
4337
|
+
}
|
|
4338
|
+
if (summary.authProvidersCreated || summary.authProvidersUpdated) {
|
|
4339
|
+
lines.push(
|
|
4340
|
+
` Auth: ${summary.authProvidersCreated ?? 0} created, ${summary.authProvidersUpdated ?? 0} updated`
|
|
4341
|
+
);
|
|
4342
|
+
}
|
|
4343
|
+
if (summary.resourcesDeleted) {
|
|
4344
|
+
lines.push(
|
|
4345
|
+
` Cleaned up: ${summary.resourcesDeleted} orphaned resource(s)`
|
|
4346
|
+
);
|
|
4347
|
+
}
|
|
4348
|
+
if (lines.length > 0) {
|
|
4349
|
+
for (const line of lines) {
|
|
4350
|
+
console.log(line);
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
const envPath = resolve4(opts.env ?? ".env");
|
|
4355
|
+
const r = result;
|
|
4356
|
+
const provisionedKeys = r.provisionedApiKeys;
|
|
4357
|
+
const webhookSecret = r.webhookSecret;
|
|
4358
|
+
const envWrites = [];
|
|
4359
|
+
if (provisionedKeys && provisionedKeys.length > 0) {
|
|
4360
|
+
for (const pk of provisionedKeys) {
|
|
4361
|
+
envWrites.push({
|
|
4362
|
+
key: pk.envVar,
|
|
4363
|
+
value: pk.rawKey,
|
|
4364
|
+
label: `${pk.name} (${pk.keyType})`
|
|
4365
|
+
});
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
if (webhookSecret) {
|
|
4369
|
+
envWrites.push({
|
|
4370
|
+
key: "FOIR_WEBHOOK_SECRET",
|
|
4371
|
+
value: webhookSecret,
|
|
4372
|
+
label: "Webhook signing secret"
|
|
4373
|
+
});
|
|
4374
|
+
}
|
|
4375
|
+
if (envWrites.length > 0) {
|
|
4376
|
+
console.log();
|
|
4377
|
+
for (const { key, value, label } of envWrites) {
|
|
4378
|
+
const written = writeEnvVar(envPath, key, value);
|
|
4379
|
+
if (written) {
|
|
4380
|
+
console.log(
|
|
4381
|
+
chalk6.green(`\u2713 ${label}`) + chalk6.dim(` \u2192 ${key} written to ${envPath}`)
|
|
4382
|
+
);
|
|
4383
|
+
} else {
|
|
4384
|
+
console.log(
|
|
4385
|
+
chalk6.dim(` ${label}: ${key} already exists in ${envPath}, skipped`)
|
|
4386
|
+
);
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4286
4390
|
console.log();
|
|
4287
4391
|
}
|
|
4288
4392
|
)
|
|
4289
4393
|
);
|
|
4290
4394
|
}
|
|
4291
4395
|
|
|
4292
|
-
// src/commands/
|
|
4396
|
+
// src/commands/pull.ts
|
|
4293
4397
|
import chalk7 from "chalk";
|
|
4398
|
+
import { existsSync as existsSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
4399
|
+
import { resolve as resolve5 } from "path";
|
|
4400
|
+
import prettier from "prettier";
|
|
4401
|
+
var DEFAULT_OUTPUT = "foir.config.ts";
|
|
4402
|
+
function registerPullCommand(program2, globalOpts) {
|
|
4403
|
+
program2.command("pull").description("Export platform config to foir.config.ts").option("--key <configKey>", "Config key to export").option("--out <path>", `Output file (default: ${DEFAULT_OUTPUT})`).option("--force", "Overwrite existing file without prompting", false).action(
|
|
4404
|
+
withErrorHandler(
|
|
4405
|
+
globalOpts,
|
|
4406
|
+
async (opts) => {
|
|
4407
|
+
const client = await createPlatformClient(globalOpts());
|
|
4408
|
+
let configKey = opts.key;
|
|
4409
|
+
if (!configKey) {
|
|
4410
|
+
const { configs } = await client.configs.listConfigs({ limit: 50 });
|
|
4411
|
+
if (!configs || configs.length === 0) {
|
|
4412
|
+
throw new Error(
|
|
4413
|
+
"No configs found in this project. Push one first with `foir push`."
|
|
4414
|
+
);
|
|
4415
|
+
}
|
|
4416
|
+
if (configs.length === 1) {
|
|
4417
|
+
configKey = configs[0].key;
|
|
4418
|
+
} else {
|
|
4419
|
+
console.log("Available configs:");
|
|
4420
|
+
for (const c of configs) {
|
|
4421
|
+
console.log(` ${chalk7.cyan(c.key)} \u2014 ${c.name}`);
|
|
4422
|
+
}
|
|
4423
|
+
throw new Error(
|
|
4424
|
+
"Multiple configs found. Use --key <configKey> to specify which one to export."
|
|
4425
|
+
);
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
console.log(chalk7.dim(`Fetching config "${configKey}"...`));
|
|
4429
|
+
const config2 = await client.configs.getConfigByKey(configKey);
|
|
4430
|
+
if (!config2) {
|
|
4431
|
+
throw new Error(`Config "${configKey}" not found.`);
|
|
4432
|
+
}
|
|
4433
|
+
const configData = config2.config;
|
|
4434
|
+
if (!configData) {
|
|
4435
|
+
throw new Error(
|
|
4436
|
+
`Config "${configKey}" has no config data. It may have been created via the admin UI without a manifest.`
|
|
4437
|
+
);
|
|
4438
|
+
}
|
|
4439
|
+
const manifest = {
|
|
4440
|
+
key: config2.key,
|
|
4441
|
+
name: config2.name,
|
|
4442
|
+
...config2.configType && config2.configType !== "custom" ? { configType: config2.configType } : {},
|
|
4443
|
+
...config2.direction ? { direction: config2.direction } : {},
|
|
4444
|
+
...config2.description ? { description: config2.description } : {},
|
|
4445
|
+
...config2.connectionDomain ? { operationBaseUrl: config2.connectionDomain } : {},
|
|
4446
|
+
...configData
|
|
4447
|
+
};
|
|
4448
|
+
delete manifest.force;
|
|
4449
|
+
const jsonContent = JSON.stringify(manifest, null, 2);
|
|
4450
|
+
const tsContent = `/**
|
|
4451
|
+
* ${manifest.name} \u2014 Foir Config
|
|
4452
|
+
*
|
|
4453
|
+
* Exported from platform via \`foir pull\`.
|
|
4454
|
+
* Push changes back with \`foir push\`.
|
|
4455
|
+
*/
|
|
4456
|
+
|
|
4457
|
+
import { defineConfig } from '@eide/foir-cli/configs';
|
|
4458
|
+
|
|
4459
|
+
export default defineConfig(${jsonContent});
|
|
4460
|
+
`;
|
|
4461
|
+
let formatted;
|
|
4462
|
+
try {
|
|
4463
|
+
formatted = await prettier.format(tsContent, {
|
|
4464
|
+
parser: "typescript",
|
|
4465
|
+
singleQuote: true,
|
|
4466
|
+
trailingComma: "all"
|
|
4467
|
+
});
|
|
4468
|
+
} catch {
|
|
4469
|
+
formatted = tsContent;
|
|
4470
|
+
}
|
|
4471
|
+
const outPath = resolve5(opts.out ?? DEFAULT_OUTPUT);
|
|
4472
|
+
if (existsSync5(outPath) && !opts.force) {
|
|
4473
|
+
throw new Error(
|
|
4474
|
+
`${outPath} already exists. Use --force to overwrite.`
|
|
4475
|
+
);
|
|
4476
|
+
}
|
|
4477
|
+
writeFileSync3(outPath, formatted, "utf-8");
|
|
4478
|
+
console.log(chalk7.green(`\u2713 Exported to ${outPath}`));
|
|
4479
|
+
const models = configData.models ?? [];
|
|
4480
|
+
const operations = configData.operations ?? [];
|
|
4481
|
+
const hooks = configData.hooks ?? [];
|
|
4482
|
+
const segments = configData.segments ?? [];
|
|
4483
|
+
const schedules = configData.schedules ?? [];
|
|
4484
|
+
const authProviders = configData.authProviders ?? [];
|
|
4485
|
+
const parts = [];
|
|
4486
|
+
if (models.length > 0) parts.push(`${models.length} model(s)`);
|
|
4487
|
+
if (operations.length > 0) parts.push(`${operations.length} operation(s)`);
|
|
4488
|
+
if (hooks.length > 0) parts.push(`${hooks.length} hook(s)`);
|
|
4489
|
+
if (segments.length > 0) parts.push(`${segments.length} segment(s)`);
|
|
4490
|
+
if (schedules.length > 0) parts.push(`${schedules.length} schedule(s)`);
|
|
4491
|
+
if (authProviders.length > 0) parts.push(`${authProviders.length} auth provider(s)`);
|
|
4492
|
+
if (configData.customerProfileSchema) parts.push("customer profile schema");
|
|
4493
|
+
if (parts.length > 0) {
|
|
4494
|
+
console.log(chalk7.dim(` Contains: ${parts.join(", ")}`));
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4497
|
+
)
|
|
4498
|
+
);
|
|
4499
|
+
}
|
|
4500
|
+
|
|
4501
|
+
// src/commands/remove.ts
|
|
4502
|
+
import chalk8 from "chalk";
|
|
4294
4503
|
import inquirer5 from "inquirer";
|
|
4295
4504
|
function registerRemoveCommand(program2, globalOpts) {
|
|
4296
4505
|
program2.command("remove <key>").description("Remove a config and all its provisioned resources").option("--force", "Skip confirmation prompt", false).action(
|
|
@@ -4312,13 +4521,13 @@ function registerRemoveCommand(program2, globalOpts) {
|
|
|
4312
4521
|
}
|
|
4313
4522
|
]);
|
|
4314
4523
|
if (!confirmed) {
|
|
4315
|
-
console.log(
|
|
4524
|
+
console.log(chalk8.dim("Cancelled."));
|
|
4316
4525
|
return;
|
|
4317
4526
|
}
|
|
4318
4527
|
}
|
|
4319
4528
|
await client.configs.deleteConfig(config2.id);
|
|
4320
4529
|
console.log(
|
|
4321
|
-
|
|
4530
|
+
chalk8.green(`Removed config "${config2.name}" (${config2.key}).`)
|
|
4322
4531
|
);
|
|
4323
4532
|
}
|
|
4324
4533
|
)
|
|
@@ -4326,7 +4535,7 @@ function registerRemoveCommand(program2, globalOpts) {
|
|
|
4326
4535
|
}
|
|
4327
4536
|
|
|
4328
4537
|
// src/commands/profiles.ts
|
|
4329
|
-
import
|
|
4538
|
+
import chalk9 from "chalk";
|
|
4330
4539
|
function registerProfilesCommand(program2, globalOpts) {
|
|
4331
4540
|
const profiles = program2.command("profiles").description("Manage named project profiles");
|
|
4332
4541
|
profiles.command("list").description("List all saved project profiles").action(
|
|
@@ -4486,7 +4695,7 @@ function registerProfilesCommand(program2, globalOpts) {
|
|
|
4486
4695
|
if (opts.json || opts.jsonl) {
|
|
4487
4696
|
formatOutput({ deleted: name }, opts);
|
|
4488
4697
|
} else {
|
|
4489
|
-
console.log(
|
|
4698
|
+
console.log(chalk9.green(`Deleted profile "${name}".`));
|
|
4490
4699
|
}
|
|
4491
4700
|
}
|
|
4492
4701
|
)
|
|
@@ -4495,8 +4704,8 @@ function registerProfilesCommand(program2, globalOpts) {
|
|
|
4495
4704
|
|
|
4496
4705
|
// src/commands/register-commands.ts
|
|
4497
4706
|
import { readdirSync } from "fs";
|
|
4498
|
-
import { resolve as
|
|
4499
|
-
import
|
|
4707
|
+
import { resolve as resolve6 } from "path";
|
|
4708
|
+
import chalk10 from "chalk";
|
|
4500
4709
|
|
|
4501
4710
|
// src/command-registry/command-map.ts
|
|
4502
4711
|
var COMMANDS = [
|
|
@@ -6294,7 +6503,7 @@ function buildDispatchTable() {
|
|
|
6294
6503
|
unregisterConfig: async (v, c) => await c.configs.deleteConfig(str(v.id)),
|
|
6295
6504
|
triggerConfigSync: async (v, _c) => {
|
|
6296
6505
|
console.log(
|
|
6297
|
-
|
|
6506
|
+
chalk10.yellow(
|
|
6298
6507
|
`Config sync trigger for ${str(v.configId)} is not yet available via ConnectRPC.`
|
|
6299
6508
|
)
|
|
6300
6509
|
);
|
|
@@ -6464,11 +6673,11 @@ function registerDynamicCommands(program2, globalOpts) {
|
|
|
6464
6673
|
variables.limit = flags.limit;
|
|
6465
6674
|
}
|
|
6466
6675
|
if (flags.dir && entry.acceptsInput) {
|
|
6467
|
-
const dirPath =
|
|
6676
|
+
const dirPath = resolve6(String(flags.dir));
|
|
6468
6677
|
const files = readdirSync(dirPath).filter((f) => /\.(json|ts|js|mjs)$/.test(f)).sort();
|
|
6469
6678
|
if (files.length === 0) {
|
|
6470
6679
|
console.error(
|
|
6471
|
-
|
|
6680
|
+
chalk10.yellow(`No .json/.ts/.js files found in ${dirPath}`)
|
|
6472
6681
|
);
|
|
6473
6682
|
return;
|
|
6474
6683
|
}
|
|
@@ -6476,7 +6685,7 @@ function registerDynamicCommands(program2, globalOpts) {
|
|
|
6476
6685
|
let updated = 0;
|
|
6477
6686
|
let failed = 0;
|
|
6478
6687
|
for (const file of files) {
|
|
6479
|
-
const filePath =
|
|
6688
|
+
const filePath = resolve6(dirPath, file);
|
|
6480
6689
|
const fileData = await parseInputData({ file: filePath });
|
|
6481
6690
|
const argName = entry.inputArgName ?? "input";
|
|
6482
6691
|
const fileVars = { ...variables, [argName]: fileData };
|
|
@@ -6511,19 +6720,19 @@ function registerDynamicCommands(program2, globalOpts) {
|
|
|
6511
6720
|
} catch (updateErr) {
|
|
6512
6721
|
failed++;
|
|
6513
6722
|
const msg2 = updateErr instanceof Error ? updateErr.message : String(updateErr);
|
|
6514
|
-
console.error(
|
|
6723
|
+
console.error(chalk10.red(`\u2717 ${label}:`), msg2);
|
|
6515
6724
|
continue;
|
|
6516
6725
|
}
|
|
6517
6726
|
}
|
|
6518
6727
|
failed++;
|
|
6519
6728
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6520
|
-
console.error(
|
|
6729
|
+
console.error(chalk10.red(`\u2717 ${label}:`), msg);
|
|
6521
6730
|
}
|
|
6522
6731
|
}
|
|
6523
6732
|
if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6524
6733
|
console.log("");
|
|
6525
6734
|
console.log(
|
|
6526
|
-
|
|
6735
|
+
chalk10.bold(
|
|
6527
6736
|
`Done: ${created} created${updated ? `, ${updated} updated` : ""}${failed ? `, ${failed} failed` : ""}`
|
|
6528
6737
|
)
|
|
6529
6738
|
);
|
|
@@ -6684,7 +6893,7 @@ function registerDynamicCommands(program2, globalOpts) {
|
|
|
6684
6893
|
}
|
|
6685
6894
|
} else if (!(opts.json || opts.jsonl || opts.quiet)) {
|
|
6686
6895
|
console.error(
|
|
6687
|
-
|
|
6896
|
+
chalk10.yellow(
|
|
6688
6897
|
"Could not auto-publish: no version found in response"
|
|
6689
6898
|
)
|
|
6690
6899
|
);
|
|
@@ -6699,7 +6908,7 @@ function registerDynamicCommands(program2, globalOpts) {
|
|
|
6699
6908
|
// src/cli.ts
|
|
6700
6909
|
var __filename = fileURLToPath(import.meta.url);
|
|
6701
6910
|
var __dirname = dirname4(__filename);
|
|
6702
|
-
config({ path:
|
|
6911
|
+
config({ path: resolve7(__dirname, "../.env.local") });
|
|
6703
6912
|
var require2 = createRequire(import.meta.url);
|
|
6704
6913
|
var { version } = require2("../package.json");
|
|
6705
6914
|
var program = new Command();
|
|
@@ -6722,6 +6931,7 @@ registerProfilesCommand(program, getGlobalOpts);
|
|
|
6722
6931
|
registerMediaCommands(program, getGlobalOpts);
|
|
6723
6932
|
registerSearchCommands(program, getGlobalOpts);
|
|
6724
6933
|
registerPushCommand(program, getGlobalOpts);
|
|
6934
|
+
registerPullCommand(program, getGlobalOpts);
|
|
6725
6935
|
registerRemoveCommand(program, getGlobalOpts);
|
|
6726
6936
|
registerCreateConfigCommand(program, getGlobalOpts);
|
|
6727
6937
|
registerInitCommands(program, getGlobalOpts);
|
|
@@ -98,6 +98,16 @@ interface ApplyConfigHookInput {
|
|
|
98
98
|
expression?: Record<string, unknown>;
|
|
99
99
|
hooks?: ApplyConfigHookInput[];
|
|
100
100
|
}
|
|
101
|
+
interface ApplyConfigApiKeyInput {
|
|
102
|
+
/** Name for this API key (e.g. "Tilly iOS", "Tilly BFF"). */
|
|
103
|
+
name: string;
|
|
104
|
+
/** Key type: 'public' for client apps, 'secret' for BFF/server. */
|
|
105
|
+
keyType: 'public' | 'secret';
|
|
106
|
+
/** Environment variable name to write the key to in .env (e.g. "FOIR_PUBLIC_KEY"). */
|
|
107
|
+
envVar: string;
|
|
108
|
+
/** Optional scopes to restrict the key. */
|
|
109
|
+
scopes?: Record<string, unknown>;
|
|
110
|
+
}
|
|
101
111
|
interface ApplyConfigInput {
|
|
102
112
|
key: string;
|
|
103
113
|
name: string;
|
|
@@ -110,6 +120,7 @@ interface ApplyConfigInput {
|
|
|
110
120
|
hooks?: ApplyConfigHookInput[];
|
|
111
121
|
authProviders?: ApplyConfigAuthProviderInput[];
|
|
112
122
|
placements?: ApplyConfigPlacementInput[];
|
|
123
|
+
apiKeys?: ApplyConfigApiKeyInput[];
|
|
113
124
|
[key: string]: unknown;
|
|
114
125
|
}
|
|
115
126
|
/** Define a complete config manifest. */
|
|
@@ -133,4 +144,4 @@ declare function defineHook(hook: ApplyConfigHookInput): ApplyConfigHookInput;
|
|
|
133
144
|
/** Define an editor placement (sidebar or main-editor tab). */
|
|
134
145
|
declare function definePlacement(placement: ApplyConfigPlacementInput): ApplyConfigPlacementInput;
|
|
135
146
|
|
|
136
|
-
export { type ApplyConfigAuthProviderInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type FieldDefinitionInput, defineAuthProvider, defineConfig, defineExtension, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSegment };
|
|
147
|
+
export { type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type FieldDefinitionInput, defineAuthProvider, defineConfig, defineExtension, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSegment };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eide/foir-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Universal platform CLI for Foir platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@bufbuild/protobuf": "^2.0.0",
|
|
50
50
|
"@connectrpc/connect": "^2.0.0",
|
|
51
51
|
"@connectrpc/connect-node": "^2.0.0",
|
|
52
|
-
"@eide/foir-proto-ts": "^0.1
|
|
52
|
+
"@eide/foir-proto-ts": "^0.3.1",
|
|
53
53
|
"chalk": "^5.3.0",
|
|
54
54
|
"commander": "^12.1.0",
|
|
55
55
|
"dotenv": "^16.4.5",
|