@eide/foir-cli 0.11.3 → 0.13.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 +62 -8
- package/dist/lib/config-helpers.d.ts +64 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -848,7 +848,16 @@ function createIdentityMethods(client) {
|
|
|
848
848
|
create(UpdateProjectRequestSchema, {
|
|
849
849
|
id: params.id,
|
|
850
850
|
name: params.name,
|
|
851
|
-
description: params.description
|
|
851
|
+
description: params.description,
|
|
852
|
+
displayName: params.displayName,
|
|
853
|
+
logoUrl: params.logoUrl,
|
|
854
|
+
primaryColor: params.primaryColor,
|
|
855
|
+
fromName: params.fromName,
|
|
856
|
+
replyTo: params.replyTo,
|
|
857
|
+
supportEmail: params.supportEmail,
|
|
858
|
+
appBaseUrl: params.appBaseUrl,
|
|
859
|
+
customerWelcomeEmailEnabled: params.customerWelcomeEmailEnabled,
|
|
860
|
+
customerSignupEnabled: params.customerSignupEnabled
|
|
852
861
|
})
|
|
853
862
|
);
|
|
854
863
|
return { project: resp.project ?? null };
|
|
@@ -5697,17 +5706,17 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5697
5706
|
}
|
|
5698
5707
|
const gOpts = globalOpts();
|
|
5699
5708
|
const resolved = await resolveProjectContext(gOpts);
|
|
5700
|
-
const
|
|
5701
|
-
if (
|
|
5709
|
+
const projectBlock = config2.project;
|
|
5710
|
+
if (projectBlock) {
|
|
5702
5711
|
if (!resolved) {
|
|
5703
5712
|
throw new Error(
|
|
5704
|
-
`foir.config.ts is pinned to project "${
|
|
5713
|
+
`foir.config.ts is pinned to project "${projectBlock.name ?? projectBlock.id}" (${projectBlock.id}), but no project context is selected. Run \`foir select-project\` first.`
|
|
5705
5714
|
);
|
|
5706
5715
|
}
|
|
5707
|
-
if (resolved.project.id !==
|
|
5716
|
+
if (resolved.project.id !== projectBlock.id || resolved.project.tenantId !== projectBlock.tenantId) {
|
|
5708
5717
|
throw new Error(
|
|
5709
5718
|
`Project mismatch \u2014 refusing to push.
|
|
5710
|
-
foir.config.ts pin: ${
|
|
5719
|
+
foir.config.ts pin: ${projectBlock.name ?? projectBlock.id} (${projectBlock.id})
|
|
5711
5720
|
resolved (${resolved.source}): ${resolved.project.name} (${resolved.project.id})
|
|
5712
5721
|
Hand-edit foir.config.ts or run \`foir select-project\` to align them.`
|
|
5713
5722
|
);
|
|
@@ -5766,7 +5775,23 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5766
5775
|
console.log(` Config Key: ${chalk6.cyan(config2.key)}`);
|
|
5767
5776
|
console.log();
|
|
5768
5777
|
printSummary(summary);
|
|
5769
|
-
if (
|
|
5778
|
+
if (projectBlock?.settings && resolved) {
|
|
5779
|
+
const s = projectBlock.settings;
|
|
5780
|
+
await client.identity.updateProject({
|
|
5781
|
+
id: resolved.project.id,
|
|
5782
|
+
displayName: s.displayName,
|
|
5783
|
+
logoUrl: s.logoUrl,
|
|
5784
|
+
primaryColor: s.primaryColor,
|
|
5785
|
+
fromName: s.fromName,
|
|
5786
|
+
replyTo: s.replyTo,
|
|
5787
|
+
supportEmail: s.supportEmail,
|
|
5788
|
+
appBaseUrl: s.appBaseUrl,
|
|
5789
|
+
customerWelcomeEmailEnabled: s.customerWelcomeEmailEnabled,
|
|
5790
|
+
customerSignupEnabled: s.customerSignupEnabled
|
|
5791
|
+
});
|
|
5792
|
+
console.log(chalk6.dim(" Project settings: applied"));
|
|
5793
|
+
}
|
|
5794
|
+
if (!projectBlock && resolved) {
|
|
5770
5795
|
console.log();
|
|
5771
5796
|
console.log(chalk6.dim("Tip: pin this folder to its project by adding the following to foir.config.ts:"));
|
|
5772
5797
|
console.log(chalk6.dim(" project: {"));
|
|
@@ -5877,6 +5902,7 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5877
5902
|
}
|
|
5878
5903
|
const resolved = await resolveProjectContext(globalOpts());
|
|
5879
5904
|
let apps;
|
|
5905
|
+
let projectBlock;
|
|
5880
5906
|
if (resolved) {
|
|
5881
5907
|
const projectId = resolved.project.id;
|
|
5882
5908
|
const tenantId = resolved.project.tenantId;
|
|
@@ -5887,9 +5913,18 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5887
5913
|
apps[a.name] = appToInput(a);
|
|
5888
5914
|
}
|
|
5889
5915
|
}
|
|
5916
|
+
const { project } = await client.identity.getProject(projectId);
|
|
5917
|
+
projectBlock = {
|
|
5918
|
+
id: projectId,
|
|
5919
|
+
tenantId,
|
|
5920
|
+
...project?.name ? { name: project.name } : {},
|
|
5921
|
+
settings: projectSettingsFromGetProject(project)
|
|
5922
|
+
};
|
|
5890
5923
|
}
|
|
5891
5924
|
const configDataNoInteg = { ...configData };
|
|
5892
5925
|
delete configDataNoInteg.apps;
|
|
5926
|
+
const configDataNoProject = { ...configDataNoInteg };
|
|
5927
|
+
delete configDataNoProject.project;
|
|
5893
5928
|
const manifest = {
|
|
5894
5929
|
key: config2.key,
|
|
5895
5930
|
name: config2.name,
|
|
@@ -5897,7 +5932,8 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5897
5932
|
...config2.direction ? { direction: config2.direction } : {},
|
|
5898
5933
|
...config2.description ? { description: config2.description } : {},
|
|
5899
5934
|
...config2.connectionDomain ? { operationBaseUrl: config2.connectionDomain } : {},
|
|
5900
|
-
...
|
|
5935
|
+
...projectBlock ? { project: projectBlock } : {},
|
|
5936
|
+
...configDataNoProject,
|
|
5901
5937
|
...apps ? { apps } : {}
|
|
5902
5938
|
};
|
|
5903
5939
|
delete manifest.force;
|
|
@@ -5988,6 +6024,24 @@ export default defineConfig(${jsonContent});
|
|
|
5988
6024
|
)
|
|
5989
6025
|
);
|
|
5990
6026
|
}
|
|
6027
|
+
function projectSettingsFromGetProject(p) {
|
|
6028
|
+
if (!p) return void 0;
|
|
6029
|
+
const out = {};
|
|
6030
|
+
if (p.displayName) out.displayName = p.displayName;
|
|
6031
|
+
if (p.logoUrl) out.logoUrl = p.logoUrl;
|
|
6032
|
+
if (p.primaryColor) out.primaryColor = p.primaryColor;
|
|
6033
|
+
if (p.fromName) out.fromName = p.fromName;
|
|
6034
|
+
if (p.replyTo) out.replyTo = p.replyTo;
|
|
6035
|
+
if (p.supportEmail) out.supportEmail = p.supportEmail;
|
|
6036
|
+
if (p.appBaseUrl) out.appBaseUrl = p.appBaseUrl;
|
|
6037
|
+
if (typeof p.customerWelcomeEmailEnabled === "boolean") {
|
|
6038
|
+
out.customerWelcomeEmailEnabled = p.customerWelcomeEmailEnabled;
|
|
6039
|
+
}
|
|
6040
|
+
if (typeof p.customerSignupEnabled === "boolean") {
|
|
6041
|
+
out.customerSignupEnabled = p.customerSignupEnabled;
|
|
6042
|
+
}
|
|
6043
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
6044
|
+
}
|
|
5991
6045
|
function appToInput(a) {
|
|
5992
6046
|
const mappingsBlob = a.mappings ?? {};
|
|
5993
6047
|
const out = { source: a.manifestUrl };
|
|
@@ -252,6 +252,63 @@ interface AppInput {
|
|
|
252
252
|
placementFields?: Record<string, AppPlacementFieldChoiceInput>;
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Project-level settings applied via UpdateProject at push time and
|
|
257
|
+
* read via GetProject at pull time. Branding fields are empty-string-as-
|
|
258
|
+
* clear on the platform side: `''` clears the column, `undefined` leaves
|
|
259
|
+
* it untouched.
|
|
260
|
+
*/
|
|
261
|
+
interface ApplyConfigProjectSettingsInput {
|
|
262
|
+
/** Display name in customer-facing emails / portal headers. */
|
|
263
|
+
displayName?: string;
|
|
264
|
+
/** Public URL of the project logo (rendered in customer emails). */
|
|
265
|
+
logoUrl?: string;
|
|
266
|
+
/** Hex color used as accent in customer-facing emails. */
|
|
267
|
+
primaryColor?: string;
|
|
268
|
+
/** "From" name on outbound customer emails. */
|
|
269
|
+
fromName?: string;
|
|
270
|
+
/** "Reply-To" address on outbound customer emails. */
|
|
271
|
+
replyTo?: string;
|
|
272
|
+
/** Support email surfaced in email footers. */
|
|
273
|
+
supportEmail?: string;
|
|
274
|
+
/**
|
|
275
|
+
* Public base URL of the consumer-facing app (storefront, portal,
|
|
276
|
+
* internal tool, …). Reset / verify / invitation links in customer
|
|
277
|
+
* emails are built from this — required before the platform will mint
|
|
278
|
+
* customer-email links.
|
|
279
|
+
*/
|
|
280
|
+
appBaseUrl?: string;
|
|
281
|
+
/**
|
|
282
|
+
* Whether the platform sends a welcome email on customer registration.
|
|
283
|
+
* Default true. Disable for invite-style flows.
|
|
284
|
+
*/
|
|
285
|
+
customerWelcomeEmailEnabled?: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Whether the public CustomerRegister mutation is allowed. Default true.
|
|
288
|
+
* When false, customers can only be created via secret-key admin paths
|
|
289
|
+
* (CreateCustomer, CreateCustomerInvitation).
|
|
290
|
+
*/
|
|
291
|
+
customerSignupEnabled?: boolean;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Project pin + declarative settings. The pin (id / tenantId) is a guard
|
|
295
|
+
* against pushing one folder's config into another folder's project; the
|
|
296
|
+
* settings are applied to the platform via UpdateProject.
|
|
297
|
+
*/
|
|
298
|
+
interface ApplyConfigProjectInput {
|
|
299
|
+
/** Project id this folder is bound to. */
|
|
300
|
+
id: string;
|
|
301
|
+
/** Tenant id of the bound project. */
|
|
302
|
+
tenantId: string;
|
|
303
|
+
/** Optional human-friendly name for diff readability. */
|
|
304
|
+
name?: string;
|
|
305
|
+
/**
|
|
306
|
+
* Project-level settings reconciled by `foir push`. Omit to leave the
|
|
307
|
+
* platform settings untouched. `foir pull` populates this block from
|
|
308
|
+
* the live project state so the local config can be version-controlled.
|
|
309
|
+
*/
|
|
310
|
+
settings?: ApplyConfigProjectSettingsInput;
|
|
311
|
+
}
|
|
255
312
|
interface ApplyConfigInput {
|
|
256
313
|
key: string;
|
|
257
314
|
name: string;
|
|
@@ -259,6 +316,12 @@ interface ApplyConfigInput {
|
|
|
259
316
|
force?: boolean;
|
|
260
317
|
/** Base URL prepended to relative operation endpoints. */
|
|
261
318
|
operationBaseUrl?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Project pin + declarative project-level settings. The pin guards
|
|
321
|
+
* against cross-folder mis-pushes; the settings (when present) are
|
|
322
|
+
* applied to the platform alongside the model / operation reconcile.
|
|
323
|
+
*/
|
|
324
|
+
project?: ApplyConfigProjectInput;
|
|
262
325
|
models?: ApplyConfigModelInput[];
|
|
263
326
|
operations?: ApplyConfigOperationInput[];
|
|
264
327
|
segments?: ApplyConfigSegmentInput[];
|
|
@@ -292,4 +355,4 @@ declare function defineHook(hook: ApplyConfigHookInput): ApplyConfigHookInput;
|
|
|
292
355
|
/** Define an editor placement (sidebar or main-editor tab). */
|
|
293
356
|
declare function definePlacement(placement: ApplyConfigPlacementInput): ApplyConfigPlacementInput;
|
|
294
357
|
|
|
295
|
-
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type ExpressionPrecondition, type FieldDefinitionInput, type Precondition, type QuotaRule, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSegment, defineSelectField };
|
|
358
|
+
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type ExpressionPrecondition, type FieldDefinitionInput, type Precondition, type QuotaRule, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSegment, defineSelectField };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eide/foir-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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.31.0",
|
|
54
54
|
"chalk": "^5.3.0",
|
|
55
55
|
"commander": "^12.1.0",
|
|
56
56
|
"dotenv": "^16.4.5",
|