@object-ui/data-objectstack 17.1.0 → 17.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,130 @@
1
1
  # @object-ui/data-objectstack
2
2
 
3
+ ## 17.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c5ccbd5: Stop declaring 12 `@object-ui/data-objectstack` / `@object-ui/plugin-chatbot` /
8
+ `@object-ui/plugin-list` symbols under names `@objectstack/spec` owns
9
+ (objectui#3160, objectstack#4115 batch 6). All three packages leave the ledger.
10
+
11
+ **Breaking for importers of `@object-ui/data-objectstack`** — four exported
12
+ names changed, because the spec exports the same name for a _different_ thing:
13
+
14
+ | was | now | what the spec's same-named export actually is |
15
+ | :-------------------- | :-------------------------- | :--------------------------------------------------------------------------------------- |
16
+ | `CacheStats` | `MetadataCacheStats` | the platform `ICacheService` counters (`keyCount`, `memoryUsage`) |
17
+ | `MetadataSaveOptions` | `MetadataClientSaveOptions` | options for writing a metadata item to a **file** (`format`, `path`, `indent`, `atomic`) |
18
+ | `SecurityPolicy` | `SecurityManagerPolicy` | the package supply-chain policy (`autoScan`, licences, code signing, sandbox) |
19
+ | `ValidationError` | `DataApiValidationError` | a plain `{ field, message, code? }` entry in a validation report |
20
+
21
+ Each pair is disjoint or nearly so — `MetadataSaveOptions` and `SecurityPolicy`
22
+ share not one key with the spec type whose name they wore — so none of them was
23
+ a dialect to reconcile; they were four unrelated concepts squatting on spec
24
+ names. `DataApiValidationError` follows the `<what was validated>Validation<Error|Result>`
25
+ convention registered on objectstack#4115 (`@object-ui/core` took
26
+ `SchemaNodeValidationError` in batch 4). Its **runtime** `name` deliberately
27
+ stays `'ValidationError'`: `normaliseClientError` and `@object-ui/react`'s
28
+ error-message helper both sniff `err.name`, so that string is a wire contract,
29
+ not a symbol.
30
+
31
+ **Breaking for importers of `@object-ui/plugin-chatbot`** — `PendingActionRow`
32
+ and `PendingActionStatus` are now re-exported from `@objectstack/spec/contracts`
33
+ instead of hand-transcribed, which narrows them. The copies had drifted three
34
+ ways, and each drift had **disabled a compile-time check** rather than merely
35
+ differed from one:
36
+
37
+ - `status: PendingActionStatus | string` — a union with `string` absorbs the
38
+ literals, so that annotation carried no information at all;
39
+ - `[key: string]: unknown` — the objectstack#4075 mechanism: an index signature
40
+ makes every structural comparison against the spec answer "identical", however
41
+ far the copy has drifted;
42
+ - `created_at` / `updated_at`, which the service contract does not carry and no
43
+ consumer in this repo reads.
44
+
45
+ **Breaking for importers of `@object-ui/plugin-list`** — `ViewTab` is derived from the spec's `ViewTabSchema`
46
+ — from its **input** side, because `pinned` / `isDefault` / `visible` carry
47
+ `.default()`s and this component is handed authored metadata, not parsed output.
48
+ That removes a renderer-side tolerance the copy carried: `visible` accepted
49
+ `string | boolean` and the tab bar compared it against the literal `'false'`, a
50
+ spelling no producer emits. `label` also stops being required (the spec makes it
51
+ optional; `name` is the identifier) and `filter` stops being `any`.
52
+
53
+ `ListView` and `UserFilters` keep their names as declared dialects: both are the
54
+ React **renderers** of the spec types whose names they share, and each takes that
55
+ spec type as a prop (`ListViewProps.schema`, `UserFiltersProps.config`) rather
56
+ than restating its shape. `Tool` and `MessageContent` in `plugin-chatbot` are
57
+ vendored Vercel AI Elements / Shadcn primitives — upstream's component API, not
58
+ objectui's authored surface — so the guard now skips that directory the same way
59
+ it already skips `components/src/ui/`, with a test that fails if any file there
60
+ stops carrying its vendor banner.
61
+
62
+ Scored `minor`, not `major`, per this repo's fixed-group rule — objectui's major
63
+ tracks `@objectstack`, so breaking changes of our own ship as minor with the
64
+ semantics spelled out above (see AGENTS.md §版本号策略). A `major` here would carry
65
+ all 39 packages of the fixed group to `18.0.0` and off objectstack's 17.x line.
66
+
67
+ - d3584c6: Bring the whole `@objectstack` family to `17.0.0-rc.1`, so the dependency graph resolves a
68
+ single copy of `@objectstack/spec`.
69
+
70
+ #3178 bumped **only** `@objectstack/spec` to `17.0.0-rc.1`. The rest of the family —
71
+ `client`, `core`, `formula`, `lint` (and `sdui-parser`, reached through `lint`) — stayed on
72
+ `17.0.0-rc.0`, and each of them depends on spec at an **exact** version rather than a
73
+ caret:
74
+
75
+ ```
76
+ @objectstack/client@17.0.0-rc.0 -> spec "17.0.0-rc.0"
77
+ @objectstack/core@17.0.0-rc.0 -> spec "17.0.0-rc.0"
78
+ @objectstack/formula@17.0.0-rc.0 -> spec "17.0.0-rc.0"
79
+ @objectstack/lint@17.0.0-rc.0 -> spec "17.0.0-rc.0"
80
+ ```
81
+
82
+ So `main` carried **two** spec copies: objectui's own code read `17.0.0-rc.1` while every
83
+ `@objectstack/*` package read `17.0.0-rc.0` from its own nested `node_modules`. That breaks
84
+ the single-contract invariant this repo's guards are built on, and it breaks them
85
+ _silently_ — the affected checks depend on identity, not on version strings:
86
+
87
+ - `spec-subschema-parity.test.ts` distinguishes a genuine re-export from a fork by
88
+ **reference identity** of the zod schema object. Two spec copies make every schema a
89
+ distinct object, so a real re-export starts reading as a fork (or a fork slips through,
90
+ depending on which copy each side resolved).
91
+ - `scripts/check-spec-symbol-derivation.mjs` and `spec-symbol-parity.test.ts` use
92
+ `createRequire` to resolve spec's `.d.ts` and run it through the TS checker. With two
93
+ copies installed, _which_ declaration file the checker sees is a function of resolution
94
+ order rather than of intent.
95
+
96
+ The declared ranges were already `^17.0.0-rc.0`, which technically admits rc.1 — the pin
97
+ lived in the lockfile. Raising the remaining ranges to `^17.0.0-rc.1` makes the floor
98
+ explicit and forbids a future install from silently sliding back onto a family member that
99
+ drags rc.0 along with it. The rc.1 family members pin spec at `17.0.0-rc.1` exactly, so the
100
+ graph now converges on one copy by construction, not by luck.
101
+
102
+ No product behaviour changes here. `check:spec-symbols` reconciliation was already
103
+ completed by #3178 and stays green under the unified graph; this changeset is `minor`
104
+ per the repo's fixed-group version policy.
105
+
106
+ ### Patch Changes
107
+
108
+ - Updated dependencies [4ae0ac4]
109
+ - Updated dependencies [696e3c1]
110
+ - Updated dependencies [bca45cc]
111
+ - Updated dependencies [4bf612c]
112
+ - Updated dependencies [335041c]
113
+ - Updated dependencies [b414983]
114
+ - Updated dependencies [256f8cc]
115
+ - Updated dependencies [d9668a7]
116
+ - Updated dependencies [cb82705]
117
+ - Updated dependencies [f572849]
118
+ - Updated dependencies [d3584c6]
119
+ - Updated dependencies [a8ad6c0]
120
+ - Updated dependencies [444457c]
121
+ - Updated dependencies [850033c]
122
+ - Updated dependencies [022e4c3]
123
+ - Updated dependencies [009e25d]
124
+ - Updated dependencies [726b89c]
125
+ - @object-ui/types@17.2.0
126
+ - @object-ui/core@17.2.0
127
+
3
128
  ## 17.1.0
