@eide/foir-cli 0.2.0 → 0.3.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 +158 -38
- package/dist/lib/config-helpers.d.ts +12 -2
- package/package.json +11 -7
package/dist/cli.js
CHANGED
|
@@ -448,7 +448,7 @@ function registerLogoutCommand(program2, globalOpts) {
|
|
|
448
448
|
import inquirer from "inquirer";
|
|
449
449
|
|
|
450
450
|
// src/lib/client.ts
|
|
451
|
-
import { createClient } from "@connectrpc/connect";
|
|
451
|
+
import { createClient as createRpcClient } from "@connectrpc/connect";
|
|
452
452
|
import { createConnectTransport } from "@connectrpc/connect-node";
|
|
453
453
|
import {
|
|
454
454
|
IdentityService,
|
|
@@ -459,15 +459,16 @@ import {
|
|
|
459
459
|
ExperimentsService,
|
|
460
460
|
SettingsService,
|
|
461
461
|
StorageService
|
|
462
|
-
} from "@foir
|
|
463
|
-
import { createIdentityMethods } from "@foir
|
|
464
|
-
import { createModelsMethods } from "@foir
|
|
465
|
-
import { createRecordsMethods } from "@foir
|
|
466
|
-
import { createConfigsMethods } from "@foir
|
|
467
|
-
import { createSegmentsMethods } from "@foir
|
|
468
|
-
import { createExperimentsMethods } from "@foir
|
|
469
|
-
import { createSettingsMethods } from "@foir
|
|
470
|
-
import { createStorageMethods } from "@foir
|
|
462
|
+
} from "@eide/foir-connect-clients/services";
|
|
463
|
+
import { createIdentityMethods } from "@eide/foir-connect-clients/identity";
|
|
464
|
+
import { createModelsMethods } from "@eide/foir-connect-clients/models";
|
|
465
|
+
import { createRecordsMethods } from "@eide/foir-connect-clients/records";
|
|
466
|
+
import { createConfigsMethods } from "@eide/foir-connect-clients/configs";
|
|
467
|
+
import { createSegmentsMethods } from "@eide/foir-connect-clients/segments";
|
|
468
|
+
import { createExperimentsMethods } from "@eide/foir-connect-clients/experiments";
|
|
469
|
+
import { createSettingsMethods } from "@eide/foir-connect-clients/settings";
|
|
470
|
+
import { createStorageMethods } from "@eide/foir-connect-clients/storage";
|
|
471
|
+
import { GraphQLClient } from "graphql-request";
|
|
471
472
|
async function createPlatformClient(options) {
|
|
472
473
|
const apiUrl = getApiUrl(options);
|
|
473
474
|
const headers = {};
|
|
@@ -503,16 +504,16 @@ async function createPlatformClient(options) {
|
|
|
503
504
|
interceptors: [authInterceptor]
|
|
504
505
|
});
|
|
505
506
|
return {
|
|
506
|
-
identity: createIdentityMethods(
|
|
507
|
-
models: createModelsMethods(
|
|
508
|
-
records: createRecordsMethods(
|
|
509
|
-
configs: createConfigsMethods(
|
|
510
|
-
segments: createSegmentsMethods(
|
|
507
|
+
identity: createIdentityMethods(createRpcClient(IdentityService, transport)),
|
|
508
|
+
models: createModelsMethods(createRpcClient(ModelsService, transport)),
|
|
509
|
+
records: createRecordsMethods(createRpcClient(RecordsService, transport)),
|
|
510
|
+
configs: createConfigsMethods(createRpcClient(ConfigsService, transport)),
|
|
511
|
+
segments: createSegmentsMethods(createRpcClient(SegmentsService, transport)),
|
|
511
512
|
experiments: createExperimentsMethods(
|
|
512
|
-
|
|
513
|
+
createRpcClient(ExperimentsService, transport)
|
|
513
514
|
),
|
|
514
|
-
settings: createSettingsMethods(
|
|
515
|
-
storage: createStorageMethods(
|
|
515
|
+
settings: createSettingsMethods(createRpcClient(SettingsService, transport)),
|
|
516
|
+
storage: createStorageMethods(createRpcClient(StorageService, transport))
|
|
516
517
|
};
|
|
517
518
|
}
|
|
518
519
|
function createPlatformClientWithHeaders(apiUrl, headers) {
|
|
@@ -528,16 +529,16 @@ function createPlatformClientWithHeaders(apiUrl, headers) {
|
|
|
528
529
|
interceptors: [authInterceptor]
|
|
529
530
|
});
|
|
530
531
|
return {
|
|
531
|
-
identity: createIdentityMethods(
|
|
532
|
-
models: createModelsMethods(
|
|
533
|
-
records: createRecordsMethods(
|
|
534
|
-
configs: createConfigsMethods(
|
|
535
|
-
segments: createSegmentsMethods(
|
|
532
|
+
identity: createIdentityMethods(createRpcClient(IdentityService, transport)),
|
|
533
|
+
models: createModelsMethods(createRpcClient(ModelsService, transport)),
|
|
534
|
+
records: createRecordsMethods(createRpcClient(RecordsService, transport)),
|
|
535
|
+
configs: createConfigsMethods(createRpcClient(ConfigsService, transport)),
|
|
536
|
+
segments: createSegmentsMethods(createRpcClient(SegmentsService, transport)),
|
|
536
537
|
experiments: createExperimentsMethods(
|
|
537
|
-
|
|
538
|
+
createRpcClient(ExperimentsService, transport)
|
|
538
539
|
),
|
|
539
|
-
settings: createSettingsMethods(
|
|
540
|
-
storage: createStorageMethods(
|
|
540
|
+
settings: createSettingsMethods(createRpcClient(SettingsService, transport)),
|
|
541
|
+
storage: createStorageMethods(createRpcClient(StorageService, transport))
|
|
541
542
|
};
|
|
542
543
|
}
|
|
543
544
|
async function getStorageAuth(options) {
|
|
@@ -872,7 +873,7 @@ function registerWhoamiCommand(program2, globalOpts) {
|
|
|
872
873
|
import { promises as fs2 } from "fs";
|
|
873
874
|
import { basename } from "path";
|
|
874
875
|
import chalk3 from "chalk";
|
|
875
|
-
import { createStorageClient } from "@foir
|
|
876
|
+
import { createStorageClient } from "@eide/foir-connect-clients/storage";
|
|
876
877
|
|
|
877
878
|
// src/lib/input.ts
|
|
878
879
|
import inquirer2 from "inquirer";
|
|
@@ -966,7 +967,7 @@ function guessMimeType(filename) {
|
|
|
966
967
|
function getStorageUrl() {
|
|
967
968
|
return process.env.FOIR_STORAGE_URL ?? "https://storage.foir.dev";
|
|
968
969
|
}
|
|
969
|
-
function
|
|
970
|
+
function createClient(getToken) {
|
|
970
971
|
return createStorageClient({
|
|
971
972
|
baseUrl: getStorageUrl(),
|
|
972
973
|
getAuthToken: getToken
|
|
@@ -980,7 +981,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
980
981
|
async (filepath, flags) => {
|
|
981
982
|
const opts = globalOpts();
|
|
982
983
|
const { getToken } = await getStorageAuth(opts);
|
|
983
|
-
const storage =
|
|
984
|
+
const storage = createClient(getToken);
|
|
984
985
|
const fileBuffer = await fs2.readFile(filepath);
|
|
985
986
|
const filename = basename(filepath);
|
|
986
987
|
const mimeType = guessMimeType(filename);
|
|
@@ -1021,7 +1022,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1021
1022
|
async (flags) => {
|
|
1022
1023
|
const opts = globalOpts();
|
|
1023
1024
|
const { getToken } = await getStorageAuth(opts);
|
|
1024
|
-
const storage =
|
|
1025
|
+
const storage = createClient(getToken);
|
|
1025
1026
|
const result = await storage.listFiles({
|
|
1026
1027
|
folder: flags.folder,
|
|
1027
1028
|
mimeType: flags["mime-type"] ?? flags.mimeType,
|
|
@@ -1063,7 +1064,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1063
1064
|
withErrorHandler(globalOpts, async (id) => {
|
|
1064
1065
|
const opts = globalOpts();
|
|
1065
1066
|
const { getToken } = await getStorageAuth(opts);
|
|
1066
|
-
const storage =
|
|
1067
|
+
const storage = createClient(getToken);
|
|
1067
1068
|
const file = await storage.getFile(id);
|
|
1068
1069
|
formatOutput(file, opts);
|
|
1069
1070
|
})
|
|
@@ -1072,7 +1073,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1072
1073
|
withErrorHandler(globalOpts, async () => {
|
|
1073
1074
|
const opts = globalOpts();
|
|
1074
1075
|
const { getToken } = await getStorageAuth(opts);
|
|
1075
|
-
const storage =
|
|
1076
|
+
const storage = createClient(getToken);
|
|
1076
1077
|
const usage = await storage.getStorageUsage();
|
|
1077
1078
|
if (opts.json || opts.jsonl) {
|
|
1078
1079
|
formatOutput(usage, opts);
|
|
@@ -1091,7 +1092,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1091
1092
|
async (id, flags) => {
|
|
1092
1093
|
const opts = globalOpts();
|
|
1093
1094
|
const { getToken } = await getStorageAuth(opts);
|
|
1094
|
-
const storage =
|
|
1095
|
+
const storage = createClient(getToken);
|
|
1095
1096
|
const file = await storage.updateFile({
|
|
1096
1097
|
id,
|
|
1097
1098
|
filename: flags.filename,
|
|
@@ -1112,7 +1113,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1112
1113
|
async (id, flags) => {
|
|
1113
1114
|
const opts = globalOpts();
|
|
1114
1115
|
const { getToken } = await getStorageAuth(opts);
|
|
1115
|
-
const storage =
|
|
1116
|
+
const storage = createClient(getToken);
|
|
1116
1117
|
const file = await storage.updateFileMetadata({
|
|
1117
1118
|
id,
|
|
1118
1119
|
altText: flags.altText ?? flags["alt-text"],
|
|
@@ -1140,7 +1141,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1140
1141
|
return;
|
|
1141
1142
|
}
|
|
1142
1143
|
const { getToken } = await getStorageAuth(opts);
|
|
1143
|
-
const storage =
|
|
1144
|
+
const storage = createClient(getToken);
|
|
1144
1145
|
if (flags.permanent) {
|
|
1145
1146
|
await storage.permanentlyDeleteFile(id);
|
|
1146
1147
|
success("Permanently deleted file");
|
|
@@ -1155,7 +1156,7 @@ function registerMediaCommands(program2, globalOpts) {
|
|
|
1155
1156
|
withErrorHandler(globalOpts, async (id) => {
|
|
1156
1157
|
const opts = globalOpts();
|
|
1157
1158
|
const { getToken } = await getStorageAuth(opts);
|
|
1158
|
-
const storage =
|
|
1159
|
+
const storage = createClient(getToken);
|
|
1159
1160
|
const file = await storage.restoreFile(id);
|
|
1160
1161
|
if (opts.json || opts.jsonl) {
|
|
1161
1162
|
formatOutput(file, opts);
|
|
@@ -2258,7 +2259,7 @@ import { readdirSync } from "fs";
|
|
|
2258
2259
|
import { resolve as resolve5 } from "path";
|
|
2259
2260
|
import chalk9 from "chalk";
|
|
2260
2261
|
|
|
2261
|
-
//
|
|
2262
|
+
// src/command-registry/command-map.ts
|
|
2262
2263
|
var COMMANDS = [
|
|
2263
2264
|
// =========================================================================
|
|
2264
2265
|
// MODELS
|
|
@@ -2433,6 +2434,15 @@ var COMMANDS = [
|
|
|
2433
2434
|
scalarResult: true,
|
|
2434
2435
|
successMessage: "Unpublished record"
|
|
2435
2436
|
},
|
|
2437
|
+
{
|
|
2438
|
+
group: "records",
|
|
2439
|
+
name: "cancel-schedule",
|
|
2440
|
+
description: "Cancel a scheduled publish or unpublish",
|
|
2441
|
+
operation: "cancelScheduledRecordPublish",
|
|
2442
|
+
operationType: "mutation",
|
|
2443
|
+
positionalArgs: [{ name: "versionId", graphqlArg: "versionId", description: "Version ID" }],
|
|
2444
|
+
successMessage: "Cancelled scheduled publish for version {versionId}"
|
|
2445
|
+
},
|
|
2436
2446
|
{
|
|
2437
2447
|
group: "records",
|
|
2438
2448
|
name: "duplicate",
|
|
@@ -2489,6 +2499,104 @@ var COMMANDS = [
|
|
|
2489
2499
|
successMessage: "Created variant"
|
|
2490
2500
|
},
|
|
2491
2501
|
// =========================================================================
|
|
2502
|
+
// ROLLOUTS
|
|
2503
|
+
// =========================================================================
|
|
2504
|
+
{
|
|
2505
|
+
group: "rollouts",
|
|
2506
|
+
name: "list",
|
|
2507
|
+
description: "List rollouts",
|
|
2508
|
+
operation: "listPublishBatches",
|
|
2509
|
+
operationType: "query",
|
|
2510
|
+
columns: [
|
|
2511
|
+
{ key: "id", header: "ID", width: 28 },
|
|
2512
|
+
{ key: "name", header: "Name", width: 24 },
|
|
2513
|
+
{ key: "status", header: "Status", width: 16 },
|
|
2514
|
+
{ key: "itemCount", header: "Items", width: 6 },
|
|
2515
|
+
{ key: "completedCount", header: "Done", width: 6 },
|
|
2516
|
+
{ key: "scheduledAt", header: "Scheduled", width: 12, format: "timeAgo" },
|
|
2517
|
+
{ key: "createdAt", header: "Created", width: 12, format: "timeAgo" }
|
|
2518
|
+
]
|
|
2519
|
+
},
|
|
2520
|
+
{
|
|
2521
|
+
group: "rollouts",
|
|
2522
|
+
name: "get",
|
|
2523
|
+
description: "Get a rollout",
|
|
2524
|
+
operation: "getPublishBatch",
|
|
2525
|
+
operationType: "query",
|
|
2526
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }]
|
|
2527
|
+
},
|
|
2528
|
+
{
|
|
2529
|
+
group: "rollouts",
|
|
2530
|
+
name: "create",
|
|
2531
|
+
description: "Create a rollout",
|
|
2532
|
+
operation: "createPublishBatch",
|
|
2533
|
+
operationType: "mutation",
|
|
2534
|
+
acceptsInput: true,
|
|
2535
|
+
successMessage: "Created rollout {name}"
|
|
2536
|
+
},
|
|
2537
|
+
{
|
|
2538
|
+
group: "rollouts",
|
|
2539
|
+
name: "update",
|
|
2540
|
+
description: "Update a rollout",
|
|
2541
|
+
operation: "updatePublishBatch",
|
|
2542
|
+
operationType: "mutation",
|
|
2543
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2544
|
+
acceptsInput: true,
|
|
2545
|
+
successMessage: "Updated rollout"
|
|
2546
|
+
},
|
|
2547
|
+
{
|
|
2548
|
+
group: "rollouts",
|
|
2549
|
+
name: "cancel",
|
|
2550
|
+
description: "Cancel a rollout",
|
|
2551
|
+
operation: "cancelPublishBatch",
|
|
2552
|
+
operationType: "mutation",
|
|
2553
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2554
|
+
requiresConfirmation: true,
|
|
2555
|
+
scalarResult: true,
|
|
2556
|
+
successMessage: "Cancelled rollout"
|
|
2557
|
+
},
|
|
2558
|
+
{
|
|
2559
|
+
group: "rollouts",
|
|
2560
|
+
name: "rollback",
|
|
2561
|
+
description: "Rollback a completed rollout",
|
|
2562
|
+
operation: "rollbackPublishBatch",
|
|
2563
|
+
operationType: "mutation",
|
|
2564
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2565
|
+
requiresConfirmation: true,
|
|
2566
|
+
scalarResult: true,
|
|
2567
|
+
successMessage: "Rolled back rollout"
|
|
2568
|
+
},
|
|
2569
|
+
{
|
|
2570
|
+
group: "rollouts",
|
|
2571
|
+
name: "retry",
|
|
2572
|
+
description: "Retry failed items in a rollout",
|
|
2573
|
+
operation: "retryFailedBatchItems",
|
|
2574
|
+
operationType: "mutation",
|
|
2575
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2576
|
+
scalarResult: true,
|
|
2577
|
+
successMessage: "Retrying failed items in rollout"
|
|
2578
|
+
},
|
|
2579
|
+
{
|
|
2580
|
+
group: "rollouts",
|
|
2581
|
+
name: "add-items",
|
|
2582
|
+
description: "Add version IDs to a rollout",
|
|
2583
|
+
operation: "addItemsToPublishBatch",
|
|
2584
|
+
operationType: "mutation",
|
|
2585
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2586
|
+
acceptsInput: true,
|
|
2587
|
+
successMessage: "Added items to rollout"
|
|
2588
|
+
},
|
|
2589
|
+
{
|
|
2590
|
+
group: "rollouts",
|
|
2591
|
+
name: "remove-items",
|
|
2592
|
+
description: "Remove version IDs from a rollout",
|
|
2593
|
+
operation: "removeItemsFromPublishBatch",
|
|
2594
|
+
operationType: "mutation",
|
|
2595
|
+
positionalArgs: [{ name: "id", graphqlArg: "id", description: "Rollout ID" }],
|
|
2596
|
+
acceptsInput: true,
|
|
2597
|
+
successMessage: "Removed items from rollout"
|
|
2598
|
+
},
|
|
2599
|
+
// =========================================================================
|
|
2492
2600
|
// LOCALES
|
|
2493
2601
|
// =========================================================================
|
|
2494
2602
|
{
|
|
@@ -3197,6 +3305,7 @@ var COMMANDS = [
|
|
|
3197
3305
|
description: "List hook deliveries",
|
|
3198
3306
|
operation: "hookDeliveries",
|
|
3199
3307
|
operationType: "query",
|
|
3308
|
+
positionalArgs: [{ name: "hookId", graphqlArg: "hookId", description: "Hook ID" }],
|
|
3200
3309
|
columns: [
|
|
3201
3310
|
{ key: "id", header: "ID", width: 28 },
|
|
3202
3311
|
{ key: "event", header: "Event", width: 16 },
|
|
@@ -3600,8 +3709,19 @@ var COMMANDS = [
|
|
|
3600
3709
|
}
|
|
3601
3710
|
];
|
|
3602
3711
|
|
|
3712
|
+
// src/command-registry/schema-engine.ts
|
|
3713
|
+
import {
|
|
3714
|
+
buildSchema,
|
|
3715
|
+
isObjectType,
|
|
3716
|
+
isInputObjectType,
|
|
3717
|
+
isListType,
|
|
3718
|
+
isNonNullType,
|
|
3719
|
+
isScalarType,
|
|
3720
|
+
isEnumType
|
|
3721
|
+
} from "graphql";
|
|
3722
|
+
|
|
3603
3723
|
// src/commands/register-commands.ts
|
|
3604
|
-
import { RecordType } from "@foir
|
|
3724
|
+
import { RecordType } from "@eide/foir-connect-clients/records";
|
|
3605
3725
|
function buildDispatchTable() {
|
|
3606
3726
|
return {
|
|
3607
3727
|
// ── Models ──────────────────────────────────────────────────
|
|
@@ -40,7 +40,8 @@ interface ApplyConfigOperationInput {
|
|
|
40
40
|
name: string;
|
|
41
41
|
description?: string;
|
|
42
42
|
category?: string;
|
|
43
|
-
|
|
43
|
+
/** HTTP endpoint URL that the platform calls when this operation is triggered. */
|
|
44
|
+
endpoint?: string;
|
|
44
45
|
config?: Record<string, unknown>;
|
|
45
46
|
isActive?: boolean;
|
|
46
47
|
}
|
|
@@ -78,8 +79,17 @@ interface ApplyConfigPlacementInput {
|
|
|
78
79
|
modelKeys?: string[];
|
|
79
80
|
}
|
|
80
81
|
interface ApplyConfigHookInput {
|
|
82
|
+
/** Unique key for this hook. */
|
|
83
|
+
key?: string;
|
|
84
|
+
/** Display name. */
|
|
85
|
+
name?: string;
|
|
86
|
+
/** Lifecycle event that triggers this hook. */
|
|
81
87
|
event: string;
|
|
82
|
-
|
|
88
|
+
/** Key of the operation to execute. */
|
|
89
|
+
operationKey?: string;
|
|
90
|
+
/** Filter to scope the hook (e.g., `{ modelKey: 'redirect' }`). */
|
|
91
|
+
filter?: Record<string, unknown>;
|
|
92
|
+
type?: string;
|
|
83
93
|
url?: string;
|
|
84
94
|
method?: string;
|
|
85
95
|
async?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eide/foir-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Universal platform CLI for Foir platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -49,19 +49,23 @@
|
|
|
49
49
|
"@bufbuild/protobuf": "^2.0.0",
|
|
50
50
|
"@connectrpc/connect": "^2.0.0",
|
|
51
51
|
"@connectrpc/connect-node": "^2.0.0",
|
|
52
|
-
"@foir
|
|
52
|
+
"@eide/foir-connect-clients": "0.2.2",
|
|
53
53
|
"chalk": "^5.3.0",
|
|
54
54
|
"commander": "^12.1.0",
|
|
55
55
|
"dotenv": "^16.4.5",
|
|
56
|
+
"graphql": "^16.13.2",
|
|
57
|
+
"graphql-request": "^7.4.0",
|
|
56
58
|
"inquirer": "^9.2.12",
|
|
57
59
|
"open": "^10.1.0",
|
|
58
60
|
"ora": "^8.1.1",
|
|
59
61
|
"prettier": "^3.4.2"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@eide/command-registry": "workspace:*",
|
|
63
64
|
"@types/inquirer": "^9.0.7",
|
|
64
65
|
"@types/node": "^22.5.0",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
67
|
+
"@typescript-eslint/parser": "^8.58.0",
|
|
68
|
+
"eslint": "^10.1.0",
|
|
65
69
|
"tsup": "^8.5.1",
|
|
66
70
|
"tsx": "^4.20.0",
|
|
67
71
|
"typescript": "5.9.2",
|
|
@@ -72,7 +76,7 @@
|
|
|
72
76
|
},
|
|
73
77
|
"repository": {
|
|
74
78
|
"type": "git",
|
|
75
|
-
"url": "https://github.com/eidestudio/foir.git"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
+
"url": "https://github.com/eidestudio/foir-cli.git"
|
|
80
|
+
},
|
|
81
|
+
"packageManager": "pnpm@9.15.4"
|
|
82
|
+
}
|