@eide/foir-cli 0.23.0 → 0.25.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 +913 -29
- package/dist/lib/config-helpers.d.ts +24 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -469,7 +469,7 @@ import { StorageService as StorageService2 } from "@eide/foir-proto-ts/storage/v
|
|
|
469
469
|
import { OperationsService as OperationsService2 } from "@eide/foir-proto-ts/operations/v1/operations_pb";
|
|
470
470
|
import { HooksService as HooksService2 } from "@eide/foir-proto-ts/hooks/v1/hooks_pb";
|
|
471
471
|
import { NotificationsService as NotificationsService2 } from "@eide/foir-proto-ts/notifications/v1/notifications_pb";
|
|
472
|
-
import { SchedulesService as
|
|
472
|
+
import { SchedulesService as SchedulesService3 } from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
473
473
|
import { AppsService as AppsService2 } from "@eide/foir-proto-ts/apps/v1/apps_service_pb";
|
|
474
474
|
import { SecretsService as SecretsService2 } from "@eide/foir-proto-ts/secrets/v1/secrets_pb";
|
|
475
475
|
|
|
@@ -1281,6 +1281,7 @@ import {
|
|
|
1281
1281
|
FieldSchema as ProtoFieldSchema,
|
|
1282
1282
|
SharingConfigSchema as ProtoSharingConfigSchema,
|
|
1283
1283
|
ModelConfigSchema as ProtoModelConfigSchema,
|
|
1284
|
+
LookupDefinitionSchema as ProtoLookupDefinitionSchema,
|
|
1284
1285
|
CreateModelRequestSchema,
|
|
1285
1286
|
GetModelRequestSchema,
|
|
1286
1287
|
GetModelByKeyRequestSchema,
|
|
@@ -1328,7 +1329,13 @@ function jsConfigToProto(c) {
|
|
|
1328
1329
|
naturalKeyField: c.naturalKeyField,
|
|
1329
1330
|
systemEntity: c.systemEntity ?? false,
|
|
1330
1331
|
deletable: c.deletable,
|
|
1331
|
-
editable: c.editable
|
|
1332
|
+
editable: c.editable,
|
|
1333
|
+
lookups: c.lookups ? c.lookups.map(
|
|
1334
|
+
(l) => create3(ProtoLookupDefinitionSchema, {
|
|
1335
|
+
keyBy: l.keyBy ?? [],
|
|
1336
|
+
name: l.name
|
|
1337
|
+
})
|
|
1338
|
+
) : []
|
|
1332
1339
|
});
|
|
1333
1340
|
}
|
|
1334
1341
|
function createModelsMethods(client) {
|
|
@@ -1383,7 +1390,8 @@ function createModelsMethods(client) {
|
|
|
1383
1390
|
config: params.config ? jsConfigToProto(params.config) : void 0,
|
|
1384
1391
|
changeDescription: params.changeDescription,
|
|
1385
1392
|
updatePushSnapshot: params.updatePushSnapshot ?? false,
|
|
1386
|
-
snapshotOnly: params.snapshotOnly ?? false
|
|
1393
|
+
snapshotOnly: params.snapshotOnly ?? false,
|
|
1394
|
+
allowLookupRebuild: params.allowLookupRebuild ?? false
|
|
1387
1395
|
})
|
|
1388
1396
|
);
|
|
1389
1397
|
return resp.model ?? null;
|
|
@@ -1464,7 +1472,10 @@ import {
|
|
|
1464
1472
|
GlobalSearchRequestSchema,
|
|
1465
1473
|
GetEmbeddingStatsRequestSchema,
|
|
1466
1474
|
GetRecordEmbeddingsRequestSchema,
|
|
1467
|
-
FindSimilarRecordsRequestSchema
|
|
1475
|
+
FindSimilarRecordsRequestSchema,
|
|
1476
|
+
WriteEmbeddingsRequestSchema,
|
|
1477
|
+
DeleteEmbeddingsRequestSchema,
|
|
1478
|
+
SearchEmbeddingsRequestSchema
|
|
1468
1479
|
} from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
1469
1480
|
import { RecordType } from "@eide/foir-proto-ts/records/v1/records_pb";
|
|
1470
1481
|
function sanitizeData(obj) {
|
|
@@ -1812,6 +1823,34 @@ function createRecordsMethods(client) {
|
|
|
1812
1823
|
})
|
|
1813
1824
|
);
|
|
1814
1825
|
return resp.records ?? [];
|
|
1826
|
+
},
|
|
1827
|
+
async writeEmbeddings(params) {
|
|
1828
|
+
const resp = await client.writeEmbeddings(
|
|
1829
|
+
create4(WriteEmbeddingsRequestSchema, {
|
|
1830
|
+
recordId: params.recordId,
|
|
1831
|
+
vector: params.vector,
|
|
1832
|
+
dimensions: params.dimensions,
|
|
1833
|
+
provider: params.provider,
|
|
1834
|
+
modelName: params.modelName
|
|
1835
|
+
})
|
|
1836
|
+
);
|
|
1837
|
+
return resp.success;
|
|
1838
|
+
},
|
|
1839
|
+
async deleteEmbeddings(recordId) {
|
|
1840
|
+
const resp = await client.deleteEmbeddings(
|
|
1841
|
+
create4(DeleteEmbeddingsRequestSchema, { recordId })
|
|
1842
|
+
);
|
|
1843
|
+
return resp.success;
|
|
1844
|
+
},
|
|
1845
|
+
async searchEmbeddings(params) {
|
|
1846
|
+
const resp = await client.searchEmbeddings(
|
|
1847
|
+
create4(SearchEmbeddingsRequestSchema, {
|
|
1848
|
+
queryVector: params.queryVector,
|
|
1849
|
+
modelKey: params.modelKey,
|
|
1850
|
+
limit: params.limit ?? 10
|
|
1851
|
+
})
|
|
1852
|
+
);
|
|
1853
|
+
return resp.results ?? [];
|
|
1815
1854
|
}
|
|
1816
1855
|
};
|
|
1817
1856
|
}
|
|
@@ -3032,8 +3071,144 @@ function createCronSchedulesMethods(client) {
|
|
|
3032
3071
|
};
|
|
3033
3072
|
}
|
|
3034
3073
|
|
|
3035
|
-
// src/lib/rpc/
|
|
3074
|
+
// src/lib/rpc/publish-batches.ts
|
|
3036
3075
|
import { create as create13 } from "@bufbuild/protobuf";
|
|
3076
|
+
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
|
3077
|
+
import {
|
|
3078
|
+
ListPublishBatchesRequestSchema,
|
|
3079
|
+
GetPublishBatchRequestSchema,
|
|
3080
|
+
CreatePublishBatchRequestSchema,
|
|
3081
|
+
UpdatePublishBatchRequestSchema,
|
|
3082
|
+
DeletePublishBatchRequestSchema,
|
|
3083
|
+
TriggerPublishBatchRequestSchema,
|
|
3084
|
+
PausePublishBatchRequestSchema,
|
|
3085
|
+
ResumePublishBatchRequestSchema,
|
|
3086
|
+
PreviewRollbackBatchRequestSchema,
|
|
3087
|
+
RollbackPublishBatchRequestSchema,
|
|
3088
|
+
RetryFailedBatchItemsRequestSchema,
|
|
3089
|
+
AddItemsToPublishBatchRequestSchema,
|
|
3090
|
+
RemoveItemsFromPublishBatchRequestSchema
|
|
3091
|
+
} from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
3092
|
+
function createPublishBatchesMethods(client) {
|
|
3093
|
+
return {
|
|
3094
|
+
async listPublishBatches(params = {}) {
|
|
3095
|
+
const resp = await client.listPublishBatches(
|
|
3096
|
+
create13(ListPublishBatchesRequestSchema, {
|
|
3097
|
+
status: params.status,
|
|
3098
|
+
limit: params.limit ?? 50,
|
|
3099
|
+
offset: params.offset ?? 0
|
|
3100
|
+
})
|
|
3101
|
+
);
|
|
3102
|
+
return { batches: resp.batches ?? [], total: resp.total };
|
|
3103
|
+
},
|
|
3104
|
+
async getPublishBatch(id) {
|
|
3105
|
+
const resp = await client.getPublishBatch(
|
|
3106
|
+
create13(GetPublishBatchRequestSchema, { id })
|
|
3107
|
+
);
|
|
3108
|
+
return { batch: resp.batch ?? null, items: resp.items ?? [] };
|
|
3109
|
+
},
|
|
3110
|
+
async createPublishBatch(input) {
|
|
3111
|
+
const resp = await client.createPublishBatch(
|
|
3112
|
+
create13(CreatePublishBatchRequestSchema, {
|
|
3113
|
+
name: input.name,
|
|
3114
|
+
description: input.description,
|
|
3115
|
+
scheduledAt: timestampFromDate(input.scheduledAt),
|
|
3116
|
+
versionIds: input.versionIds ?? [],
|
|
3117
|
+
modelIds: input.modelIds ?? [],
|
|
3118
|
+
operationIds: input.operationIds ?? [],
|
|
3119
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3120
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3121
|
+
includeProfileSchema: input.includeProfileSchema ?? false
|
|
3122
|
+
})
|
|
3123
|
+
);
|
|
3124
|
+
return resp.batch ?? null;
|
|
3125
|
+
},
|
|
3126
|
+
async updatePublishBatch(input) {
|
|
3127
|
+
const resp = await client.updatePublishBatch(
|
|
3128
|
+
create13(UpdatePublishBatchRequestSchema, {
|
|
3129
|
+
id: input.id,
|
|
3130
|
+
name: input.name,
|
|
3131
|
+
description: input.description,
|
|
3132
|
+
scheduledAt: input.scheduledAt ? timestampFromDate(input.scheduledAt) : void 0
|
|
3133
|
+
})
|
|
3134
|
+
);
|
|
3135
|
+
return resp.batch ?? null;
|
|
3136
|
+
},
|
|
3137
|
+
async deletePublishBatch(id) {
|
|
3138
|
+
const resp = await client.deletePublishBatch(
|
|
3139
|
+
create13(DeletePublishBatchRequestSchema, { id })
|
|
3140
|
+
);
|
|
3141
|
+
return resp.success;
|
|
3142
|
+
},
|
|
3143
|
+
async triggerPublishBatch(id) {
|
|
3144
|
+
const resp = await client.triggerPublishBatch(
|
|
3145
|
+
create13(TriggerPublishBatchRequestSchema, { id })
|
|
3146
|
+
);
|
|
3147
|
+
return resp.batch ?? null;
|
|
3148
|
+
},
|
|
3149
|
+
async pausePublishBatch(id) {
|
|
3150
|
+
const resp = await client.pausePublishBatch(
|
|
3151
|
+
create13(PausePublishBatchRequestSchema, { id })
|
|
3152
|
+
);
|
|
3153
|
+
return resp.batch ?? null;
|
|
3154
|
+
},
|
|
3155
|
+
async resumePublishBatch(id) {
|
|
3156
|
+
const resp = await client.resumePublishBatch(
|
|
3157
|
+
create13(ResumePublishBatchRequestSchema, { id })
|
|
3158
|
+
);
|
|
3159
|
+
return resp.batch ?? null;
|
|
3160
|
+
},
|
|
3161
|
+
async previewRollback(batchId) {
|
|
3162
|
+
const resp = await client.previewRollbackBatch(
|
|
3163
|
+
create13(PreviewRollbackBatchRequestSchema, { batchId })
|
|
3164
|
+
);
|
|
3165
|
+
return resp;
|
|
3166
|
+
},
|
|
3167
|
+
async rollbackPublishBatch(batchId) {
|
|
3168
|
+
const resp = await client.rollbackPublishBatch(
|
|
3169
|
+
create13(RollbackPublishBatchRequestSchema, { batchId })
|
|
3170
|
+
);
|
|
3171
|
+
return resp.batch ?? null;
|
|
3172
|
+
},
|
|
3173
|
+
async retryFailedItems(batchId) {
|
|
3174
|
+
const resp = await client.retryFailedBatchItems(
|
|
3175
|
+
create13(RetryFailedBatchItemsRequestSchema, { batchId })
|
|
3176
|
+
);
|
|
3177
|
+
return resp.batch ?? null;
|
|
3178
|
+
},
|
|
3179
|
+
async addItems(input) {
|
|
3180
|
+
const resp = await client.addItemsToPublishBatch(
|
|
3181
|
+
create13(AddItemsToPublishBatchRequestSchema, {
|
|
3182
|
+
batchId: input.batchId,
|
|
3183
|
+
versionIds: input.versionIds ?? [],
|
|
3184
|
+
modelIds: input.modelIds ?? [],
|
|
3185
|
+
operationIds: input.operationIds ?? [],
|
|
3186
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3187
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3188
|
+
includeProfileSchema: input.includeProfileSchema ?? false
|
|
3189
|
+
})
|
|
3190
|
+
);
|
|
3191
|
+
return resp.batch ?? null;
|
|
3192
|
+
},
|
|
3193
|
+
async removeItems(input) {
|
|
3194
|
+
const resp = await client.removeItemsFromPublishBatch(
|
|
3195
|
+
create13(RemoveItemsFromPublishBatchRequestSchema, {
|
|
3196
|
+
batchId: input.batchId,
|
|
3197
|
+
versionIds: input.versionIds ?? [],
|
|
3198
|
+
modelIds: input.modelIds ?? [],
|
|
3199
|
+
operationIds: input.operationIds ?? [],
|
|
3200
|
+
contextDimensionIds: input.contextDimensionIds ?? [],
|
|
3201
|
+
authProviderIds: input.authProviderIds ?? [],
|
|
3202
|
+
excludeProfileSchema: input.excludeProfileSchema ?? false
|
|
3203
|
+
})
|
|
3204
|
+
);
|
|
3205
|
+
return resp.batch ?? null;
|
|
3206
|
+
}
|
|
3207
|
+
};
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
// src/lib/rpc/secrets.ts
|
|
3211
|
+
import { create as create14 } from "@bufbuild/protobuf";
|
|
3037
3212
|
import {
|
|
3038
3213
|
PutSecretRequestSchema,
|
|
3039
3214
|
GetSecretRequestSchema,
|
|
@@ -3048,7 +3223,7 @@ function createSecretsMethods(client) {
|
|
|
3048
3223
|
return {
|
|
3049
3224
|
async put(args) {
|
|
3050
3225
|
const resp = await client.putSecret(
|
|
3051
|
-
|
|
3226
|
+
create14(PutSecretRequestSchema, {
|
|
3052
3227
|
tenantId: args.tenantId,
|
|
3053
3228
|
projectId: args.projectId,
|
|
3054
3229
|
ownerKind: args.ownerKind,
|
|
@@ -3061,12 +3236,12 @@ function createSecretsMethods(client) {
|
|
|
3061
3236
|
},
|
|
3062
3237
|
async get(ref, purpose) {
|
|
3063
3238
|
return client.getSecret(
|
|
3064
|
-
|
|
3239
|
+
create14(GetSecretRequestSchema, { ref, purpose: purpose ?? "" })
|
|
3065
3240
|
);
|
|
3066
3241
|
},
|
|
3067
3242
|
async list(args) {
|
|
3068
3243
|
const resp = await client.listSecrets(
|
|
3069
|
-
|
|
3244
|
+
create14(ListSecretsRequestSchema, {
|
|
3070
3245
|
tenantId: args.tenantId,
|
|
3071
3246
|
projectId: args.projectId,
|
|
3072
3247
|
ownerKind: args.ownerKind ?? OwnerKind.UNSPECIFIED,
|
|
@@ -3078,19 +3253,19 @@ function createSecretsMethods(client) {
|
|
|
3078
3253
|
},
|
|
3079
3254
|
async rotate(ref, plaintext) {
|
|
3080
3255
|
const resp = await client.rotateSecret(
|
|
3081
|
-
|
|
3256
|
+
create14(RotateSecretRequestSchema, { ref, plaintext })
|
|
3082
3257
|
);
|
|
3083
3258
|
return resp.newRef;
|
|
3084
3259
|
},
|
|
3085
3260
|
async delete(ref) {
|
|
3086
|
-
await client.deleteSecret(
|
|
3261
|
+
await client.deleteSecret(create14(DeleteSecretRequestSchema, { ref }));
|
|
3087
3262
|
},
|
|
3088
3263
|
async restore(ref) {
|
|
3089
|
-
await client.restoreSecret(
|
|
3264
|
+
await client.restoreSecret(create14(RestoreSecretRequestSchema, { ref }));
|
|
3090
3265
|
},
|
|
3091
3266
|
async purge(args = {}) {
|
|
3092
3267
|
const resp = await client.purgeSoftDeleted(
|
|
3093
|
-
|
|
3268
|
+
create14(PurgeSoftDeletedRequestSchema, {
|
|
3094
3269
|
tenantId: args.tenantId ?? "",
|
|
3095
3270
|
projectId: args.projectId ?? ""
|
|
3096
3271
|
})
|
|
@@ -3154,7 +3329,10 @@ async function createPlatformClient(options) {
|
|
|
3154
3329
|
createRpcClient(NotificationsService2, transport)
|
|
3155
3330
|
),
|
|
3156
3331
|
cronSchedules: createCronSchedulesMethods(
|
|
3157
|
-
createRpcClient(
|
|
3332
|
+
createRpcClient(SchedulesService3, transport)
|
|
3333
|
+
),
|
|
3334
|
+
publishBatches: createPublishBatchesMethods(
|
|
3335
|
+
createRpcClient(SchedulesService3, transport)
|
|
3158
3336
|
),
|
|
3159
3337
|
apps: createAppsMethods(createRpcClient(AppsService2, transport)),
|
|
3160
3338
|
secrets: createSecretsMethods(createRpcClient(SecretsService2, transport))
|
|
@@ -3188,7 +3366,10 @@ function createPlatformClientWithHeaders(apiUrl, headers) {
|
|
|
3188
3366
|
createRpcClient(NotificationsService2, transport)
|
|
3189
3367
|
),
|
|
3190
3368
|
cronSchedules: createCronSchedulesMethods(
|
|
3191
|
-
createRpcClient(
|
|
3369
|
+
createRpcClient(SchedulesService3, transport)
|
|
3370
|
+
),
|
|
3371
|
+
publishBatches: createPublishBatchesMethods(
|
|
3372
|
+
createRpcClient(SchedulesService3, transport)
|
|
3192
3373
|
),
|
|
3193
3374
|
apps: createAppsMethods(createRpcClient(AppsService2, transport)),
|
|
3194
3375
|
secrets: createSecretsMethods(createRpcClient(SecretsService2, transport))
|
|
@@ -4890,7 +5071,15 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
4890
5071
|
const operationBaseUrl = manifest.operationBaseUrl ?? "";
|
|
4891
5072
|
const modelConflicts = [];
|
|
4892
5073
|
const mappingConflicts = [];
|
|
4893
|
-
await reconcileModels(
|
|
5074
|
+
await reconcileModels(
|
|
5075
|
+
client,
|
|
5076
|
+
configId,
|
|
5077
|
+
manifest.models ?? [],
|
|
5078
|
+
summary,
|
|
5079
|
+
options.force ?? false,
|
|
5080
|
+
options.allowLookupRebuild ?? false,
|
|
5081
|
+
modelConflicts
|
|
5082
|
+
);
|
|
4894
5083
|
await reconcileOperations(client, configId, manifest.operations ?? [], operationBaseUrl, summary);
|
|
4895
5084
|
await reconcileHooks(client, configId, manifest.hooks ?? [], summary);
|
|
4896
5085
|
await reconcileSegments(client, configId, manifest.segments ?? [], summary);
|
|
@@ -4921,7 +5110,7 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
4921
5110
|
}
|
|
4922
5111
|
return summary;
|
|
4923
5112
|
}
|
|
4924
|
-
async function reconcileModels(client, configId, models, summary, force, conflictOut) {
|
|
5113
|
+
async function reconcileModels(client, configId, models, summary, force, allowLookupRebuild, conflictOut) {
|
|
4925
5114
|
const existing = await client.models.listModels({ limit: 200 });
|
|
4926
5115
|
const allByKey = new Map(
|
|
4927
5116
|
existing.items.map((m) => [m.key, m])
|
|
@@ -4938,6 +5127,7 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
4938
5127
|
if (m.pluralName) config2.pluralName = m.pluralName;
|
|
4939
5128
|
if (m.pluralKey) config2.pluralKey = m.pluralKey;
|
|
4940
5129
|
if (m.description) config2.description = m.description;
|
|
5130
|
+
if (m.lookups !== void 0) config2.lookups = m.lookups;
|
|
4941
5131
|
const ex = allByKey.get(m.key);
|
|
4942
5132
|
if (!ex) {
|
|
4943
5133
|
plans.push({ kind: "create", model: m, config: config2 });
|
|
@@ -5006,7 +5196,8 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
5006
5196
|
name: p.name,
|
|
5007
5197
|
fields: fieldsToWrite,
|
|
5008
5198
|
config: p.config,
|
|
5009
|
-
updatePushSnapshot: true
|
|
5199
|
+
updatePushSnapshot: true,
|
|
5200
|
+
allowLookupRebuild
|
|
5010
5201
|
});
|
|
5011
5202
|
summary.models.updated++;
|
|
5012
5203
|
summary.updatedModelIds.push(p.id);
|
|
@@ -5629,6 +5820,10 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5629
5820
|
"--publish",
|
|
5630
5821
|
"Promote updated models, operations, auth providers, profile schema, and design tokens to the published channel after the push. New resources auto-publish; this flag covers updates, which are otherwise left as drafts.",
|
|
5631
5822
|
false
|
|
5823
|
+
).option(
|
|
5824
|
+
"--rebuild",
|
|
5825
|
+
"Accept lookup renames. A lookup with the same keyBy and a changed `name` override rebuilds its projection rows (old rows are dropped, new rows are re-emitted from records). Without this flag, the server rejects renames with a pointer here. Pure add / remove on lookups does not require this flag.",
|
|
5826
|
+
false
|
|
5632
5827
|
).option("--env <path>", "Path to .env file (default: .env)").action(
|
|
5633
5828
|
withErrorHandler(
|
|
5634
5829
|
globalOpts,
|
|
@@ -5689,7 +5884,8 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5689
5884
|
tenantId: resolved?.project.tenantId,
|
|
5690
5885
|
projectId: resolved?.project.id,
|
|
5691
5886
|
force: opts.force ?? false,
|
|
5692
|
-
publishDesignTokens: opts.publish ?? false
|
|
5887
|
+
publishDesignTokens: opts.publish ?? false,
|
|
5888
|
+
allowLookupRebuild: opts.rebuild ?? false
|
|
5693
5889
|
});
|
|
5694
5890
|
} catch (e) {
|
|
5695
5891
|
if (e instanceof PushConflictError) {
|
|
@@ -7501,8 +7697,61 @@ function registerApiKeysCommands(program2, globalOpts) {
|
|
|
7501
7697
|
);
|
|
7502
7698
|
}
|
|
7503
7699
|
|
|
7504
|
-
// src/commands/auth
|
|
7700
|
+
// src/commands/auth.ts
|
|
7505
7701
|
import chalk11 from "chalk";
|
|
7702
|
+
import { CustomerAuthConfigSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7703
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
7704
|
+
function registerAuthCommands(program2, globalOpts) {
|
|
7705
|
+
const auth = program2.command("auth").description("Inspect customer auth configuration and verify customer tokens");
|
|
7706
|
+
auth.command("config").description("Print the project's customer-auth configuration").action(
|
|
7707
|
+
withErrorHandler(globalOpts, async () => {
|
|
7708
|
+
const opts = globalOpts();
|
|
7709
|
+
const client = await createPlatformClient(opts);
|
|
7710
|
+
const config2 = await client.identity.getCustomerAuthConfig();
|
|
7711
|
+
if (!config2) {
|
|
7712
|
+
throw new Error("No customer auth configuration found for this project.");
|
|
7713
|
+
}
|
|
7714
|
+
formatOutputProto(CustomerAuthConfigSchema, config2, opts);
|
|
7715
|
+
})
|
|
7716
|
+
);
|
|
7717
|
+
auth.command("verify-token <token>").description("Verify a customer JWT and print its claims").action(
|
|
7718
|
+
withErrorHandler(globalOpts, async (token) => {
|
|
7719
|
+
const opts = globalOpts();
|
|
7720
|
+
const client = await createPlatformClient(opts);
|
|
7721
|
+
const resp = await client.identity.verifyCustomerToken(token);
|
|
7722
|
+
const expiresAtIso = resp.expiresAt ? timestampDate(resp.expiresAt).toISOString() : null;
|
|
7723
|
+
if (opts.json || opts.jsonl) {
|
|
7724
|
+
formatOutput(
|
|
7725
|
+
{
|
|
7726
|
+
valid: resp.valid,
|
|
7727
|
+
customerId: resp.customerId ?? null,
|
|
7728
|
+
email: resp.email ?? null,
|
|
7729
|
+
roles: resp.roles ?? [],
|
|
7730
|
+
expiresAt: expiresAtIso,
|
|
7731
|
+
error: resp.error ?? null
|
|
7732
|
+
},
|
|
7733
|
+
opts
|
|
7734
|
+
);
|
|
7735
|
+
return;
|
|
7736
|
+
}
|
|
7737
|
+
if (!resp.valid) {
|
|
7738
|
+
throw new Error(
|
|
7739
|
+
`Token invalid: ${resp.error ?? "no further detail"}`
|
|
7740
|
+
);
|
|
7741
|
+
}
|
|
7742
|
+
console.log(chalk11.green("\u25CF Valid"));
|
|
7743
|
+
if (resp.customerId)
|
|
7744
|
+
console.log(` Customer: ${chalk11.cyan(resp.customerId)}`);
|
|
7745
|
+
if (resp.email) console.log(` Email: ${resp.email}`);
|
|
7746
|
+
if (resp.roles && resp.roles.length > 0)
|
|
7747
|
+
console.log(` Roles: ${resp.roles.join(", ")}`);
|
|
7748
|
+
if (expiresAtIso) console.log(` Expires: ${expiresAtIso}`);
|
|
7749
|
+
})
|
|
7750
|
+
);
|
|
7751
|
+
}
|
|
7752
|
+
|
|
7753
|
+
// src/commands/auth-providers.ts
|
|
7754
|
+
import chalk12 from "chalk";
|
|
7506
7755
|
import { AuthProviderSchema } from "@eide/foir-proto-ts/identity/v1/identity_pb";
|
|
7507
7756
|
var VALID_TYPES = [
|
|
7508
7757
|
"OAUTH2",
|
|
@@ -7556,7 +7805,7 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7556
7805
|
formatOutputProto(AuthProviderSchema, provider, opts);
|
|
7557
7806
|
} else {
|
|
7558
7807
|
const p = provider;
|
|
7559
|
-
console.log(
|
|
7808
|
+
console.log(chalk12.bold(`${p.name}`) + chalk12.gray(` (${p.key})`));
|
|
7560
7809
|
console.log(` Type: ${p.type}`);
|
|
7561
7810
|
console.log(` Enabled: ${p.enabled ? "yes" : "no"}`);
|
|
7562
7811
|
console.log(` Default: ${p.isDefault ? "yes" : "no"}`);
|
|
@@ -7570,13 +7819,13 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7570
7819
|
if (p.configDisplay) {
|
|
7571
7820
|
console.log(` Config:`);
|
|
7572
7821
|
console.log(
|
|
7573
|
-
|
|
7822
|
+
chalk12.gray(
|
|
7574
7823
|
JSON.stringify(p.configDisplay, null, 2).replace(/^/gm, " ")
|
|
7575
7824
|
)
|
|
7576
7825
|
);
|
|
7577
7826
|
}
|
|
7578
|
-
console.log(
|
|
7579
|
-
console.log(
|
|
7827
|
+
console.log(chalk12.gray(` Created: ${p.createdAt}`));
|
|
7828
|
+
console.log(chalk12.gray(` Updated: ${p.updatedAt}`));
|
|
7580
7829
|
}
|
|
7581
7830
|
})
|
|
7582
7831
|
);
|
|
@@ -7686,6 +7935,637 @@ function registerAuthProvidersCommands(program2, globalOpts) {
|
|
|
7686
7935
|
);
|
|
7687
7936
|
}
|
|
7688
7937
|
|
|
7938
|
+
// src/commands/embeddings.ts
|
|
7939
|
+
import chalk13 from "chalk";
|
|
7940
|
+
function registerEmbeddingsCommands(program2, globalOpts) {
|
|
7941
|
+
const embeddings = program2.command("embeddings").description("Manage vector embeddings for semantic search");
|
|
7942
|
+
embeddings.command("write").description("Write an embedding vector for a record").option("-d, --data <json>", "Embedding input as JSON string").option("--file <path>", "Embedding input from JSON file").action(
|
|
7943
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
7944
|
+
const opts = globalOpts();
|
|
7945
|
+
const input = await parseInputData({
|
|
7946
|
+
data: cmdOpts.data,
|
|
7947
|
+
file: cmdOpts.file
|
|
7948
|
+
});
|
|
7949
|
+
if (!input?.recordId) {
|
|
7950
|
+
throw new Error("Embedding input missing required field: recordId");
|
|
7951
|
+
}
|
|
7952
|
+
if (!Array.isArray(input.vector) || input.vector.length === 0) {
|
|
7953
|
+
throw new Error(
|
|
7954
|
+
"Embedding input missing required field: vector (non-empty number[])"
|
|
7955
|
+
);
|
|
7956
|
+
}
|
|
7957
|
+
const dimensions = input.dimensions ?? input.vector.length;
|
|
7958
|
+
const client = await createPlatformClient(opts);
|
|
7959
|
+
const ok = await client.records.writeEmbeddings({
|
|
7960
|
+
recordId: input.recordId,
|
|
7961
|
+
vector: input.vector,
|
|
7962
|
+
dimensions,
|
|
7963
|
+
provider: input.provider,
|
|
7964
|
+
modelName: input.modelName
|
|
7965
|
+
});
|
|
7966
|
+
if (opts.json || opts.jsonl) {
|
|
7967
|
+
formatOutput({ written: ok, recordId: input.recordId, dimensions }, opts);
|
|
7968
|
+
} else if (ok) {
|
|
7969
|
+
success(
|
|
7970
|
+
`Wrote ${dimensions}-dim embedding for ${input.recordId}`
|
|
7971
|
+
);
|
|
7972
|
+
} else {
|
|
7973
|
+
throw new Error(`Write failed for ${input.recordId}`);
|
|
7974
|
+
}
|
|
7975
|
+
})
|
|
7976
|
+
);
|
|
7977
|
+
embeddings.command("delete <recordId>").description("Delete the embedding for a record").option("--confirm", "Skip confirmation prompt").action(
|
|
7978
|
+
withErrorHandler(
|
|
7979
|
+
globalOpts,
|
|
7980
|
+
async (recordId, cmdOpts) => {
|
|
7981
|
+
const opts = globalOpts();
|
|
7982
|
+
const confirmed = await confirmAction(
|
|
7983
|
+
`Delete embedding for ${recordId}?`,
|
|
7984
|
+
{ confirm: !!cmdOpts.confirm }
|
|
7985
|
+
);
|
|
7986
|
+
if (!confirmed) {
|
|
7987
|
+
console.log("Aborted.");
|
|
7988
|
+
return;
|
|
7989
|
+
}
|
|
7990
|
+
const client = await createPlatformClient(opts);
|
|
7991
|
+
const ok = await client.records.deleteEmbeddings(recordId);
|
|
7992
|
+
if (opts.json || opts.jsonl) {
|
|
7993
|
+
formatOutput({ deleted: ok, recordId }, opts);
|
|
7994
|
+
} else {
|
|
7995
|
+
success(`Deleted embedding for ${recordId}`);
|
|
7996
|
+
}
|
|
7997
|
+
}
|
|
7998
|
+
)
|
|
7999
|
+
);
|
|
8000
|
+
embeddings.command("search").description("Search by vector similarity").requiredOption(
|
|
8001
|
+
"-d, --data <json>",
|
|
8002
|
+
'Search input as JSON: {"queryVector":[\u2026],"modelKey":"\u2026","limit":10}'
|
|
8003
|
+
).action(
|
|
8004
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8005
|
+
const opts = globalOpts();
|
|
8006
|
+
const input = await parseInputData({
|
|
8007
|
+
data: cmdOpts.data
|
|
8008
|
+
});
|
|
8009
|
+
if (!Array.isArray(input.queryVector) || input.queryVector.length === 0) {
|
|
8010
|
+
throw new Error(
|
|
8011
|
+
"Search input missing required field: queryVector (non-empty number[])"
|
|
8012
|
+
);
|
|
8013
|
+
}
|
|
8014
|
+
const client = await createPlatformClient(opts);
|
|
8015
|
+
const results = await client.records.searchEmbeddings({
|
|
8016
|
+
queryVector: input.queryVector,
|
|
8017
|
+
modelKey: input.modelKey,
|
|
8018
|
+
limit: input.limit
|
|
8019
|
+
});
|
|
8020
|
+
if (opts.json || opts.jsonl) {
|
|
8021
|
+
formatOutput(results, opts);
|
|
8022
|
+
return;
|
|
8023
|
+
}
|
|
8024
|
+
if (results.length === 0) {
|
|
8025
|
+
console.log(chalk13.dim("No matches."));
|
|
8026
|
+
return;
|
|
8027
|
+
}
|
|
8028
|
+
for (const r of results) {
|
|
8029
|
+
const score = typeof r.similarity === "number" ? r.similarity.toFixed(4) : "\u2014";
|
|
8030
|
+
console.log(
|
|
8031
|
+
` ${chalk13.cyan(r.id)} ${chalk13.dim(r.modelKey ?? "")} ${chalk13.gray(`sim=${score}`)}`
|
|
8032
|
+
);
|
|
8033
|
+
}
|
|
8034
|
+
})
|
|
8035
|
+
);
|
|
8036
|
+
embeddings.command("list <recordId>").description("List embeddings stored for a record").action(
|
|
8037
|
+
withErrorHandler(globalOpts, async (recordId) => {
|
|
8038
|
+
const opts = globalOpts();
|
|
8039
|
+
const client = await createPlatformClient(opts);
|
|
8040
|
+
const items = await client.records.getRecordEmbeddings(recordId);
|
|
8041
|
+
formatOutput(items, opts);
|
|
8042
|
+
})
|
|
8043
|
+
);
|
|
8044
|
+
embeddings.command("stats [modelKey]").description("Embedding statistics, optionally scoped to a model").action(
|
|
8045
|
+
withErrorHandler(globalOpts, async (modelKey) => {
|
|
8046
|
+
const opts = globalOpts();
|
|
8047
|
+
const client = await createPlatformClient(opts);
|
|
8048
|
+
const stats = await client.records.getEmbeddingStats(modelKey);
|
|
8049
|
+
if (opts.json || opts.jsonl) {
|
|
8050
|
+
formatOutput(stats, opts);
|
|
8051
|
+
return;
|
|
8052
|
+
}
|
|
8053
|
+
if (stats.length === 0) {
|
|
8054
|
+
console.log(chalk13.dim("No embeddings yet."));
|
|
8055
|
+
return;
|
|
8056
|
+
}
|
|
8057
|
+
for (const s of stats) {
|
|
8058
|
+
console.log(
|
|
8059
|
+
` ${chalk13.cyan(s.modelKey)} ${chalk13.dim(`embedded=${s.embeddedRecords}/${s.totalRecords} pending=${s.pendingRecords}`)}`
|
|
8060
|
+
);
|
|
8061
|
+
}
|
|
8062
|
+
})
|
|
8063
|
+
);
|
|
8064
|
+
embeddings.command("similar <recordId>").description("Find records similar to the given record").option("--model-key <key>", "Limit matches to a specific model").option("--limit <n>", "Maximum results (default: 10)").action(
|
|
8065
|
+
withErrorHandler(
|
|
8066
|
+
globalOpts,
|
|
8067
|
+
async (recordId, cmdOpts) => {
|
|
8068
|
+
const opts = globalOpts();
|
|
8069
|
+
const client = await createPlatformClient(opts);
|
|
8070
|
+
const results = await client.records.findSimilarRecords({
|
|
8071
|
+
recordId,
|
|
8072
|
+
modelKey: cmdOpts.modelKey,
|
|
8073
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0
|
|
8074
|
+
});
|
|
8075
|
+
if (opts.json || opts.jsonl) {
|
|
8076
|
+
formatOutput(results, opts);
|
|
8077
|
+
return;
|
|
8078
|
+
}
|
|
8079
|
+
if (results.length === 0) {
|
|
8080
|
+
console.log(chalk13.dim("No similar records."));
|
|
8081
|
+
return;
|
|
8082
|
+
}
|
|
8083
|
+
for (const r of results) {
|
|
8084
|
+
const score = typeof r.similarity === "number" ? r.similarity.toFixed(4) : "\u2014";
|
|
8085
|
+
console.log(
|
|
8086
|
+
` ${chalk13.cyan(r.id)} ${chalk13.dim(r.modelKey ?? "")} ${chalk13.gray(`sim=${score}`)}`
|
|
8087
|
+
);
|
|
8088
|
+
}
|
|
8089
|
+
}
|
|
8090
|
+
)
|
|
8091
|
+
);
|
|
8092
|
+
}
|
|
8093
|
+
|
|
8094
|
+
// src/commands/hooks.ts
|
|
8095
|
+
import {
|
|
8096
|
+
HookSchema,
|
|
8097
|
+
HookDeliverySchema
|
|
8098
|
+
} from "@eide/foir-proto-ts/hooks/v1/hooks_pb";
|
|
8099
|
+
function registerHooksCommands(program2, globalOpts) {
|
|
8100
|
+
const hooks = program2.command("hooks").description("Manage lifecycle hooks (event-driven webhooks)");
|
|
8101
|
+
hooks.command("list").description("List hooks").option("--event <event>", "Filter by event name").option("--active", "Show only active hooks").option("--inactive", "Show only inactive hooks").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8102
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8103
|
+
const opts = globalOpts();
|
|
8104
|
+
const client = await createPlatformClient(opts);
|
|
8105
|
+
let isActive;
|
|
8106
|
+
if (cmdOpts.active) isActive = true;
|
|
8107
|
+
else if (cmdOpts.inactive) isActive = false;
|
|
8108
|
+
const resp = await client.hooks.listHooks({
|
|
8109
|
+
event: cmdOpts.event,
|
|
8110
|
+
isActive,
|
|
8111
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8112
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8113
|
+
});
|
|
8114
|
+
formatListProto(HookSchema, resp.hooks ?? [], opts, {
|
|
8115
|
+
columns: [
|
|
8116
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8117
|
+
{ key: "key", header: "Key", width: 24 },
|
|
8118
|
+
{ key: "name", header: "Name", width: 24 },
|
|
8119
|
+
{ key: "event", header: "Event", width: 22 },
|
|
8120
|
+
{ key: "targetType", header: "Target", width: 14 },
|
|
8121
|
+
{
|
|
8122
|
+
key: "isActive",
|
|
8123
|
+
header: "Active",
|
|
8124
|
+
width: 7,
|
|
8125
|
+
format: (v) => v ? "yes" : "no"
|
|
8126
|
+
}
|
|
8127
|
+
]
|
|
8128
|
+
});
|
|
8129
|
+
})
|
|
8130
|
+
);
|
|
8131
|
+
hooks.command("get <keyOrId>").description("Get a hook by key or ID").action(
|
|
8132
|
+
withErrorHandler(globalOpts, async (keyOrId) => {
|
|
8133
|
+
const opts = globalOpts();
|
|
8134
|
+
const client = await createPlatformClient(opts);
|
|
8135
|
+
const hook = keyOrId.includes("-") || keyOrId.length > 20 ? await client.hooks.getHook(keyOrId) : await client.hooks.getHookByKey(keyOrId);
|
|
8136
|
+
if (!hook) {
|
|
8137
|
+
throw new Error(`Hook not found: ${keyOrId}`);
|
|
8138
|
+
}
|
|
8139
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8140
|
+
})
|
|
8141
|
+
);
|
|
8142
|
+
hooks.command("create").description("Create a hook").option("-d, --data <json>", "Hook definition as JSON string").option("--file <path>", "Hook definition from JSON file").action(
|
|
8143
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8144
|
+
const opts = globalOpts();
|
|
8145
|
+
const input = await parseInputData({
|
|
8146
|
+
data: cmdOpts.data,
|
|
8147
|
+
file: cmdOpts.file
|
|
8148
|
+
});
|
|
8149
|
+
for (const required of ["key", "name", "event", "targetType"]) {
|
|
8150
|
+
if (!input[required]) {
|
|
8151
|
+
throw new Error(`Hook input missing required field: ${required}`);
|
|
8152
|
+
}
|
|
8153
|
+
}
|
|
8154
|
+
const client = await createPlatformClient(opts);
|
|
8155
|
+
const hook = await client.hooks.createHook({
|
|
8156
|
+
key: input.key,
|
|
8157
|
+
name: input.name,
|
|
8158
|
+
event: input.event,
|
|
8159
|
+
targetType: input.targetType,
|
|
8160
|
+
description: input.description,
|
|
8161
|
+
operationKey: input.operationKey,
|
|
8162
|
+
notificationConfig: input.notificationConfig,
|
|
8163
|
+
filter: input.filter,
|
|
8164
|
+
configId: input.configId
|
|
8165
|
+
});
|
|
8166
|
+
if (opts.json || opts.jsonl) {
|
|
8167
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8168
|
+
} else {
|
|
8169
|
+
success(`Created hook ${hook?.key} (${hook?.id})`);
|
|
8170
|
+
}
|
|
8171
|
+
})
|
|
8172
|
+
);
|
|
8173
|
+
hooks.command("update <id>").description("Update a hook").option("-d, --data <json>", "Patch fields as JSON string").option("--file <path>", "Patch fields from JSON file").option("--active", "Activate the hook").option("--no-active", "Deactivate the hook").action(
|
|
8174
|
+
withErrorHandler(
|
|
8175
|
+
globalOpts,
|
|
8176
|
+
async (id, cmdOpts) => {
|
|
8177
|
+
const opts = globalOpts();
|
|
8178
|
+
const patch = cmdOpts.data || cmdOpts.file ? await parseInputData({
|
|
8179
|
+
data: cmdOpts.data,
|
|
8180
|
+
file: cmdOpts.file
|
|
8181
|
+
}) : {};
|
|
8182
|
+
const update = {
|
|
8183
|
+
id,
|
|
8184
|
+
name: patch.name,
|
|
8185
|
+
description: patch.description,
|
|
8186
|
+
operationKey: patch.operationKey,
|
|
8187
|
+
notificationConfig: patch.notificationConfig,
|
|
8188
|
+
filter: patch.filter
|
|
8189
|
+
};
|
|
8190
|
+
if (cmdOpts.active !== void 0) {
|
|
8191
|
+
update.isActive = !!cmdOpts.active;
|
|
8192
|
+
}
|
|
8193
|
+
const client = await createPlatformClient(opts);
|
|
8194
|
+
const hook = await client.hooks.updateHook(update);
|
|
8195
|
+
if (opts.json || opts.jsonl) {
|
|
8196
|
+
formatOutputProto(HookSchema, hook, opts);
|
|
8197
|
+
} else {
|
|
8198
|
+
success(`Updated hook ${hook?.key} (${hook?.id})`);
|
|
8199
|
+
}
|
|
8200
|
+
}
|
|
8201
|
+
)
|
|
8202
|
+
);
|
|
8203
|
+
hooks.command("delete <id>").description("Delete a hook").option("--confirm", "Skip confirmation prompt").action(
|
|
8204
|
+
withErrorHandler(
|
|
8205
|
+
globalOpts,
|
|
8206
|
+
async (id, cmdOpts) => {
|
|
8207
|
+
const opts = globalOpts();
|
|
8208
|
+
const confirmed = await confirmAction(
|
|
8209
|
+
`Delete hook ${id}? This also removes its delivery history.`,
|
|
8210
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8211
|
+
);
|
|
8212
|
+
if (!confirmed) {
|
|
8213
|
+
console.log("Aborted.");
|
|
8214
|
+
return;
|
|
8215
|
+
}
|
|
8216
|
+
const client = await createPlatformClient(opts);
|
|
8217
|
+
const deleted = await client.hooks.deleteHook(id);
|
|
8218
|
+
if (opts.json || opts.jsonl) {
|
|
8219
|
+
formatOutput({ deleted, id }, opts);
|
|
8220
|
+
} else {
|
|
8221
|
+
success(`Deleted hook ${id}`);
|
|
8222
|
+
}
|
|
8223
|
+
}
|
|
8224
|
+
)
|
|
8225
|
+
);
|
|
8226
|
+
hooks.command("deliveries <hookId>").description("List recent deliveries for a hook").option("--status <status>", "Filter by status (success / failed / pending)").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8227
|
+
withErrorHandler(
|
|
8228
|
+
globalOpts,
|
|
8229
|
+
async (hookId, cmdOpts) => {
|
|
8230
|
+
const opts = globalOpts();
|
|
8231
|
+
const client = await createPlatformClient(opts);
|
|
8232
|
+
const resp = await client.hooks.listHookDeliveries({
|
|
8233
|
+
hookId,
|
|
8234
|
+
status: cmdOpts.status,
|
|
8235
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8236
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8237
|
+
});
|
|
8238
|
+
formatListProto(HookDeliverySchema, resp.deliveries ?? [], opts, {
|
|
8239
|
+
columns: [
|
|
8240
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8241
|
+
{ key: "event", header: "Event", width: 22 },
|
|
8242
|
+
{ key: "status", header: "Status", width: 10 },
|
|
8243
|
+
{ key: "attempts", header: "Tries", width: 6 },
|
|
8244
|
+
{
|
|
8245
|
+
key: "durationMs",
|
|
8246
|
+
header: "Duration",
|
|
8247
|
+
width: 10,
|
|
8248
|
+
format: (v) => typeof v === "number" ? `${v}ms` : "\u2014"
|
|
8249
|
+
},
|
|
8250
|
+
{ key: "deliveredAt", header: "Delivered", width: 24 }
|
|
8251
|
+
]
|
|
8252
|
+
});
|
|
8253
|
+
}
|
|
8254
|
+
)
|
|
8255
|
+
);
|
|
8256
|
+
hooks.command("retry-delivery <deliveryId>").description("Retry a failed delivery").action(
|
|
8257
|
+
withErrorHandler(globalOpts, async (deliveryId) => {
|
|
8258
|
+
const opts = globalOpts();
|
|
8259
|
+
const client = await createPlatformClient(opts);
|
|
8260
|
+
const ok = await client.hooks.retryHookDelivery(deliveryId);
|
|
8261
|
+
if (opts.json || opts.jsonl) {
|
|
8262
|
+
formatOutput({ retried: ok, deliveryId }, opts);
|
|
8263
|
+
} else if (ok) {
|
|
8264
|
+
success(`Re-queued delivery ${deliveryId}`);
|
|
8265
|
+
} else {
|
|
8266
|
+
throw new Error(`Retry failed for delivery ${deliveryId}`);
|
|
8267
|
+
}
|
|
8268
|
+
})
|
|
8269
|
+
);
|
|
8270
|
+
hooks.command("test <hookId>").description("Send a test delivery against the hook").option("-d, --data <json>", "Test payload as JSON string").option("--file <path>", "Test payload from JSON file").action(
|
|
8271
|
+
withErrorHandler(
|
|
8272
|
+
globalOpts,
|
|
8273
|
+
async (hookId, cmdOpts) => {
|
|
8274
|
+
const opts = globalOpts();
|
|
8275
|
+
const testPayload = cmdOpts.data || cmdOpts.file ? await parseInputData({
|
|
8276
|
+
data: cmdOpts.data,
|
|
8277
|
+
file: cmdOpts.file
|
|
8278
|
+
}) : void 0;
|
|
8279
|
+
const client = await createPlatformClient(opts);
|
|
8280
|
+
const result = await client.hooks.testHook({ hookId, testPayload });
|
|
8281
|
+
if (opts.json || opts.jsonl) {
|
|
8282
|
+
formatOutput(result, opts);
|
|
8283
|
+
} else if (result.success) {
|
|
8284
|
+
success(`Test delivery succeeded for hook ${hookId}`);
|
|
8285
|
+
} else {
|
|
8286
|
+
throw new Error(
|
|
8287
|
+
`Test delivery failed: ${result.error ?? "unknown error"}`
|
|
8288
|
+
);
|
|
8289
|
+
}
|
|
8290
|
+
}
|
|
8291
|
+
)
|
|
8292
|
+
);
|
|
8293
|
+
}
|
|
8294
|
+
|
|
8295
|
+
// src/commands/rollouts.ts
|
|
8296
|
+
import chalk14 from "chalk";
|
|
8297
|
+
import { PublishBatchSchema } from "@eide/foir-proto-ts/schedules/v1/schedules_pb";
|
|
8298
|
+
function parseScheduledAt(value) {
|
|
8299
|
+
const date = new Date(value);
|
|
8300
|
+
if (Number.isNaN(date.getTime())) {
|
|
8301
|
+
throw new Error(
|
|
8302
|
+
`Invalid scheduledAt "${value}". Expected an ISO-8601 timestamp.`
|
|
8303
|
+
);
|
|
8304
|
+
}
|
|
8305
|
+
return date;
|
|
8306
|
+
}
|
|
8307
|
+
function registerRolloutsCommands(program2, globalOpts) {
|
|
8308
|
+
const rollouts = program2.command("rollouts").description("Manage bulk scheduled publishing rollouts");
|
|
8309
|
+
rollouts.command("list").description("List rollouts").option("--status <status>", "Filter by status").option("--limit <n>", "Maximum results (default: 50)").option("--offset <n>", "Pagination offset").action(
|
|
8310
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8311
|
+
const opts = globalOpts();
|
|
8312
|
+
const client = await createPlatformClient(opts);
|
|
8313
|
+
const { batches } = await client.publishBatches.listPublishBatches({
|
|
8314
|
+
status: cmdOpts.status,
|
|
8315
|
+
limit: cmdOpts.limit ? parseInt(String(cmdOpts.limit), 10) : void 0,
|
|
8316
|
+
offset: cmdOpts.offset ? parseInt(String(cmdOpts.offset), 10) : void 0
|
|
8317
|
+
});
|
|
8318
|
+
formatListProto(PublishBatchSchema, batches, opts, {
|
|
8319
|
+
columns: [
|
|
8320
|
+
{ key: "id", header: "ID", width: 28 },
|
|
8321
|
+
{ key: "name", header: "Name", width: 28 },
|
|
8322
|
+
{ key: "status", header: "Status", width: 12 },
|
|
8323
|
+
{ key: "itemCount", header: "Items", width: 6 },
|
|
8324
|
+
{ key: "completedCount", header: "Done", width: 6 },
|
|
8325
|
+
{ key: "failedCount", header: "Failed", width: 7 },
|
|
8326
|
+
{ key: "scheduledAt", header: "Scheduled", width: 24 }
|
|
8327
|
+
]
|
|
8328
|
+
});
|
|
8329
|
+
})
|
|
8330
|
+
);
|
|
8331
|
+
rollouts.command("get <id>").description("Get a rollout (with its items)").action(
|
|
8332
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8333
|
+
const opts = globalOpts();
|
|
8334
|
+
const client = await createPlatformClient(opts);
|
|
8335
|
+
const { batch, items } = await client.publishBatches.getPublishBatch(id);
|
|
8336
|
+
if (!batch) throw new Error(`Rollout not found: ${id}`);
|
|
8337
|
+
if (opts.json || opts.jsonl) {
|
|
8338
|
+
formatOutput({ rollout: batch, items }, opts);
|
|
8339
|
+
return;
|
|
8340
|
+
}
|
|
8341
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8342
|
+
if (items.length > 0) {
|
|
8343
|
+
console.log();
|
|
8344
|
+
console.log(chalk14.bold(`Items (${items.length}):`));
|
|
8345
|
+
for (const it of items) {
|
|
8346
|
+
console.log(
|
|
8347
|
+
` ${chalk14.cyan(it.id)} ${chalk14.dim(it.targetKind)} ${chalk14.gray(it.status ?? "")}`
|
|
8348
|
+
);
|
|
8349
|
+
}
|
|
8350
|
+
}
|
|
8351
|
+
})
|
|
8352
|
+
);
|
|
8353
|
+
rollouts.command("create").description("Create a rollout").option("-d, --data <json>", "Rollout definition as JSON string").option("--file <path>", "Rollout definition from JSON file").action(
|
|
8354
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
8355
|
+
const opts = globalOpts();
|
|
8356
|
+
const input = await parseInputData({
|
|
8357
|
+
data: cmdOpts.data,
|
|
8358
|
+
file: cmdOpts.file
|
|
8359
|
+
});
|
|
8360
|
+
if (!input?.name) {
|
|
8361
|
+
throw new Error("Rollout input missing required field: name");
|
|
8362
|
+
}
|
|
8363
|
+
if (!input.scheduledAt) {
|
|
8364
|
+
throw new Error("Rollout input missing required field: scheduledAt");
|
|
8365
|
+
}
|
|
8366
|
+
const scheduledAt = parseScheduledAt(input.scheduledAt);
|
|
8367
|
+
const client = await createPlatformClient(opts);
|
|
8368
|
+
const batch = await client.publishBatches.createPublishBatch({
|
|
8369
|
+
name: input.name,
|
|
8370
|
+
description: input.description,
|
|
8371
|
+
scheduledAt,
|
|
8372
|
+
versionIds: input.versionIds,
|
|
8373
|
+
modelIds: input.modelIds,
|
|
8374
|
+
operationIds: input.operationIds,
|
|
8375
|
+
contextDimensionIds: input.contextDimensionIds,
|
|
8376
|
+
authProviderIds: input.authProviderIds,
|
|
8377
|
+
includeProfileSchema: input.includeProfileSchema
|
|
8378
|
+
});
|
|
8379
|
+
if (opts.json || opts.jsonl) {
|
|
8380
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8381
|
+
} else {
|
|
8382
|
+
success(`Created rollout ${batch?.name} (${batch?.id})`);
|
|
8383
|
+
}
|
|
8384
|
+
})
|
|
8385
|
+
);
|
|
8386
|
+
rollouts.command("update <id>").description("Update a rollout (name, description, scheduledAt)").option("-d, --data <json>", "Patch fields as JSON string").option("--file <path>", "Patch fields from JSON file").action(
|
|
8387
|
+
withErrorHandler(
|
|
8388
|
+
globalOpts,
|
|
8389
|
+
async (id, cmdOpts) => {
|
|
8390
|
+
const opts = globalOpts();
|
|
8391
|
+
const patch = await parseInputData({
|
|
8392
|
+
data: cmdOpts.data,
|
|
8393
|
+
file: cmdOpts.file
|
|
8394
|
+
});
|
|
8395
|
+
const client = await createPlatformClient(opts);
|
|
8396
|
+
const batch = await client.publishBatches.updatePublishBatch({
|
|
8397
|
+
id,
|
|
8398
|
+
name: patch.name,
|
|
8399
|
+
description: patch.description,
|
|
8400
|
+
scheduledAt: patch.scheduledAt ? parseScheduledAt(patch.scheduledAt) : void 0
|
|
8401
|
+
});
|
|
8402
|
+
if (opts.json || opts.jsonl) {
|
|
8403
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8404
|
+
} else {
|
|
8405
|
+
success(`Updated rollout ${batch?.name} (${batch?.id})`);
|
|
8406
|
+
}
|
|
8407
|
+
}
|
|
8408
|
+
)
|
|
8409
|
+
);
|
|
8410
|
+
rollouts.command("delete <id>").description("Delete a rollout before it runs").option("--confirm", "Skip confirmation prompt").action(
|
|
8411
|
+
withErrorHandler(
|
|
8412
|
+
globalOpts,
|
|
8413
|
+
async (id, cmdOpts) => {
|
|
8414
|
+
const opts = globalOpts();
|
|
8415
|
+
const confirmed = await confirmAction(
|
|
8416
|
+
`Delete rollout ${id}? This cannot be undone.`,
|
|
8417
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8418
|
+
);
|
|
8419
|
+
if (!confirmed) {
|
|
8420
|
+
console.log("Aborted.");
|
|
8421
|
+
return;
|
|
8422
|
+
}
|
|
8423
|
+
const client = await createPlatformClient(opts);
|
|
8424
|
+
const ok = await client.publishBatches.deletePublishBatch(id);
|
|
8425
|
+
if (opts.json || opts.jsonl) {
|
|
8426
|
+
formatOutput({ deleted: ok, id }, opts);
|
|
8427
|
+
} else {
|
|
8428
|
+
success(`Deleted rollout ${id}`);
|
|
8429
|
+
}
|
|
8430
|
+
}
|
|
8431
|
+
)
|
|
8432
|
+
);
|
|
8433
|
+
rollouts.command("trigger <id>").description("Trigger a rollout immediately (ignore its scheduled time)").action(
|
|
8434
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8435
|
+
const opts = globalOpts();
|
|
8436
|
+
const client = await createPlatformClient(opts);
|
|
8437
|
+
const batch = await client.publishBatches.triggerPublishBatch(id);
|
|
8438
|
+
if (opts.json || opts.jsonl) {
|
|
8439
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8440
|
+
} else {
|
|
8441
|
+
success(`Triggered rollout ${batch?.name} (${batch?.id})`);
|
|
8442
|
+
}
|
|
8443
|
+
})
|
|
8444
|
+
);
|
|
8445
|
+
rollouts.command("pause <id>").description("Pause an in-flight rollout").action(
|
|
8446
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8447
|
+
const opts = globalOpts();
|
|
8448
|
+
const client = await createPlatformClient(opts);
|
|
8449
|
+
const batch = await client.publishBatches.pausePublishBatch(id);
|
|
8450
|
+
if (opts.json || opts.jsonl) {
|
|
8451
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8452
|
+
} else {
|
|
8453
|
+
success(`Paused rollout ${batch?.id}`);
|
|
8454
|
+
}
|
|
8455
|
+
})
|
|
8456
|
+
);
|
|
8457
|
+
rollouts.command("resume <id>").description("Resume a paused rollout").action(
|
|
8458
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8459
|
+
const opts = globalOpts();
|
|
8460
|
+
const client = await createPlatformClient(opts);
|
|
8461
|
+
const batch = await client.publishBatches.resumePublishBatch(id);
|
|
8462
|
+
if (opts.json || opts.jsonl) {
|
|
8463
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8464
|
+
} else {
|
|
8465
|
+
success(`Resumed rollout ${batch?.id}`);
|
|
8466
|
+
}
|
|
8467
|
+
})
|
|
8468
|
+
);
|
|
8469
|
+
rollouts.command("retry <id>").description("Retry failed items in a rollout").action(
|
|
8470
|
+
withErrorHandler(globalOpts, async (id) => {
|
|
8471
|
+
const opts = globalOpts();
|
|
8472
|
+
const client = await createPlatformClient(opts);
|
|
8473
|
+
const batch = await client.publishBatches.retryFailedItems(id);
|
|
8474
|
+
if (opts.json || opts.jsonl) {
|
|
8475
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8476
|
+
} else {
|
|
8477
|
+
success(`Re-queued failed items for rollout ${batch?.id}`);
|
|
8478
|
+
}
|
|
8479
|
+
})
|
|
8480
|
+
);
|
|
8481
|
+
rollouts.command("rollback <id>").description(
|
|
8482
|
+
"Roll back a completed rollout (use --preview to dry-run first)"
|
|
8483
|
+
).option("--preview", "Preview the rollback without executing").option("--confirm", "Skip confirmation prompt").action(
|
|
8484
|
+
withErrorHandler(
|
|
8485
|
+
globalOpts,
|
|
8486
|
+
async (id, cmdOpts) => {
|
|
8487
|
+
const opts = globalOpts();
|
|
8488
|
+
const client = await createPlatformClient(opts);
|
|
8489
|
+
if (cmdOpts.preview) {
|
|
8490
|
+
const preview = await client.publishBatches.previewRollback(id);
|
|
8491
|
+
formatOutput(preview, opts);
|
|
8492
|
+
return;
|
|
8493
|
+
}
|
|
8494
|
+
const confirmed = await confirmAction(
|
|
8495
|
+
`Roll back rollout ${id}? This creates a new inverse rollout that reverts published changes.`,
|
|
8496
|
+
{ confirm: !!cmdOpts.confirm }
|
|
8497
|
+
);
|
|
8498
|
+
if (!confirmed) {
|
|
8499
|
+
console.log("Aborted.");
|
|
8500
|
+
return;
|
|
8501
|
+
}
|
|
8502
|
+
const rollback = await client.publishBatches.rollbackPublishBatch(id);
|
|
8503
|
+
if (opts.json || opts.jsonl) {
|
|
8504
|
+
formatOutputProto(PublishBatchSchema, rollback, opts);
|
|
8505
|
+
} else {
|
|
8506
|
+
success(
|
|
8507
|
+
`Rollback rollout ${rollback?.id} created for ${id}`
|
|
8508
|
+
);
|
|
8509
|
+
}
|
|
8510
|
+
}
|
|
8511
|
+
)
|
|
8512
|
+
);
|
|
8513
|
+
rollouts.command("add-items <id>").description("Add items (records / models / operations / etc.) to a rollout").option("-d, --data <json>", "Items as JSON string").option("--file <path>", "Items from JSON file").action(
|
|
8514
|
+
withErrorHandler(
|
|
8515
|
+
globalOpts,
|
|
8516
|
+
async (id, cmdOpts) => {
|
|
8517
|
+
const opts = globalOpts();
|
|
8518
|
+
const items = await parseInputData({
|
|
8519
|
+
data: cmdOpts.data,
|
|
8520
|
+
file: cmdOpts.file
|
|
8521
|
+
});
|
|
8522
|
+
const client = await createPlatformClient(opts);
|
|
8523
|
+
const batch = await client.publishBatches.addItems({
|
|
8524
|
+
batchId: id,
|
|
8525
|
+
versionIds: items.versionIds,
|
|
8526
|
+
modelIds: items.modelIds,
|
|
8527
|
+
operationIds: items.operationIds,
|
|
8528
|
+
contextDimensionIds: items.contextDimensionIds,
|
|
8529
|
+
authProviderIds: items.authProviderIds,
|
|
8530
|
+
includeProfileSchema: items.includeProfileSchema
|
|
8531
|
+
});
|
|
8532
|
+
if (opts.json || opts.jsonl) {
|
|
8533
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8534
|
+
} else {
|
|
8535
|
+
success(`Added items to rollout ${batch?.id}`);
|
|
8536
|
+
}
|
|
8537
|
+
}
|
|
8538
|
+
)
|
|
8539
|
+
);
|
|
8540
|
+
rollouts.command("remove-items <id>").description("Remove items from a rollout").option("-d, --data <json>", "Items to remove as JSON string").option("--file <path>", "Items to remove from JSON file").action(
|
|
8541
|
+
withErrorHandler(
|
|
8542
|
+
globalOpts,
|
|
8543
|
+
async (id, cmdOpts) => {
|
|
8544
|
+
const opts = globalOpts();
|
|
8545
|
+
const items = await parseInputData({
|
|
8546
|
+
data: cmdOpts.data,
|
|
8547
|
+
file: cmdOpts.file
|
|
8548
|
+
});
|
|
8549
|
+
const client = await createPlatformClient(opts);
|
|
8550
|
+
const batch = await client.publishBatches.removeItems({
|
|
8551
|
+
batchId: id,
|
|
8552
|
+
versionIds: items.versionIds,
|
|
8553
|
+
modelIds: items.modelIds,
|
|
8554
|
+
operationIds: items.operationIds,
|
|
8555
|
+
contextDimensionIds: items.contextDimensionIds,
|
|
8556
|
+
authProviderIds: items.authProviderIds,
|
|
8557
|
+
excludeProfileSchema: items.excludeProfileSchema
|
|
8558
|
+
});
|
|
8559
|
+
if (opts.json || opts.jsonl) {
|
|
8560
|
+
formatOutputProto(PublishBatchSchema, batch, opts);
|
|
8561
|
+
} else {
|
|
8562
|
+
success(`Removed items from rollout ${batch?.id}`);
|
|
8563
|
+
}
|
|
8564
|
+
}
|
|
8565
|
+
)
|
|
8566
|
+
);
|
|
8567
|
+
}
|
|
8568
|
+
|
|
7689
8569
|
// src/commands/locales.ts
|
|
7690
8570
|
import { LocaleSchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7691
8571
|
function registerLocalesCommands(program2, globalOpts) {
|
|
@@ -7890,7 +8770,7 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7890
8770
|
// src/commands/design-tokens.ts
|
|
7891
8771
|
import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
|
|
7892
8772
|
import { resolve as resolve6 } from "path";
|
|
7893
|
-
import
|
|
8773
|
+
import chalk15 from "chalk";
|
|
7894
8774
|
function registerDesignTokensCommands(program2, globalOpts) {
|
|
7895
8775
|
const tokens = program2.command("design-tokens").description("Manage project design tokens (W3C-formatted)");
|
|
7896
8776
|
tokens.command("get").description("Print the current design tokens document").option("--channel <channel>", "draft | published", "draft").option(
|
|
@@ -7938,7 +8818,7 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7938
8818
|
const resp = await client.settings.publishDesignTokens();
|
|
7939
8819
|
success("Design tokens published");
|
|
7940
8820
|
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7941
|
-
console.log(
|
|
8821
|
+
console.log(chalk15.yellow("\nBreaking changes:"));
|
|
7942
8822
|
for (const c of resp.breakingChanges) {
|
|
7943
8823
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7944
8824
|
}
|
|
@@ -7954,7 +8834,7 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7954
8834
|
const resp = await client.settings.publishDesignTokens();
|
|
7955
8835
|
success("Design tokens published");
|
|
7956
8836
|
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7957
|
-
console.log(
|
|
8837
|
+
console.log(chalk15.yellow("\nBreaking changes:"));
|
|
7958
8838
|
for (const c of resp.breakingChanges) {
|
|
7959
8839
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7960
8840
|
}
|
|
@@ -7979,12 +8859,12 @@ function registerDesignTokensCommands(program2, globalOpts) {
|
|
|
7979
8859
|
return;
|
|
7980
8860
|
}
|
|
7981
8861
|
if (status.hasPendingChanges) {
|
|
7982
|
-
console.log(
|
|
8862
|
+
console.log(chalk15.yellow("\u25CF Pending changes"));
|
|
7983
8863
|
} else {
|
|
7984
|
-
console.log(
|
|
8864
|
+
console.log(chalk15.green("\u25CF Up to date"));
|
|
7985
8865
|
}
|
|
7986
8866
|
if (status.breakingChanges && status.breakingChanges.length > 0) {
|
|
7987
|
-
console.log(
|
|
8867
|
+
console.log(chalk15.yellow("\nPending changes:"));
|
|
7988
8868
|
for (const c of status.breakingChanges) {
|
|
7989
8869
|
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7990
8870
|
}
|
|
@@ -9156,7 +10036,11 @@ registerOperationsCommands(program, getGlobalOpts);
|
|
|
9156
10036
|
registerSegmentsCommands(program, getGlobalOpts);
|
|
9157
10037
|
registerSchedulesCommands(program, getGlobalOpts);
|
|
9158
10038
|
registerApiKeysCommands(program, getGlobalOpts);
|
|
10039
|
+
registerAuthCommands(program, getGlobalOpts);
|
|
9159
10040
|
registerAuthProvidersCommands(program, getGlobalOpts);
|
|
10041
|
+
registerEmbeddingsCommands(program, getGlobalOpts);
|
|
10042
|
+
registerHooksCommands(program, getGlobalOpts);
|
|
10043
|
+
registerRolloutsCommands(program, getGlobalOpts);
|
|
9160
10044
|
registerLocalesCommands(program, getGlobalOpts);
|
|
9161
10045
|
registerSettingsCommands(program, getGlobalOpts);
|
|
9162
10046
|
registerDesignTokensCommands(program, getGlobalOpts);
|
|
@@ -67,6 +67,23 @@ type GenericFieldDefinitionInput = BaseFieldDefinitionInput & {
|
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
69
|
type FieldDefinitionInput = SelectFieldDefinitionInput | EnumFieldDefinitionInput | GenericFieldDefinitionInput;
|
|
70
|
+
/**
|
|
71
|
+
* Lookup definition — declares one indexed access path on a model.
|
|
72
|
+
*
|
|
73
|
+
* `keyBy` is the ordered list of top-level scalar field keys that make
|
|
74
|
+
* up the lookup key. Single-field lookups are common; composites are
|
|
75
|
+
* first-class (e.g. `['fromHost', 'fromPath']` for a redirect model).
|
|
76
|
+
* `name` overrides the generated GraphQL query field name; omit it to
|
|
77
|
+
* use `<typeLowerCamel>By<PascalCaseKeyFields>`.
|
|
78
|
+
*
|
|
79
|
+
* Validation runs server-side via the platform's config-write RPC —
|
|
80
|
+
* see RFC §Data model → Constraints. The CLI does no local validation
|
|
81
|
+
* here; the server's structured error surfaces verbatim on failure.
|
|
82
|
+
*/
|
|
83
|
+
interface LookupDefinitionInput {
|
|
84
|
+
keyBy: string[];
|
|
85
|
+
name?: string;
|
|
86
|
+
}
|
|
70
87
|
interface ApplyConfigModelInput {
|
|
71
88
|
key: string;
|
|
72
89
|
name: string;
|
|
@@ -75,6 +92,12 @@ interface ApplyConfigModelInput {
|
|
|
75
92
|
description?: string;
|
|
76
93
|
fields?: FieldDefinitionInput[];
|
|
77
94
|
config?: Record<string, unknown>;
|
|
95
|
+
/**
|
|
96
|
+
* Lookup definitions for this model. Server validates: existence /
|
|
97
|
+
* scalar-type / top-level-only / caps (4 lookups, 4 fields) / GraphQL
|
|
98
|
+
* field-name regex for `name`. See RFC §Data model (config surface).
|
|
99
|
+
*/
|
|
100
|
+
lookups?: LookupDefinitionInput[];
|
|
78
101
|
}
|
|
79
102
|
interface QuotaRule {
|
|
80
103
|
/** Segment key to target (empty string or omitted = default/fallback). */
|
|
@@ -453,4 +476,4 @@ interface FoirSecretsConfig {
|
|
|
453
476
|
*/
|
|
454
477
|
declare function defineSecrets(config: FoirSecretsConfig): FoirSecretsConfig;
|
|
455
478
|
|
|
456
|
-
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigDesignTokensInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type ExpressionPrecondition, type FieldDefinitionInput, type FoirSecretsConfig, type Precondition, type QuotaRule, type SecretDeclaration, type SecretOwnerKind, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineDesignTokens, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
|
|
479
|
+
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigDesignTokensInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type ExpressionPrecondition, type FieldDefinitionInput, type FoirSecretsConfig, type LookupDefinitionInput, type Precondition, type QuotaRule, type SecretDeclaration, type SecretOwnerKind, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineDesignTokens, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eide/foir-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Universal platform CLI for Foir platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@bufbuild/protovalidate": "^1.1.1",
|
|
51
51
|
"@connectrpc/connect": "^2.0.0",
|
|
52
52
|
"@connectrpc/connect-node": "^2.0.0",
|
|
53
|
-
"@eide/foir-proto-ts": "^0.
|
|
53
|
+
"@eide/foir-proto-ts": "^0.66.0",
|
|
54
54
|
"chalk": "^5.3.0",
|
|
55
55
|
"commander": "^12.1.0",
|
|
56
56
|
"dotenv": "^16.4.5",
|