4
129
 
5
130
  ### Minor Changes
package/README.md CHANGED
@@ -179,7 +179,12 @@ import {
179
179
  BulkOperationError, // Bulk operation failures with partial results
180
180
  ConnectionError, // Network/connection errors (503/504)
181
181
  AuthenticationError, // Authentication failures (401/403)
182
- ValidationError, // Data validation errors (400)
182
+ DataApiValidationError, // Data validation errors (400). Its runtime `name` is
183
+ // still 'ValidationError' — that string is the wire
184
+ // discriminator shared with @objectstack/client. The
185
+ // SYMBOL is prefixed because @objectstack/spec/kernel
186
+ // owns `ValidationError` for a { field, message, code? }
187
+ // record (objectui#3160).
183
188
  } from '@object-ui/data-objectstack';
184
189
  ```
185
190
 
package/dist/index.cjs CHANGED
@@ -29,6 +29,7 @@ __export(index_exports, {
29
29
  CloudOperations: () => CloudOperations,
30
30
  ConcurrentUpdateError: () => ConcurrentUpdateError,
31
31
  ConnectionError: () => ConnectionError,
32
+ DataApiValidationError: () => DataApiValidationError,
32
33
  FILTER_OPERATOR_ALIASES: () => FILTER_OPERATOR_ALIASES,
33
34
  IntegrationManager: () => IntegrationManager,
34
35
  MalformedFilterError: () => MalformedFilterError,
@@ -37,7 +38,6 @@ __export(index_exports, {
37
38
  ObjectStackAdapter: () => ObjectStackAdapter,
38
39
  ObjectStackError: () => ObjectStackError,
39
40
  SecurityManager: () => SecurityManager,
40
- ValidationError: () => ValidationError,
41
41
  calculateAutoLayout: () => calculateAutoLayout,
42
42
  classifyAnalyticsFailure: () => classifyAnalyticsFailure,
43
43
  clearSharedDiscoveryCache: () => clearSharedDiscoveryCache,
@@ -933,10 +933,10 @@ var AuthenticationError = class extends ObjectStackError {
933
933
  this.name = "AuthenticationError";
934
934
  }
935
935
  };
936
- var ValidationError = class extends ObjectStackError {
936
+ var DataApiValidationError = class extends ObjectStackError {
937
937
  /**
938
- * Create a new ValidationError
939
- *
938
+ * Create a new DataApiValidationError
939
+ *
940
940
  * @param message - Human-readable error message
941
941
  * @param field - The field that failed validation (optional)
942
942
  * @param validationErrors - Array of validation error details
@@ -987,7 +987,7 @@ function createErrorFromResponse(response, context) {
987
987
  }
988
988
  return new ObjectStackError(message, "NOT_FOUND", 404, details);
989
989
  case 400:
990
- return new ValidationError(message, void 0, response?.data?.errors, details);
990
+ return new DataApiValidationError(message, void 0, response?.data?.errors, details);
991
991
  case 503:
992
992
  return new ConnectionError(message, response?.config?.url, details, 503);
993
993
  case 504:
@@ -1700,7 +1700,7 @@ function normaliseClientError(error) {
1700
1700
  const message = typeof rec.message === "string" && rec.message.trim() ? rec.message : typeof rec.code === "string" ? rec.code : "";
1701
1701
  return { field, message };
1702
1702
  }).filter((x) => x !== null);
1703
- return new ValidationError(
1703
+ return new DataApiValidationError(
1704
1704
  typeof e.message === "string" ? e.message : "Validation failed",
1705
1705
  validationErrors[0]?.field,
1706
1706
  validationErrors,
@@ -3736,6 +3736,7 @@ function createObjectStackAdapter(config) {
3736
3736
  CloudOperations,
3737
3737
  ConcurrentUpdateError,
3738
3738
  ConnectionError,
3739
+ DataApiValidationError,
3739
3740
  FILTER_OPERATOR_ALIASES,
3740
3741
  IntegrationManager,
3741
3742
  MalformedFilterError,
@@ -3744,7 +3745,6 @@ function createObjectStackAdapter(config) {
3744
3745
  ObjectStackAdapter,
3745
3746
  ObjectStackError,
3746
3747
  SecurityManager,
3747
- ValidationError,
3748
3748
  calculateAutoLayout,
3749
3749
  classifyAnalyticsFailure,
3750
3750
  clearSharedDiscoveryCache,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { ObjectStackClient } from '@objectstack/client';
2
+ import { DroppedFieldsEvent } from '@objectstack/spec/data';
3
+ export { DroppedFieldsEvent } from '@objectstack/spec/data';
2
4
  import { DataSource, QueryParams, QueryResult, GlobalSearchResult, DataSourceMutationEvent, BatchTransactionOperation, ImportRequestOptions, ImportRecordsResult, CreateImportJobResult, ImportJobProgressInfo, ImportJobResultsInfo, ListImportJobsOptions, ImportJobSummaryInfo, ImportJobUndoResult, ExportDownloadRequest, FileUploadResult } from '@object-ui/types';
3
5
  export { FileUploadResult } from '@object-ui/types';
4
6
 
@@ -95,16 +97,28 @@ declare class AuthenticationError extends ObjectStackError {
95
97
  constructor(message?: string, details?: Record<string, unknown>, statusCode?: number);
96
98
  }
97
99
  /**
98
- * Error thrown when data validation fails
100
+ * Error thrown when the ObjectStack data API rejects a write as invalid.
101
+ *
102
+ * NOT the spec's `ValidationError` (`@objectstack/spec/kernel`), whose name this
103
+ * class wore until objectui#3160 (objectstack#4115 ledger batch 6). That one is
104
+ * a plain DATA SHAPE — `{ field, message, code? }`, one entry in a plugin
105
+ * manifest's validation report — and `@object-ui/types` re-exports it under that
106
+ * name. This is a runtime `Error` subclass carrying an HTTP status plus a list
107
+ * of such entries, so the two are not even the same KIND of thing.
108
+ *
109
+ * The name follows the convention registered on objectstack#4115 for this
110
+ * family — `<what was validated>Validation<Error|Result>`. `@object-ui/core`
111
+ * took `SchemaNodeValidationError` for its SDUI-tree walk; this one belongs to
112
+ * the data API.
99
113
  */
100
- declare class ValidationError extends ObjectStackError {
114
+ declare class DataApiValidationError extends ObjectStackError {
101
115
  field?: string | undefined;
102
116
  validationErrors?: Array<{
103
117
  field: string;
104
118
  message: string;
105
119
  }> | undefined;
106
120
  /**
107
- * Create a new ValidationError
121
+ * Create a new DataApiValidationError
108
122
  *
109
123
  * @param message - Human-readable error message
110
124
  * @param field - The field that failed validation (optional)
@@ -148,9 +162,18 @@ declare function isErrorType<T extends ObjectStackError>(error: unknown, errorCl
148
162
  * LICENSE file in the root directory of this source tree.
149
163
  */
150
164
  /**
151
- * Cache statistics for monitoring
165
+ * Statistics reported by {@link MetadataCache.getStats} for monitoring.
166
+ *
167
+ * NOT the spec's `CacheStats` (`@objectstack/spec/contracts`), whose name this
168
+ * interface wore until objectui#3160 (objectstack#4115 ledger batch 6). That one
169
+ * describes the platform's `ICacheService` — a server-side KV cache measured by
170
+ * `keyCount` and `memoryUsage`. This one describes the browser-side LRU in front
171
+ * of `/api/v1/meta/*`: it is bounded (`size`/`maxSize`), it evicts, it coalesces
172
+ * concurrent fetches onto one in-flight promise, and it reports a `hitRate`.
173
+ * Neither type has a key the other has, so this is a name collision, not a
174
+ * dialect — deriving would have replaced every field.
152
175
  */
153
- interface CacheStats {
176
+ interface MetadataCacheStats {
154
177
  size: number;
155
178
  maxSize: number;
156
179
  hits: number;
@@ -563,7 +586,21 @@ interface MetadataDraftHeader {
563
586
  updatedAt: string | null;
564
587
  updatedBy: string | null;
565
588
  }
566
- interface MetadataSaveOptions {
589
+ /**
590
+ * Options for {@link MetadataClient.save} — a WRITE OVER HTTP to
591
+ * `/api/v1/meta/:type/:name`.
592
+ *
593
+ * NOT the spec's `MetadataSaveOptions` (`@objectstack/spec/system` and
594
+ * `/kernel`), whose name this interface wore until objectui#3160
595
+ * (objectstack#4115 ledger batch 6). Both spec copies describe writing a
596
+ * metadata item to a FILE — `format: json|yaml|ts`, `path`, `indent`,
597
+ * `prettify`, `sortKeys`, `backup`, `atomic`, `loader`. Not one of those keys
598
+ * exists here, and not one of these exists there: this is the REST client's
599
+ * request envelope — optimistic concurrency (`ifMatch` → `If-Match`), actor
600
+ * attribution, the destructive-change override, the ADR-0033 draft/publish
601
+ * mode, and the owning package. Same words, different layer.
602
+ */
603
+ interface MetadataClientSaveOptions {
567
604
  /**
568
605
  * Optimistic concurrency token (the `checksum` returned by the last
569
606
  * read). When present, sent as the `If-Match` header so concurrent
@@ -608,7 +645,7 @@ interface MetadataGetOptions {
608
645
  */
609
646
  packageId?: string;
610
647
  }
611
- interface MetadataDeleteOptions extends MetadataSaveOptions {
648
+ interface MetadataDeleteOptions extends MetadataClientSaveOptions {
612
649
  /**
613
650
  * Target state. `'draft'` discards the pending draft (keeps the
614
651
  * published overlay intact). Omit to reset the active overlay back
@@ -847,7 +884,7 @@ declare class MetadataClient {
847
884
  * envelopes; we send bare for consistency. Pass `mode: 'draft'` to
848
885
  * stage the change without publishing (Studio's "Save" button).
849
886
  */
850
- save<T = unknown>(type: string, name: string, item: unknown, options?: MetadataSaveOptions): Promise<T>;
887
+ save<T = unknown>(type: string, name: string, item: unknown, options?: MetadataClientSaveOptions): Promise<T>;
851
888
  /**
852
889
  * Publish a single pending draft BY REFERENCE — promotes the draft row for
853
890
  * `(type, name)` into the active overlay and drops the draft. Works for ANY
@@ -957,7 +994,20 @@ declare class MetadataClient {
957
994
  * Security module integration for @objectstack/spec v3.0.0
958
995
  * Provides advanced security policies: CSP config, audit logging, data masking.
959
996
  */
960
- interface SecurityPolicy {
997
+ /**
998
+ * Configuration for {@link SecurityManager} — this adapter's browser-side
999
+ * security posture: the CSP header it generates, the in-memory audit log it
1000
+ * keeps, and the field-masking rules it applies before a record is rendered.
1001
+ *
1002
+ * NOT the spec's `SecurityPolicy` (`@objectstack/spec/kernel`), whose name this
1003
+ * interface wore until objectui#3160 (objectstack#4115 ledger batch 6). That one
1004
+ * is the PACKAGE SUPPLY-CHAIN policy — `{ id, name, autoScan, thresholds,
1005
+ * allowedLicenses, prohibitedLicenses, codeSigning, sandbox }` — the rules a
1006
+ * marketplace applies when scanning a plugin before install. It shares no key
1007
+ * with this one, so there was nothing to derive; the collision is the word
1008
+ * "security", not the concept.
1009
+ */
1010
+ interface SecurityManagerPolicy {
961
1011
  /** Content Security Policy configuration */
962
1012
  csp?: CSPConfig;
963
1013
  /** Audit logging configuration */
@@ -1031,7 +1081,7 @@ interface AuditLogEntry {
1031
1081
  declare class SecurityManager {
1032
1082
  private policy;
1033
1083
  private auditLog;
1034
- constructor(policy?: SecurityPolicy);
1084
+ constructor(policy?: SecurityManagerPolicy);
1035
1085
  /**
1036
1086
  * Generate a CSP header string from the configuration.
1037
1087
  */
@@ -1055,11 +1105,11 @@ declare class SecurityManager {
1055
1105
  /**
1056
1106
  * Update the security policy.
1057
1107
  */
1058
- updatePolicy(policy: Partial<SecurityPolicy>): void;
1108
+ updatePolicy(policy: Partial<SecurityManagerPolicy>): void;
1059
1109
  /**
1060
1110
  * Get current security policy.
1061
1111
  */
1062
- getPolicy(): SecurityPolicy;
1112
+ getPolicy(): SecurityManagerPolicy;
1063
1113
  }
1064
1114
 
1065
1115
  /**
@@ -1379,7 +1429,7 @@ declare function isConcurrentUpdateError(error: unknown): error is ConcurrentUpd
1379
1429
  *
1380
1430
  * Two shapes are recognised:
1381
1431
  * - `409` + `CONCURRENT_UPDATE` → {@link ConcurrentUpdateError};
1382
- * - `400` + `VALIDATION_FAILED` → {@link ValidationError}, carrying the
1432
+ * - `400` + `VALIDATION_FAILED` → {@link DataApiValidationError}, carrying the
1383
1433
  * server's per-field entries so a form can mark the offending inputs
1384
1434
  * instead of showing one undirected toast.
1385
1435
  */
@@ -1414,19 +1464,7 @@ type ConnectionStateListener = (event: ConnectionStateEvent) => void;
1414
1464
  * Event listener type for batch operation progress
1415
1465
  */
1416
1466
  type BatchProgressListener = (event: BatchProgressEvent) => void;
1417
- /**
1418
- * One server-reported write-strip: caller-supplied fields the backend LEGALLY
1419
- * removed from a write before persisting (a non-system caller cannot seed a
1420
- * `readonly` field, a `readonlyWhen` predicate locked it, etc.). Mirrors the
1421
- * framework `DroppedFieldsEvent` (spec `DroppedFieldsEventSchema`) structurally
1422
- * so we don't pin a client type version — `reason` is kept as a widened string
1423
- * for forward-compatibility with reasons added server-side.
1424
- */
1425
- interface DroppedFieldsEvent {
1426
- object: string;
1427
- fields: string[];
1428
- reason: string;
1429
- }
1467
+
1430
1468
  /**
1431
1469
  * Emitted after a create/update whose response carried `droppedFields`
1432
1470
  * (framework #3431/#3455). The write SUCCEEDED — this is a warning that some
@@ -2085,7 +2123,7 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
2085
2123
  /**
2086
2124
  * Get cache statistics for monitoring performance.
2087
2125
  */
2088
- getCacheStats(): CacheStats;
2126
+ getCacheStats(): MetadataCacheStats;
2089
2127
  /**
2090
2128
  * Invalidate metadata cache entries.
2091
2129
  *
@@ -2173,4 +2211,4 @@ declare function createObjectStackAdapter<T = unknown>(config: {
2173
2211
  reconnectDelay?: number;
2174
2212
  }): DataSource<T>;
2175
2213
 
2176
- export { AnalyticsNotInstalledError, AnalyticsQueryRejectedError, type AuditEventType, type AuditLogConfig, type AuditLogEntry, AuthenticationError, type BatchProgressEvent, type BatchProgressListener, BulkOperationError, type CSPConfig, type CacheStats, type CloudDeploymentConfig, type CloudHostingConfig, type CloudMarketplaceEntry, CloudOperations, ConcurrentUpdateError, ConnectionError, type ConnectionState, type ConnectionStateEvent, type ConnectionStateListener, type ContractValidationError, type ContractValidationResult, type DataMaskingConfig, type DataMaskingRule, type DroppedFieldsEvent, type EmailIntegrationConfig, FILTER_OPERATOR_ALIASES, type IntegrationConfig, IntegrationManager, type IntegrationProvider, type IntegrationTrigger, MalformedFilterError, type MetadataAuditEntry, type MetadataAuditResponse, MetadataClient, type MetadataClientConfig, type MetadataDeleteOptions, type MetadataDiagnostics, type MetadataDiagnosticsEntry, type MetadataDiagnosticsOptions, type MetadataDiagnosticsSummary, type MetadataDraftHeader, type MetadataError, type MetadataGetOptions, type MetadataHistoryOptions, type MetadataLayered, type MetadataListOptions, MetadataNotFoundError, type MetadataReference, type MetadataSaveOptions, type MetadataValidationIssue, ObjectStackAdapter, ObjectStackError, type ObjectStackUserStateAdapterOptions, type PluginAPIContract, type PluginContract, type PluginExport, SecurityManager, type SecurityPolicy, type SlackIntegrationConfig, type StudioCanvasConfig, type StudioColorPalette, type StudioPropertyEditor, type StudioShadowPreset, type StudioThemeBuilderConfig, type StudioTypographyPreset, type UserDataAdapter, ValidationError, type WebhookIntegrationConfig, type WriteWarningEvent, type WriteWarningListener, calculateAutoLayout, classifyAnalyticsFailure, clearSharedDiscoveryCache, createDefaultCanvasConfig, createErrorFromResponse, createObjectStackAdapter, createObjectStackUserStateAdapter, generateContractManifest, getSharedDiscovery, is404Error, isAnalyticsNotInstalledError, isConcurrentUpdateError, isErrorType, isMalformedFilterError, isObjectStackError, normaliseClientError, readTransactionalBatchCapability, serializeOrderBy, snapToGrid, validatePluginContract };
2214
+ export { AnalyticsNotInstalledError, AnalyticsQueryRejectedError, type AuditEventType, type AuditLogConfig, type AuditLogEntry, AuthenticationError, type BatchProgressEvent, type BatchProgressListener, BulkOperationError, type CSPConfig, type CloudDeploymentConfig, type CloudHostingConfig, type CloudMarketplaceEntry, CloudOperations, ConcurrentUpdateError, ConnectionError, type ConnectionState, type ConnectionStateEvent, type ConnectionStateListener, type ContractValidationError, type ContractValidationResult, DataApiValidationError, type DataMaskingConfig, type DataMaskingRule, type EmailIntegrationConfig, FILTER_OPERATOR_ALIASES, type IntegrationConfig, IntegrationManager, type IntegrationProvider, type IntegrationTrigger, MalformedFilterError, type MetadataAuditEntry, type MetadataAuditResponse, type MetadataCacheStats, MetadataClient, type MetadataClientConfig, type MetadataClientSaveOptions, type MetadataDeleteOptions, type MetadataDiagnostics, type MetadataDiagnosticsEntry, type MetadataDiagnosticsOptions, type MetadataDiagnosticsSummary, type MetadataDraftHeader, type MetadataError, type MetadataGetOptions, type MetadataHistoryOptions, type MetadataLayered, type MetadataListOptions, MetadataNotFoundError, type MetadataReference, type MetadataValidationIssue, ObjectStackAdapter, ObjectStackError, type ObjectStackUserStateAdapterOptions, type PluginAPIContract, type PluginContract, type PluginExport, SecurityManager, type SecurityManagerPolicy, type SlackIntegrationConfig, type StudioCanvasConfig, type StudioColorPalette, type StudioPropertyEditor, type StudioShadowPreset, type StudioThemeBuilderConfig, type StudioTypographyPreset, type UserDataAdapter, type WebhookIntegrationConfig, type WriteWarningEvent, type WriteWarningListener, calculateAutoLayout, classifyAnalyticsFailure, clearSharedDiscoveryCache, createDefaultCanvasConfig, createErrorFromResponse, createObjectStackAdapter, createObjectStackUserStateAdapter, generateContractManifest, getSharedDiscovery, is404Error, isAnalyticsNotInstalledError, isConcurrentUpdateError, isErrorType, isMalformedFilterError, isObjectStackError, normaliseClientError, readTransactionalBatchCapability, serializeOrderBy, snapToGrid, validatePluginContract };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { ObjectStackClient } from '@objectstack/client';
2
+ import { DroppedFieldsEvent } from '@objectstack/spec/data';
3
+ export { DroppedFieldsEvent } from '@objectstack/spec/data';
2
4
  import { DataSource, QueryParams, QueryResult, GlobalSearchResult, DataSourceMutationEvent, BatchTransactionOperation, ImportRequestOptions, ImportRecordsResult, CreateImportJobResult, ImportJobProgressInfo, ImportJobResultsInfo, ListImportJobsOptions, ImportJobSummaryInfo, ImportJobUndoResult, ExportDownloadRequest, FileUploadResult } from '@object-ui/types';
3
5
  export { FileUploadResult } from '@object-ui/types';
4
6
 
@@ -95,16 +97,28 @@ declare class AuthenticationError extends ObjectStackError {
95
97
  constructor(message?: string, details?: Record<string, unknown>, statusCode?: number);
96
98
  }
97
99
  /**
98
- * Error thrown when data validation fails
100
+ * Error thrown when the ObjectStack data API rejects a write as invalid.
101
+ *
102
+ * NOT the spec's `ValidationError` (`@objectstack/spec/kernel`), whose name this
103
+ * class wore until objectui#3160 (objectstack#4115 ledger batch 6). That one is
104
+ * a plain DATA SHAPE — `{ field, message, code? }`, one entry in a plugin
105
+ * manifest's validation report — and `@object-ui/types` re-exports it under that
106
+ * name. This is a runtime `Error` subclass carrying an HTTP status plus a list
107
+ * of such entries, so the two are not even the same KIND of thing.
108
+ *
109
+ * The name follows the convention registered on objectstack#4115 for this
110
+ * family — `<what was validated>Validation<Error|Result>`. `@object-ui/core`
111
+ * took `SchemaNodeValidationError` for its SDUI-tree walk; this one belongs to
112
+ * the data API.
99
113
  */
100
- declare class ValidationError extends ObjectStackError {
114
+ declare class DataApiValidationError extends ObjectStackError {
101
115
  field?: string | undefined;
102
116
  validationErrors?: Array<{
103
117
  field: string;
104
118
  message: string;
105
119
  }> | undefined;
106
120
  /**
107
- * Create a new ValidationError
121
+ * Create a new DataApiValidationError
108
122
  *
109
123
  * @param message - Human-readable error message
110
124
  * @param field - The field that failed validation (optional)
@@ -148,9 +162,18 @@ declare function isErrorType<T extends ObjectStackError>(error: unknown, errorCl
148
162
  * LICENSE file in the root directory of this source tree.
149
163
  */
150
164
  /**
151
- * Cache statistics for monitoring
165
+ * Statistics reported by {@link MetadataCache.getStats} for monitoring.
166
+ *
167
+ * NOT the spec's `CacheStats` (`@objectstack/spec/contracts`), whose name this
168
+ * interface wore until objectui#3160 (objectstack#4115 ledger batch 6). That one
169
+ * describes the platform's `ICacheService` — a server-side KV cache measured by
170
+ * `keyCount` and `memoryUsage`. This one describes the browser-side LRU in front
171
+ * of `/api/v1/meta/*`: it is bounded (`size`/`maxSize`), it evicts, it coalesces
172
+ * concurrent fetches onto one in-flight promise, and it reports a `hitRate`.
173
+ * Neither type has a key the other has, so this is a name collision, not a
174
+ * dialect — deriving would have replaced every field.
152
175
  */
153
- interface CacheStats {
176
+ interface MetadataCacheStats {
154
177
  size: number;
155
178
  maxSize: number;
156
179
  hits: number;
@@ -563,7 +586,21 @@ interface MetadataDraftHeader {
563
586
  updatedAt: string | null;
564
587
  updatedBy: string | null;
565
588
  }
566
- interface MetadataSaveOptions {
589
+ /**
590
+ * Options for {@link MetadataClient.save} — a WRITE OVER HTTP to
591
+ * `/api/v1/meta/:type/:name`.
592
+ *
593
+ * NOT the spec's `MetadataSaveOptions` (`@objectstack/spec/system` and
594
+ * `/kernel`), whose name this interface wore until objectui#3160
595
+ * (objectstack#4115 ledger batch 6). Both spec copies describe writing a
596
+ * metadata item to a FILE — `format: json|yaml|ts`, `path`, `indent`,
597
+ * `prettify`, `sortKeys`, `backup`, `atomic`, `loader`. Not one of those keys
598
+ * exists here, and not one of these exists there: this is the REST client's
599
+ * request envelope — optimistic concurrency (`ifMatch` → `If-Match`), actor
600
+ * attribution, the destructive-change override, the ADR-0033 draft/publish
601
+ * mode, and the owning package. Same words, different layer.
602
+ */
603
+ interface MetadataClientSaveOptions {
567
604
  /**
568
605
  * Optimistic concurrency token (the `checksum` returned by the last
569
606
  * read). When present, sent as the `If-Match` header so concurrent
@@ -608,7 +645,7 @@ interface MetadataGetOptions {
608
645
  */
609
646
  packageId?: string;
610
647
  }
611
- interface MetadataDeleteOptions extends MetadataSaveOptions {
648
+ interface MetadataDeleteOptions extends MetadataClientSaveOptions {
612
649
  /**
613
650
  * Target state. `'draft'` discards the pending draft (keeps the
614
651
  * published overlay intact). Omit to reset the active overlay back
@@ -847,7 +884,7 @@ declare class MetadataClient {
847
884
  * envelopes; we send bare for consistency. Pass `mode: 'draft'` to
848
885
  * stage the change without publishing (Studio's "Save" button).
849
886
  */
850
- save<T = unknown>(type: string, name: string, item: unknown, options?: MetadataSaveOptions): Promise<T>;
887
+ save<T = unknown>(type: string, name: string, item: unknown, options?: MetadataClientSaveOptions): Promise<T>;
851
888
  /**
852
889
  * Publish a single pending draft BY REFERENCE — promotes the draft row for
853
890
  * `(type, name)` into the active overlay and drops the draft. Works for ANY
@@ -957,7 +994,20 @@ declare class MetadataClient {
957
994
  * Security module integration for @objectstack/spec v3.0.0
958
995
  * Provides advanced security policies: CSP config, audit logging, data masking.
959
996
  */
960
- interface SecurityPolicy {
997
+ /**
998
+ * Configuration for {@link SecurityManager} — this adapter's browser-side
999
+ * security posture: the CSP header it generates, the in-memory audit log it
1000
+ * keeps, and the field-masking rules it applies before a record is rendered.
1001
+ *
1002
+ * NOT the spec's `SecurityPolicy` (`@objectstack/spec/kernel`), whose name this
1003
+ * interface wore until objectui#3160 (objectstack#4115 ledger batch 6). That one
1004
+ * is the PACKAGE SUPPLY-CHAIN policy — `{ id, name, autoScan, thresholds,
1005
+ * allowedLicenses, prohibitedLicenses, codeSigning, sandbox }` — the rules a
1006
+ * marketplace applies when scanning a plugin before install. It shares no key
1007
+ * with this one, so there was nothing to derive; the collision is the word
1008
+ * "security", not the concept.
1009
+ */
1010
+ interface SecurityManagerPolicy {
961
1011
  /** Content Security Policy configuration */
962
1012
  csp?: CSPConfig;
963
1013
  /** Audit logging configuration */
@@ -1031,7 +1081,7 @@ interface AuditLogEntry {
1031
1081
  declare class SecurityManager {
1032
1082
  private policy;
1033
1083
  private auditLog;
1034
- constructor(policy?: SecurityPolicy);
1084
+ constructor(policy?: SecurityManagerPolicy);
1035
1085
  /**
1036
1086
  * Generate a CSP header string from the configuration.
1037
1087
  */
@@ -1055,11 +1105,11 @@ declare class SecurityManager {
1055
1105
  /**
1056
1106
  * Update the security policy.
1057
1107
  */
1058
- updatePolicy(policy: Partial<SecurityPolicy>): void;
1108
+ updatePolicy(policy: Partial<SecurityManagerPolicy>): void;
1059
1109
  /**
1060
1110
  * Get current security policy.
1061
1111
  */
1062
- getPolicy(): SecurityPolicy;
1112
+ getPolicy(): SecurityManagerPolicy;
1063
1113
  }
1064
1114
 
1065
1115
  /**
@@ -1379,7 +1429,7 @@ declare function isConcurrentUpdateError(error: unknown): error is ConcurrentUpd
1379
1429
  *
1380
1430
  * Two shapes are recognised:
1381
1431
  * - `409` + `CONCURRENT_UPDATE` → {@link ConcurrentUpdateError};
1382
- * - `400` + `VALIDATION_FAILED` → {@link ValidationError}, carrying the
1432
+ * - `400` + `VALIDATION_FAILED` → {@link DataApiValidationError}, carrying the
1383
1433
  * server's per-field entries so a form can mark the offending inputs
1384
1434
  * instead of showing one undirected toast.
1385
1435
  */
@@ -1414,19 +1464,7 @@ type ConnectionStateListener = (event: ConnectionStateEvent) => void;
1414
1464
  * Event listener type for batch operation progress
1415
1465
  */
1416
1466
  type BatchProgressListener = (event: BatchProgressEvent) => void;
1417
- /**
1418
- * One server-reported write-strip: caller-supplied fields the backend LEGALLY
1419
- * removed from a write before persisting (a non-system caller cannot seed a
1420
- * `readonly` field, a `readonlyWhen` predicate locked it, etc.). Mirrors the
1421
- * framework `DroppedFieldsEvent` (spec `DroppedFieldsEventSchema`) structurally
1422
- * so we don't pin a client type version — `reason` is kept as a widened string
1423
- * for forward-compatibility with reasons added server-side.
1424
- */
1425
- interface DroppedFieldsEvent {
1426
- object: string;
1427
- fields: string[];
1428
- reason: string;
1429
- }
1467
+
1430
1468
  /**
1431
1469
  * Emitted after a create/update whose response carried `droppedFields`
1432
1470
  * (framework #3431/#3455). The write SUCCEEDED — this is a warning that some
@@ -2085,7 +2123,7 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
2085
2123
  /**
2086
2124
  * Get cache statistics for monitoring performance.
2087
2125
  */
2088
- getCacheStats(): CacheStats;
2126
+ getCacheStats(): MetadataCacheStats;
2089
2127
  /**
2090
2128
  * Invalidate metadata cache entries.
2091
2129
  *
@@ -2173,4 +2211,4 @@ declare function createObjectStackAdapter<T = unknown>(config: {
2173
2211
  reconnectDelay?: number;
2174
2212
  }): DataSource<T>;
2175
2213
 
2176
- export { AnalyticsNotInstalledError, AnalyticsQueryRejectedError, type AuditEventType, type AuditLogConfig, type AuditLogEntry, AuthenticationError, type BatchProgressEvent, type BatchProgressListener, BulkOperationError, type CSPConfig, type CacheStats, type CloudDeploymentConfig, type CloudHostingConfig, type CloudMarketplaceEntry, CloudOperations, ConcurrentUpdateError, ConnectionError, type ConnectionState, type ConnectionStateEvent, type ConnectionStateListener, type ContractValidationError, type ContractValidationResult, type DataMaskingConfig, type DataMaskingRule, type DroppedFieldsEvent, type EmailIntegrationConfig, FILTER_OPERATOR_ALIASES, type IntegrationConfig, IntegrationManager, type IntegrationProvider, type IntegrationTrigger, MalformedFilterError, type MetadataAuditEntry, type MetadataAuditResponse, MetadataClient, type MetadataClientConfig, type MetadataDeleteOptions, type MetadataDiagnostics, type MetadataDiagnosticsEntry, type MetadataDiagnosticsOptions, type MetadataDiagnosticsSummary, type MetadataDraftHeader, type MetadataError, type MetadataGetOptions, type MetadataHistoryOptions, type MetadataLayered, type MetadataListOptions, MetadataNotFoundError, type MetadataReference, type MetadataSaveOptions, type MetadataValidationIssue, ObjectStackAdapter, ObjectStackError, type ObjectStackUserStateAdapterOptions, type PluginAPIContract, type PluginContract, type PluginExport, SecurityManager, type SecurityPolicy, type SlackIntegrationConfig, type StudioCanvasConfig, type StudioColorPalette, type StudioPropertyEditor, type StudioShadowPreset, type StudioThemeBuilderConfig, type StudioTypographyPreset, type UserDataAdapter, ValidationError, type WebhookIntegrationConfig, type WriteWarningEvent, type WriteWarningListener, calculateAutoLayout, classifyAnalyticsFailure, clearSharedDiscoveryCache, createDefaultCanvasConfig, createErrorFromResponse, createObjectStackAdapter, createObjectStackUserStateAdapter, generateContractManifest, getSharedDiscovery, is404Error, isAnalyticsNotInstalledError, isConcurrentUpdateError, isErrorType, isMalformedFilterError, isObjectStackError, normaliseClientError, readTransactionalBatchCapability, serializeOrderBy, snapToGrid, validatePluginContract };
2214
+ export { AnalyticsNotInstalledError, AnalyticsQueryRejectedError, type AuditEventType, type AuditLogConfig, type AuditLogEntry, AuthenticationError, type BatchProgressEvent, type BatchProgressListener, BulkOperationError, type CSPConfig, type CloudDeploymentConfig, type CloudHostingConfig, type CloudMarketplaceEntry, CloudOperations, ConcurrentUpdateError, ConnectionError, type ConnectionState, type ConnectionStateEvent, type ConnectionStateListener, type ContractValidationError, type ContractValidationResult, DataApiValidationError, type DataMaskingConfig, type DataMaskingRule, type EmailIntegrationConfig, FILTER_OPERATOR_ALIASES, type IntegrationConfig, IntegrationManager, type IntegrationProvider, type IntegrationTrigger, MalformedFilterError, type MetadataAuditEntry, type MetadataAuditResponse, type MetadataCacheStats, MetadataClient, type MetadataClientConfig, type MetadataClientSaveOptions, type MetadataDeleteOptions, type MetadataDiagnostics, type MetadataDiagnosticsEntry, type MetadataDiagnosticsOptions, type MetadataDiagnosticsSummary, type MetadataDraftHeader, type MetadataError, type MetadataGetOptions, type MetadataHistoryOptions, type MetadataLayered, type MetadataListOptions, MetadataNotFoundError, type MetadataReference, type MetadataValidationIssue, ObjectStackAdapter, ObjectStackError, type ObjectStackUserStateAdapterOptions, type PluginAPIContract, type PluginContract, type PluginExport, SecurityManager, type SecurityManagerPolicy, type SlackIntegrationConfig, type StudioCanvasConfig, type StudioColorPalette, type StudioPropertyEditor, type StudioShadowPreset, type StudioThemeBuilderConfig, type StudioTypographyPreset, type UserDataAdapter, type WebhookIntegrationConfig, type WriteWarningEvent, type WriteWarningListener, calculateAutoLayout, classifyAnalyticsFailure, clearSharedDiscoveryCache, createDefaultCanvasConfig, createErrorFromResponse, createObjectStackAdapter, createObjectStackUserStateAdapter, generateContractManifest, getSharedDiscovery, is404Error, isAnalyticsNotInstalledError, isConcurrentUpdateError, isErrorType, isMalformedFilterError, isObjectStackError, normaliseClientError, readTransactionalBatchCapability, serializeOrderBy, snapToGrid, validatePluginContract };
package/dist/index.js CHANGED
@@ -880,10 +880,10 @@ var AuthenticationError = class extends ObjectStackError {
880
880
  this.name = "AuthenticationError";
881
881
  }
882
882
  };
883
- var ValidationError = class extends ObjectStackError {
883
+ var DataApiValidationError = class extends ObjectStackError {
884
884
  /**
885
- * Create a new ValidationError
886
- *
885
+ * Create a new DataApiValidationError
886
+ *
887
887
  * @param message - Human-readable error message
888
888
  * @param field - The field that failed validation (optional)
889
889
  * @param validationErrors - Array of validation error details
@@ -934,7 +934,7 @@ function createErrorFromResponse(response, context) {
934
934
  }
935
935
  return new ObjectStackError(message, "NOT_FOUND", 404, details);
936
936
  case 400:
937
- return new ValidationError(message, void 0, response?.data?.errors, details);
937
+ return new DataApiValidationError(message, void 0, response?.data?.errors, details);
938
938
  case 503:
939
939
  return new ConnectionError(message, response?.config?.url, details, 503);
940
940
  case 504:
@@ -1647,7 +1647,7 @@ function normaliseClientError(error) {
1647
1647
  const message = typeof rec.message === "string" && rec.message.trim() ? rec.message : typeof rec.code === "string" ? rec.code : "";
1648
1648
  return { field, message };
1649
1649
  }).filter((x) => x !== null);
1650
- return new ValidationError(
1650
+ return new DataApiValidationError(
1651
1651
  typeof e.message === "string" ? e.message : "Validation failed",
1652
1652
  validationErrors[0]?.field,
1653
1653
  validationErrors,
@@ -3682,6 +3682,7 @@ export {
3682
3682
  CloudOperations,
3683
3683
  ConcurrentUpdateError,
3684
3684
  ConnectionError,
3685
+ DataApiValidationError,
3685
3686
  FILTER_OPERATOR_ALIASES,
3686
3687
  IntegrationManager,
3687
3688
  MalformedFilterError,
@@ -3690,7 +3691,6 @@ export {
3690
3691
  ObjectStackAdapter,
3691
3692
  ObjectStackError,
3692
3693
  SecurityManager,
3693
- ValidationError,
3694
3694
  calculateAutoLayout,
3695
3695
  classifyAnalyticsFailure,
3696
3696
  clearSharedDiscoveryCache,