@protobase/schema 0.20.0 → 0.21.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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FileOptions, FileProcessor, FileProcessorInput, ImageFormat, ImageVariant, ImageVariantOptions, imageFormats } from "./files/file-options.js";
2
- import { ActionInputKind, ActionInputModel, ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, GalleryModel, GroupChartModel, HelpWhen, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NavModel, NavRecentModel, NowValue, OrderByItem, PeriodChartModel, RecordMode, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, UserMenuItemModel, UserMenuModel, ViewModel } from "./model.js";
2
+ import { ActionInputKind, ActionInputModel, ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, GalleryModel, GroupChartModel, HelpWhen, HistorySectionModel, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NavModel, NavRecentModel, NowValue, OrderByItem, PeriodChartModel, RecordMode, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, UserMenuItemModel, UserMenuModel, ViewModel } from "./model.js";
3
3
  import { AccessAction, AccessContext, AccessFn, AccessResult, AccessUser, FieldAccess, FieldRule } from "./access/types.js";
4
4
  import { AnyField, Constraint, Field, FieldMeta, FieldTypeDef } from "./field.js";
5
5
  import { RelationField } from "./relation-field.js";
@@ -39,4 +39,4 @@ import { AccessSource, ResolveOptions, ResolvedAccess, RowFilterOperation, acces
39
39
  import { restrictModel } from "./access/restrict.js";
40
40
  import "./access/index.js";
41
41
  import { AssistantAction, AssistantActionRequest, AssistantCardPart, AssistantDiff, AssistantEvent, AssistantMessage, AssistantMessageRequest, AssistantPart, AssistantState, AssistantStep, AssistantStepState, AssistantTablePart, AssistantTextPart, AssistantTone, AssistantWidgetPart } from "./assistant/protocol.js";
42
- export { type Access, type AccessAction, type AccessContext, type AccessFn, type AccessResult, type AccessSource, type AccessUser, type ActionInputKind, type ActionInputModel, type ActionModel, type ActionRun, type AnyField, type AppAddress, type AssistantAction, type AssistantActionRequest, type AssistantCardPart, type AssistantDiff, type AssistantEvent, type AssistantMessage, type AssistantMessageRequest, type AssistantPart, type AssistantState, type AssistantStep, type AssistantStepState, type AssistantTablePart, type AssistantTextPart, type AssistantTone, type AssistantWidgetPart, type BadgeShape, type BottomBarItemModel, type BottomBarModel, type BottomBarNames, type BottomBarSource, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartInput, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CompareOp, type ComponentRef, type Constraint, type CreateModel, type CreatedOptions, type CustomSectionModel, type DatePreset, type DeletedOptions, type DurationLiteral, type DurationUnit, type EvaluateOptions, type EventActor, type EventContext, type EventHelpers, type EventMatch, type EventModel, type EventOperation, type EventSpec, type ExportModel, type Field, type FieldAccess, type FieldFormat, type FieldMeta, type FieldModel, type FieldPath, type FieldRefValue, type FieldRefs, type FieldRule, type FieldType, type FieldTypeDef, type FieldView, type FieldViewModel, type FieldViews, type FieldWidgetModel, type FieldsInput, type FileField, type FileFieldModel, type FileOptions, type FileProcessor, type FileProcessorInput, type FilterError, type FilterErrorCode, type FilterExpr, type FilterLayout, type FilterLimits, type FilterOf, type FilterParse, type FilterValue, type FilterWidgetModel, type GalleryModel, type Grant, type GroupChartInput, type GroupChartModel, type HeldCapability, type HelpWhen, type ImageFormat, type ImageVariant, type ImageVariantOptions, type InferRecord, type Issue, type JsonValue, type KeyOf, type KeyRefs, type KeyType, type KeyValue, type LayoutItemModel, type ListColumn, type ListDisplayModel, type ListModel, type ListQuery, type Literal, type MapSectionModel, type MapView, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type PeriodChartInput, type PeriodChartModel, type RecordKey, type RecordMode, type RecordOf, type Ref, type Refs, type RelatedColumnModel, type RelatedModel, type RelationField, type ResolveOptions, type ResolvedAccess, type ResourceBuilder, type ResourceModel, type RoleEntry, type RoleLimit, type Roles, type RolesOptions, type RowFilterOperation, type Rule, type SaveFeedback, type SaveSearchModel, type SearchMatch, type SearchRef, type SearchRefs, type SearchResultModel, type SearchesOfModel, type SectionPresentation, type ShowWhen, type SignInAddress, type SignInPromptModel, type SignInStep, type SignInViewModel, type SortSpec, type Span, type StatusTone, type UndeletedOptions, type UpdatedOptions, type UserMenuItemModel, type UserMenuModel, type UserMenuSource, type Validator, type ViewBuilder, type ViewModel, type ViewProps, accessWarnings, addressWords, anonymousRole, appPath, bottomBar, bottomBarErrors, checkFilter, checkOrderBy, checkRecord, createWhere, defineRoles, enumLabel, evaluateFilter, f, fieldRef, fieldsUsedBy, fitsKeyType, imageFormats, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
42
+ export { type Access, type AccessAction, type AccessContext, type AccessFn, type AccessResult, type AccessSource, type AccessUser, type ActionInputKind, type ActionInputModel, type ActionModel, type ActionRun, type AnyField, type AppAddress, type AssistantAction, type AssistantActionRequest, type AssistantCardPart, type AssistantDiff, type AssistantEvent, type AssistantMessage, type AssistantMessageRequest, type AssistantPart, type AssistantState, type AssistantStep, type AssistantStepState, type AssistantTablePart, type AssistantTextPart, type AssistantTone, type AssistantWidgetPart, type BadgeShape, type BottomBarItemModel, type BottomBarModel, type BottomBarNames, type BottomBarSource, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartInput, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CompareOp, type ComponentRef, type Constraint, type CreateModel, type CreatedOptions, type CustomSectionModel, type DatePreset, type DeletedOptions, type DurationLiteral, type DurationUnit, type EvaluateOptions, type EventActor, type EventContext, type EventHelpers, type EventMatch, type EventModel, type EventOperation, type EventSpec, type ExportModel, type Field, type FieldAccess, type FieldFormat, type FieldMeta, type FieldModel, type FieldPath, type FieldRefValue, type FieldRefs, type FieldRule, type FieldType, type FieldTypeDef, type FieldView, type FieldViewModel, type FieldViews, type FieldWidgetModel, type FieldsInput, type FileField, type FileFieldModel, type FileOptions, type FileProcessor, type FileProcessorInput, type FilterError, type FilterErrorCode, type FilterExpr, type FilterLayout, type FilterLimits, type FilterOf, type FilterParse, type FilterValue, type FilterWidgetModel, type GalleryModel, type Grant, type GroupChartInput, type GroupChartModel, type HeldCapability, type HelpWhen, type HistorySectionModel, type ImageFormat, type ImageVariant, type ImageVariantOptions, type InferRecord, type Issue, type JsonValue, type KeyOf, type KeyRefs, type KeyType, type KeyValue, type LayoutItemModel, type ListColumn, type ListDisplayModel, type ListModel, type ListQuery, type Literal, type MapSectionModel, type MapView, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type PeriodChartInput, type PeriodChartModel, type RecordKey, type RecordMode, type RecordOf, type Ref, type Refs, type RelatedColumnModel, type RelatedModel, type RelationField, type ResolveOptions, type ResolvedAccess, type ResourceBuilder, type ResourceModel, type RoleEntry, type RoleLimit, type Roles, type RolesOptions, type RowFilterOperation, type Rule, type SaveFeedback, type SaveSearchModel, type SearchMatch, type SearchRef, type SearchRefs, type SearchResultModel, type SearchesOfModel, type SectionPresentation, type ShowWhen, type SignInAddress, type SignInPromptModel, type SignInStep, type SignInViewModel, type SortSpec, type Span, type StatusTone, type UndeletedOptions, type UpdatedOptions, type UserMenuItemModel, type UserMenuModel, type UserMenuSource, type Validator, type ViewBuilder, type ViewModel, type ViewProps, accessWarnings, addressWords, anonymousRole, appPath, bottomBar, bottomBarErrors, checkFilter, checkOrderBy, checkRecord, createWhere, defineRoles, enumLabel, evaluateFilter, f, fieldRef, fieldsUsedBy, fitsKeyType, imageFormats, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
package/dist/layout.d.ts CHANGED
@@ -64,6 +64,15 @@ export declare const layout: {
64
64
  sidebar?: boolean;
65
65
  when?: ShowWhen;
66
66
  }) => LayoutItemModel;
67
+ /**
68
+ * The record's changes, newest first: who made each, when, and the fields before and after, only those the user may
69
+ * read. `limit` changes show before Show more (default 10). Needs `.history()` on the resource; a view without a
70
+ * layout shows it last by itself. See [Record history](website/src/content/docs/reference/history.mdx).
71
+ */
72
+ history: (title?: string, o?: {
73
+ limit?: number;
74
+ when?: ShowWhen;
75
+ }) => LayoutItemModel;
67
76
  /**
68
77
  * A component of the project, registered in `protobase.ui.tsx` under its name, drawn where it is listed: in the main
69
78
  * column, or in the sidebar with `sidebar: true`. The record page stays around it, with its title, breadcrumbs,
package/dist/layout.js CHANGED
@@ -80,6 +80,20 @@ const layout = {
80
80
  ...o.when !== void 0 && { when: o.when }
81
81
  }),
82
82
  /**
83
+ * The record's changes, newest first: who made each, when, and the fields before and after, only those the user may
84
+ * read. `limit` changes show before Show more (default 10). Needs `.history()` on the resource; a view without a
85
+ * layout shows it last by itself. See [Record history](website/src/content/docs/reference/history.mdx).
86
+ */
87
+ history: (title = "History", o = {}) => {
88
+ if (o.limit !== void 0 && (!Number.isInteger(o.limit) || o.limit < 1)) throw new Error(`l.history "${title}": limit must be a positive whole number`);
89
+ return {
90
+ kind: "history",
91
+ title,
92
+ ...o.limit !== void 0 && { limit: o.limit },
93
+ ...o.when !== void 0 && { when: o.when }
94
+ };
95
+ },
96
+ /**
83
97
  * A component of the project, registered in `protobase.ui.tsx` under its name, drawn where it is listed: in the main
84
98
  * column, or in the sidebar with `sidebar: true`. The record page stays around it, with its title, breadcrumbs,
85
99
  * actions and save; the component reads the record with `useLayoutRecord()`.
package/dist/model.d.ts CHANGED
@@ -96,6 +96,8 @@ export type ResourceModel = {
96
96
  owner?: string;
97
97
  /** The events its changes raise (`.events()`), the catalogue subscriptions pick from. */
98
98
  events?: EventModel[];
99
+ /** Whether every change of its records is kept, with who made it (`.history()`). */
100
+ history?: true;
99
101
  };
100
102
  /** What happened to a record: `delete` and `undelete` include setting and clearing a soft delete field. */
101
103
  export type EventOperation = 'create' | 'update' | 'delete' | 'undelete';
@@ -636,6 +638,20 @@ export type MapSectionModel = {
636
638
  /** Whether it shows on the form, the read view or both. */
637
639
  when?: ShowWhen;
638
640
  };
641
+ /**
642
+ * The record's changes, newest first, with who made each and the fields before and after: only fields the caller may
643
+ * read. Needs `.history()` on the resource. See [Record history](website/src/content/docs/reference/history.mdx).
644
+ */
645
+ export type HistorySectionModel = {
646
+ /** A history section. */
647
+ kind: 'history';
648
+ /** The section's title. */
649
+ title: string;
650
+ /** How many changes it shows before Show more; 10 when omitted. */
651
+ limit?: number;
652
+ /** Whether it shows on the form, the read view or both. */
653
+ when?: ShowWhen;
654
+ };
639
655
  /** How a section shows its fields on the read view: `facts` as a row of key facts; label/value rows when omitted. */
640
656
  export type SectionPresentation = 'facts';
641
657
  /** An item of the record page (`.layout((r) => ...)` with `l`); see [The record page](website/src/content/docs/reference/ui-config.mdx#the-record-page). */
@@ -664,7 +680,7 @@ export type LayoutItemModel = {
664
680
  fields: string[];
665
681
  /** Whether it shows on the form, the read view or both. */
666
682
  when?: ShowWhen;
667
- } | RelatedModel | CustomSectionModel | MapSectionModel | GalleryModel;
683
+ } | RelatedModel | CustomSectionModel | MapSectionModel | GalleryModel | HistorySectionModel;
668
684
  /**
669
685
  * A record's photos as tiles in the main column under `title`, one large and the next few smaller, opening a lightbox
670
686
  * that steps through them all: first the record's own file field `image`, then the `image` of the records of
@@ -13,5 +13,6 @@ export type ResourceState = {
13
13
  searchMatch?: Record<string, SearchMatch>;
14
14
  owner?: string;
15
15
  events?: EventSpec[];
16
+ history?: boolean;
16
17
  };
17
18
  //#endregion
@@ -57,7 +57,8 @@ const assembleModel = (state) => {
57
57
  ...state.tenant && { tenant: state.tenant },
58
58
  ...state.search && { search: [...state.search] },
59
59
  ...state.searchMatch && Object.keys(state.searchMatch).length > 0 && { searchMatch: { ...state.searchMatch } },
60
- ...state.owner && { owner: state.owner }
60
+ ...state.owner && { owner: state.owner },
61
+ ...state.history && { history: true }
61
62
  };
62
63
  };
63
64
  const sensitiveProblems = (model) => Object.values(model.fields).filter((field) => field.sensitive).flatMap((field) => [
@@ -83,6 +83,12 @@ export declare class ResourceBuilder<F extends FieldsInput = {}, K = never> {
83
83
  * ```
84
84
  */
