@foir/cli 0.64.0 → 0.64.1

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.
@@ -153,12 +153,16 @@ interface AccessInput {
153
153
  ownerPlane: 'customer' | 'admin' | 'project';
154
154
  /**
155
155
  * Visibility new records start at (the record descriptor modes):
156
- * - `'private'` — only the owner and explicit grants. The default.
157
- * - `'public_project'` — readable by anyone in the project.
158
- * - `'public_world'` — readable by anyone (public API).
159
- * Omit to use the platform default (private).
160
- */
161
- defaultVisibility?: 'private' | 'public_project' | 'public_world';
156
+ * - `'private'` — only the owner and explicit grants.
157
+ * - `'public'` — readable by anyone in the project (CMS-style content;
158
+ * including authenticated customers on the public API).
159
+ * On a PROJECT-plane model, omitting this defaults to `'public'` — project
160
+ * content is meant to be read, so it is customer-readable by default; set
161
+ * `'private'` explicitly to opt a project model out. Owned planes
162
+ * (customer/admin) are always private (the platform rejects a public default
163
+ * there), regardless of this value.
164
+ */
165
+ defaultVisibility?: 'private' | 'public';
162
166
  }
163
167
  interface ApplyConfigModelInput {
164
168
  key: string;
@@ -216,8 +220,17 @@ interface ApplyConfigOperationInput {
216
220
  };
217
221
  /** Retry policy for failed executions. */
218
222
  retryPolicy?: Record<string, unknown>;
219
- /** Roles allowed to execute this operation. */
220
- allowedRoles?: string[];
223
+ /**
224
+ * Admin permission verbs required to execute this operation.
225
+ *
226
+ * CONJUNCTIVE: the caller must hold EVERY verb listed, so adding one always
227
+ * narrows who may execute. Omit or pass `[]` for no gate. Entries are verbs
228
+ * from the admin permission vocabulary, e.g. `['content:write']`.
229
+ *
230
+ * Replaced `allowedRoles` (TTS-1049), which named role KEYS. Role keys are
231
+ * yours to choose, so renaming a role silently changed who could execute.
232
+ */
233
+ allowedPermissions?: string[];
221
234
  /** Precondition that must be met before execution (e.g., segment membership). */
222
235
  precondition?: Precondition;
223
236
  /**
@@ -358,6 +371,37 @@ interface ApplyConfigContextDimensionInput {
358
371
  sourceModelKey?: string;
359
372
  defaultRecordKey?: string;
360
373
  }
374
+ /**
375
+ * A project locale. Natural key is the locale `code` (e.g. "en-GB").
376
+ * Reconciled by `foir push` — declared locales are created / updated. Locales
377
+ * are also admin-editable and carry no config ownership, so a push never
378
+ * DELETES a locale it did not declare (create/update only).
379
+ */
380
+ interface ApplyConfigLocaleInput {
381
+ /** BCP-47 locale code, immutable after create (e.g. "en", "fr-CA"). */
382
+ locale: string;
383
+ displayName: string;
384
+ nativeName?: string;
385
+ isDefault?: boolean;
386
+ isActive?: boolean;
387
+ isRtl?: boolean;
388
+ /** Locale code to fall back to when a translation is missing. */
389
+ fallbackLocale?: string;
390
+ }
391
+ /**
392
+ * A variant-catalog entry — a named targeting definition. Natural key is `key`.
393
+ * Reconciled by `foir push` (create/update only, same rationale as locales).
394
+ */
395
+ interface ApplyConfigVariantCatalogEntryInput {
396
+ key: string;
397
+ name: string;
398
+ description?: string;
399
+ /** RuleExpression object evaluated to decide whether this variant applies. */
400
+ targetingRules?: Record<string, unknown>;
401
+ priority?: number;
402
+ isDefault?: boolean;
403
+ isActive?: boolean;
404
+ }
361
405
  interface ApplyConfigScheduleInput {
362
406
  /** Unique key for this schedule. Defaults to operationKey if not provided. */
363
407
  key?: string;
@@ -612,11 +656,20 @@ interface ApplyConfigProjectSettingsInput {
612
656
  */
613
657
  customerWelcomeEmailEnabled?: boolean;
614
658
  /**
615
- * Whether the public CustomerRegister mutation is allowed. Default true.
616
- * When false, customers can only be created via secret-key admin paths
617
- * (CreateCustomer, CreateCustomerInvitation).
659
+ * Self-serve customer signup mode. Default `public`. `restricted` accepts only
660
+ * invited emails, `waitlist` queues signups for approval, `closed` disables
661
+ * self-serve signup entirely.
618
662
  */
619
- customerSignupEnabled?: boolean;
663
+ signupMode?: SignupModeName;
664
+ /**
665
+ * Email hygiene + allow/block restrictions applied to `public`-mode signups.
666
+ * `blockSubaddresses` requires the canonical inbox form (rejects subaddress
667
+ * tags, Gmail dots, and the googlemail alias domain). An allowlist, when
668
+ * non-empty, is exclusive and beats the blocklist. List patterns: exact
669
+ * `user@domain.com`, whole domain (`domain.com`), wildcard subdomains
670
+ * (`*.domain.com`).
671
+ */
672
+ signupRestrictions?: SignupRestrictionsInput;
620
673
  /**
621
674
  * Whether email/password customer login is exposed. Default true. Disable
622
675
  * for a passwordless project (one-time codes or single sign-on only).
@@ -627,6 +680,15 @@ interface ApplyConfigProjectSettingsInput {
627
680
  */
628
681
  customerOtpEnabled?: boolean;
629
682
  }
683
+ /** Self-serve signup mode, as authored in config-as-code. */
684
+ type SignupModeName = 'public' | 'restricted' | 'waitlist' | 'closed';
685
+ /** Email hygiene + allow/block restrictions, as authored in config-as-code. */
686
+ interface SignupRestrictionsInput {
687
+ blockSubaddresses?: boolean;
688
+ blockDisposable?: boolean;
689
+ allowlist?: string[];
690
+ blocklist?: string[];
691
+ }
630
692
  /**
631
693
  * Project pin + declarative settings. The pin (id / tenantId) is a guard
632
694
  * against pushing one folder's config into another folder's project; the
@@ -683,6 +745,10 @@ interface ApplyConfigInput {
683
745
  models?: ApplyConfigModelInput[];
684
746
  operations?: ApplyConfigOperationInput[];
685
747
  contextDimensions?: ApplyConfigContextDimensionInput[];
748
+ /** Project locales, reconciled by `foir push` (create/update only). */
749
+ locales?: ApplyConfigLocaleInput[];
750
+ /** Variant-catalog entries, reconciled by `foir push` (create/update only). */
751
+ variantCatalog?: ApplyConfigVariantCatalogEntryInput[];
686
752
  schedules?: ApplyConfigScheduleInput[];
687
753
  hooks?: ApplyConfigHookInput[];
688
754
  authProviders?: ApplyConfigAuthProviderInput[];
@@ -727,6 +793,10 @@ declare function defineEnumField(field: EnumFieldDefinitionInput): FieldDefiniti
727
793
  declare function defineOperation(operation: ApplyConfigOperationInput): ApplyConfigOperationInput;
728
794
  /** Define a context dimension (segment rule / model source) with type safety. */
729
795
  declare function defineContextDimension(dimension: ApplyConfigContextDimensionInput): ApplyConfigContextDimensionInput;
796
+ /** Define a project locale. */
797
+ declare function defineLocale(locale: ApplyConfigLocaleInput): ApplyConfigLocaleInput;
798
+ /** Define a variant-catalog entry (targeting definition). */
799
+ declare function defineVariantCatalogEntry(entry: ApplyConfigVariantCatalogEntryInput): ApplyConfigVariantCatalogEntryInput;
730
800
  /** Define a cron schedule for an operation. */
731
801
  declare function defineSchedule(schedule: ApplyConfigScheduleInput): ApplyConfigScheduleInput;
732
802
  /** Define an auth provider. */
@@ -771,4 +841,4 @@ interface FoirSecretsConfig {
771
841
  */
772
842
  declare function defineSecrets(config: FoirSecretsConfig): FoirSecretsConfig;
773
843
 
774
- export { type AccessInput, type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigContextDimensionInput, type ApplyConfigCustomerRoleInput, type ApplyConfigDesignTokensInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigRelyingPartyInput, type ApplyConfigRelyingPartyLoginMethods, type ApplyConfigScheduleInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type FieldAccessInput, type FieldDefinitionInput, type FieldRelationshipInput, type FoirSecretsConfig, type LookupDefinitionInput, type QuotaRule, type ReferenceFieldConfig, type ReferenceFieldDefinitionInput, type SecretDeclaration, type SecretOwnerKind, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineContextDimension, defineDesignTokens, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineRelyingParty, defineSchedule, defineSecrets, defineSelectField };
844
+ export { type AccessInput, type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigContextDimensionInput, type ApplyConfigCustomerRoleInput, type ApplyConfigDesignTokensInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigLocaleInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigRelyingPartyInput, type ApplyConfigRelyingPartyLoginMethods, type ApplyConfigScheduleInput, type ApplyConfigVariantCatalogEntryInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type FieldAccessInput, type FieldDefinitionInput, type FieldRelationshipInput, type FoirSecretsConfig, type LookupDefinitionInput, type QuotaRule, type ReferenceFieldConfig, type ReferenceFieldDefinitionInput, type SecretDeclaration, type SecretOwnerKind, type SelectFieldConfig, type SelectFieldDefinitionInput, type SignupModeName, type SignupRestrictionsInput, defineAuthProvider, defineConfig, defineContextDimension, defineDesignTokens, defineEnumField, defineField, defineHook, defineLocale, defineModel, defineOperation, definePlacement, defineRelyingParty, defineSchedule, defineSecrets, defineSelectField, defineVariantCatalogEntry };
@@ -23,6 +23,12 @@ function defineOperation(operation) {
23
23
  function defineContextDimension(dimension) {
24
24
  return dimension;
25
25
  }
26
+ function defineLocale(locale) {
27
+ return locale;
28
+ }
29
+ function defineVariantCatalogEntry(entry) {
30
+ return entry;
31
+ }
26
32
  function defineSchedule(schedule) {
27
33
  return schedule;
28
34
  }
@@ -49,11 +55,13 @@ export {
49
55
  defineEnumField,
50
56
  defineField,
51
57
  defineHook,
58
+ defineLocale,
52
59
  defineModel,
53
60
  defineOperation,
54
61
  definePlacement,
55
62
  defineRelyingParty,
56
63
  defineSchedule,
57
64
  defineSecrets,
58
- defineSelectField
65
+ defineSelectField,
66
+ defineVariantCatalogEntry
59
67
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foir/cli",
3
- "version": "0.64.0",
3
+ "version": "0.64.1",
4
4
  "description": "Universal platform CLI for Foir platform",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -37,6 +37,7 @@
37
37
  "@bufbuild/protovalidate": "^1.1.1",
38
38
  "@connectrpc/connect": "^2.0.0",
39
39
  "@connectrpc/connect-node": "^2.0.0",
40
+ "@modelcontextprotocol/sdk": "^1.29.0",
40
41
  "chalk": "^5.3.0",
41
42
  "commander": "^12.1.0",
42
43
  "dotenv": "^16.4.5",
@@ -55,8 +56,10 @@
55
56
  "tsx": "^4.20.0",
56
57
  "typescript": "5.9.2",
57
58
  "vitest": "^3.2.4",
59
+ "@foir/console-routes": "0.0.0",
60
+ "@foir/proto-ts": "0.109.0",
58
61
  "@foir/rpc-node": "0.0.0",
59
- "@foir/proto-ts": "0.109.0"
62
+ "@foir/sdk": "0.7.0"
60
63
  },
61
64
  "engines": {
62
65
  "node": ">=18.0.0"