@eide/foir-cli 0.24.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 +29 -6
- package/dist/lib/config-helpers.d.ts +24 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -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;
|
|
@@ -5063,7 +5071,15 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
5063
5071
|
const operationBaseUrl = manifest.operationBaseUrl ?? "";
|
|
5064
5072
|
const modelConflicts = [];
|
|
5065
5073
|
const mappingConflicts = [];
|
|
5066
|
-
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
|
+
);
|
|
5067
5083
|
await reconcileOperations(client, configId, manifest.operations ?? [], operationBaseUrl, summary);
|
|
5068
5084
|
await reconcileHooks(client, configId, manifest.hooks ?? [], summary);
|
|
5069
5085
|
await reconcileSegments(client, configId, manifest.segments ?? [], summary);
|
|
@@ -5094,7 +5110,7 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
5094
5110
|
}
|
|
5095
5111
|
return summary;
|
|
5096
5112
|
}
|
|
5097
|
-
async function reconcileModels(client, configId, models, summary, force, conflictOut) {
|
|
5113
|
+
async function reconcileModels(client, configId, models, summary, force, allowLookupRebuild, conflictOut) {
|
|
5098
5114
|
const existing = await client.models.listModels({ limit: 200 });
|
|
5099
5115
|
const allByKey = new Map(
|
|
5100
5116
|
existing.items.map((m) => [m.key, m])
|
|
@@ -5111,6 +5127,7 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
5111
5127
|
if (m.pluralName) config2.pluralName = m.pluralName;
|
|
5112
5128
|
if (m.pluralKey) config2.pluralKey = m.pluralKey;
|
|
5113
5129
|
if (m.description) config2.description = m.description;
|
|
5130
|
+
if (m.lookups !== void 0) config2.lookups = m.lookups;
|
|
5114
5131
|
const ex = allByKey.get(m.key);
|
|
5115
5132
|
if (!ex) {
|
|
5116
5133
|
plans.push({ kind: "create", model: m, config: config2 });
|
|
@@ -5179,7 +5196,8 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
5179
5196
|
name: p.name,
|
|
5180
5197
|
fields: fieldsToWrite,
|
|
5181
5198
|
config: p.config,
|
|
5182
|
-
updatePushSnapshot: true
|
|
5199
|
+
updatePushSnapshot: true,
|
|
5200
|
+
allowLookupRebuild
|
|
5183
5201
|
});
|
|
5184
5202
|
summary.models.updated++;
|
|
5185
5203
|
summary.updatedModelIds.push(p.id);
|
|
@@ -5802,6 +5820,10 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5802
5820
|
"--publish",
|
|
5803
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.",
|
|
5804
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
|
|
5805
5827
|
).option("--env <path>", "Path to .env file (default: .env)").action(
|
|
5806
5828
|
withErrorHandler(
|
|
5807
5829
|
globalOpts,
|
|
@@ -5862,7 +5884,8 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5862
5884
|
tenantId: resolved?.project.tenantId,
|
|
5863
5885
|
projectId: resolved?.project.id,
|
|
5864
5886
|
force: opts.force ?? false,
|
|
5865
|
-
publishDesignTokens: opts.publish ?? false
|
|
5887
|
+
publishDesignTokens: opts.publish ?? false,
|
|
5888
|
+
allowLookupRebuild: opts.rebuild ?? false
|
|
5866
5889
|
});
|
|
5867
5890
|
} catch (e) {
|
|
5868
5891
|
if (e instanceof PushConflictError) {
|
|
@@ -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",
|