@eide/foir-cli 0.18.0 → 0.20.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 CHANGED
@@ -6625,7 +6625,9 @@ function registerRecordsCommands(program2, globalOpts) {
6625
6625
  }
6626
6626
  )
6627
6627
  );
6628
- records.command("update <modelKey> <id>").description("Update a record").option("-d, --data <json>", "Record data as JSON").option("-f, --file <path>", "Read data from file").action(
6628
+ records.command("update <modelKey> <id>").description(
6629
+ "Update a record's data column directly. Bypasses versioning \u2014 no version row is created and currentVersionId is unchanged. For the admin-equivalent atomic save (data + new version + currentVersionId bump), use `records save`."
6630
+ ).option("-d, --data <json>", "Record data as JSON").option("-f, --file <path>", "Read data from file").action(
6629
6631
  withErrorHandler(
6630
6632
  globalOpts,
6631
6633
  async (_modelKey, id, cmdOpts) => {
@@ -6641,6 +6643,34 @@ function registerRecordsCommands(program2, globalOpts) {
6641
6643
  }
6642
6644
  )
6643
6645
  );
6646
+ records.command("save <modelKey> <id>").description(
6647
+ "Save record content (admin Save Draft equivalent). Atomically replaces data, creates an immutable version row, and advances currentVersionId \u2014 preview and storefront see the new content without a separate publish step."
6648
+ ).option("-d, --data <json>", "Record data as JSON").option("-f, --file <path>", "Read data from file").option("-m, --message <msg>", "Change description").option("--variant <key>", "Save into a specific variant").action(
6649
+ withErrorHandler(
6650
+ globalOpts,
6651
+ async (_modelKey, id, cmdOpts) => {
6652
+ const opts = globalOpts();
6653
+ const client = await createPlatformClient(opts);
6654
+ const inputData = await parseInputData(cmdOpts);
6655
+ const result = await client.records.saveContent({
6656
+ recordId: id,
6657
+ data: inputData,
6658
+ variantKey: cmdOpts.variant,
6659
+ changeDescription: cmdOpts.message
6660
+ });
6661
+ formatOutput(
6662
+ {
6663
+ record: result.record ? toJson3(RecordSchema, result.record) : null,
6664
+ version: result.version ? toJson3(RecordSchema, result.version) : null
6665
+ },
6666
+ opts
6667
+ );
6668
+ if (!(opts.json || opts.jsonl || opts.quiet)) {
6669
+ success(`Saved record ${id} \u2192 version ${result.version?.id}`);
6670
+ }
6671
+ }
6672
+ )
6673
+ );
6644
6674
  records.command("delete <modelKey> <id>").description("Delete a record").option("--confirm", "Skip confirmation prompt").action(
6645
6675
  withErrorHandler(
6646
6676
  globalOpts,
@@ -6748,7 +6778,7 @@ function registerRecordsCommands(program2, globalOpts) {
6748
6778
  })
6749
6779
  );
6750
6780
  records.command("create-version <parentId>").description(
6751
- "Create a new version on a versioned record (or variant). parentId is the record or variant ID."
6781
+ "Low-level: create a version row without touching the parent record's data column or currentVersionId. The new version is orphaned from preview/storefront resolution until published. For the admin-equivalent atomic save (data + version + currentVersionId), use `records save`."
6752
6782
  ).option("-d, --data <json>", "Version content as JSON").option("-f, --file <path>", "Read content from file").option("-m, --message <msg>", "Change description").option("--source-version <id>", "Source version ID to base off").action(
6753
6783
  withErrorHandler(
6754
6784
  globalOpts,
@@ -16,28 +16,57 @@
16
16
  * });
17
17
  * ```
18
18
  */
19
- interface SelectFieldConfig extends Record<string, unknown> {
19
+ /**
20
+ * `select` is record-backed: options come from records of `optionModelKey`.
21
+ * For inline `{label, value}` choices, declare `type: 'enum'` instead — the
22
+ * `options?: never` here forbids the legacy shape at the type level.
23
+ */
24
+ interface SelectFieldConfig {
20
25
  optionModelKey: string;
21
26
  multiple?: boolean;
27
+ options?: never;
28
+ }
29
+ interface EnumFieldOption {
30
+ label: string;
31
+ value: string;
32
+ }
33
+ /**
34
+ * `enum` is config-only: the storefront receives a typed string-literal
35
+ * union from inline `{label, value}` options. Variant overrides apply;
36
+ * locale overrides do not.
37
+ */
38
+ interface EnumFieldConfig {
39
+ options: EnumFieldOption[];
40
+ multiple?: boolean;
41
+ default?: string | string[];
22
42
  }
23
- type FieldDefinitionInput = {
43
+ interface BaseFieldDefinitionInput {
24
44
  key: string;
25
- type: string;
26
45
  label?: string;
27
46
  required?: boolean;
28
47
  helpText?: string;
29
48
  placeholder?: string;
30
49
  defaultValue?: unknown;
31
- config?: Record<string, unknown>;
32
50
  itemType?: string;
33
51
  storage?: string;
34
52
  templateZone?: string;
35
53
  zoneOrder?: number;
36
- };
37
- type SelectFieldDefinitionInput = Omit<FieldDefinitionInput, 'type' | 'config'> & {
54
+ }
55
+ type SelectFieldDefinitionInput = BaseFieldDefinitionInput & {
38
56
  type: 'select';
39
57
  config: SelectFieldConfig;
40
58
  };
59
+ type EnumFieldDefinitionInput = BaseFieldDefinitionInput & {
60
+ type: 'enum';
61
+ config: EnumFieldConfig;
62
+ };
63
+ type GenericFieldDefinitionInput = BaseFieldDefinitionInput & {
64
+ type: string;
65
+ config?: Record<string, unknown> & {
66
+ options?: never;
67
+ };
68
+ };
69
+ type FieldDefinitionInput = SelectFieldDefinitionInput | EnumFieldDefinitionInput | GenericFieldDefinitionInput;
41
70
  interface ApplyConfigModelInput {
42
71
  key: string;
43
72
  name: string;
@@ -342,6 +371,8 @@ declare function defineModel(model: ApplyConfigModelInput): ApplyConfigModelInpu
342
371
  declare function defineField(field: FieldDefinitionInput): FieldDefinitionInput;
343
372
  /** Define a select field — requires `optionModelKey` pointing to a model whose records become options. */
344
373
  declare function defineSelectField(field: SelectFieldDefinitionInput): FieldDefinitionInput;
374
+ /** Define an enum field — config-only choice from inline `{label, value}` options. */
375
+ declare function defineEnumField(field: EnumFieldDefinitionInput): FieldDefinitionInput;
345
376
  /** Define an operation with type safety. */
346
377
  declare function defineOperation(operation: ApplyConfigOperationInput): ApplyConfigOperationInput;
347
378
  /** Define a segment with type safety. */
@@ -388,4 +419,4 @@ interface FoirSecretsConfig {
388
419
  */
389
420
  declare function defineSecrets(config: FoirSecretsConfig): FoirSecretsConfig;
390
421
 
391
- 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 FoirSecretsConfig, type Precondition, type QuotaRule, type SecretDeclaration, type SecretOwnerKind, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
422
+ 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 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, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
@@ -11,6 +11,9 @@ function defineField(field) {
11
11
  function defineSelectField(field) {
12
12
  return field;
13
13
  }
14
+ function defineEnumField(field) {
15
+ return field;
16
+ }
14
17
  function defineOperation(operation) {
15
18
  return operation;
16
19
  }
@@ -35,6 +38,7 @@ function defineSecrets(config) {
35
38
  export {
36
39
  defineAuthProvider,
37
40
  defineConfig,
41
+ defineEnumField,
38
42
  defineField,
39
43
  defineHook,
40
44
  defineModel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eide/foir-cli",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Universal platform CLI for Foir platform",
5
5
  "type": "module",
6
6
  "publishConfig": {