85
85
  events(define: (e: EventHelpers<RecordOf<F>>, r: FieldRefs<F>) => EventSpec[]): ResourceBuilder<F, K>;
86
+ /**
87
+ * Keeps every change of its records, from the API or elsewhere: the fields before and after, and who made it. The
88
+ * record page shows it as History, and admins list every change as Activity. See
89
+ * [Record history](website/src/content/docs/reference/history.mdx).
90
+ */
91
+ history(): ResourceBuilder<F, K>;
86
92
  /** The code predicates (`match`) of its events, by event name. */
87
93
  eventMatches(): Record<string, EventMatch<any>>;
88
94
  /**
package/dist/resource.js CHANGED
@@ -94,6 +94,14 @@ var ResourceBuilder = class ResourceBuilder {
94
94
  events(define) {
95
95
  return this.next({ events: define(eventHelpers(), this.refs()) });
96
96
  }
97
+ /**
98
+ * Keeps every change of its records, from the API or elsewhere: the fields before and after, and who made it. The
99
+ * record page shows it as History, and admins list every change as Activity. See
100
+ * [Record history](website/src/content/docs/reference/history.mdx).
101
+ */
102
+ history() {
103
+ return this.next({ history: true });
104
+ }
97
105
  /** The code predicates (`match`) of its events, by event name. */
98
106
  eventMatches() {
99
107
  return eventMatches(this.toModel(), this.state.events ?? []);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protobase/schema",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Resource, field, view and access definitions for Protobase configs.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {