@x12i/data 0.0.0-stage → 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 x12i
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,52 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # @x12i/data
2
+
3
+ Data grid contracts for the Unified UI Kit.
4
+
5
+ > **Status: foundation.** This package ships the types that apps, reports and
6
+ > charts will depend on. The `Table` and `DataGrid` components are not built yet.
7
+
8
+ ```ts
9
+ import { defineColumns, type ServerDataSource } from "@x12i/data";
10
+
11
+ type Order = { id: string; customer: string; total: number };
12
+
13
+ export const columns = defineColumns<Order>([
14
+ { id: "customer", header: "Customer", field: "customer", sortable: true },
15
+ { id: "total", header: "Total", field: "total", cellType: "currency" },
16
+ ]);
17
+
18
+ export const orders: ServerDataSource<Order> = {
19
+ async getRows({ startRow, endRow, sort, filter }, { signal } = {}) {
20
+ // Call your API and return { rows, total }.
21
+ return { rows: [], total: 0 };
22
+ },
23
+ };
24
+ ```
25
+
26
+ ## Saved views
27
+
28
+ `SavedView` is versioned JSON. `parseSavedView(value)` reads one from untrusted
29
+ storage (local storage, a URL, a server) and returns `null` for anything this
30
+ version does not understand, so a bad or newer record is ignored instead of
31
+ crashing the grid. `SavedViewStore` is the small interface an app implements to
32
+ keep views: `list`, `load`, `save`, `delete`.
33
+
34
+ `@x12i/flowix-ui` has one that keeps views as Flowix facts, so they follow the
35
+ user across devices and keep a revision history:
36
+
37
+ ```ts
38
+ import { createFlowixSavedViewStore } from "@x12i/flowix-ui/stores";
39
+
40
+ const views = createFlowixSavedViewStore(flowix, { namespace: "grid-views" });
41
+ ```
42
+
43
+ `@x12i/records` turns the same column definitions into a Fieldkit `FieldMap`
44
+ (`fieldMapFromColumns`), so the detail view of a row uses the grid's headers.
45
+
46
+ ## Planned engine
47
+
48
+ Headless: TanStack Table and TanStack Virtual (both MIT). Grouping, pivot, editing
49
+ UX, saved views and cell types are built on top, so no feature depends on a
50
+ commercial license.
51
+
52
+ `SavedView` is already versioned JSON, so views saved today stay readable.
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Contracts for the kit's DataGrid (spec section 7). The grid is built on
3
+ * TanStack Table and TanStack Virtual; these types are the stable surface that
4
+ * apps, reports and charts depend on.
5
+ */
6
+ type SortDirection = "asc" | "desc";
7
+ interface SortModelItem {
8
+ field: string;
9
+ direction: SortDirection;
10
+ }
11
+ type FilterOperator = "contains" | "not-contains" | "starts-with" | "equals" | "not-equals" | "gt" | "gte" | "lt" | "lte" | "between" | "in" | "before" | "after" | "is-empty" | "is-not-empty";
12
+ interface FilterModelItem {
13
+ field: string;
14
+ operator: FilterOperator;
15
+ /** Absent for `is-empty` and `is-not-empty`. An array for `in` and `between`. */
16
+ value?: unknown;
17
+ }
18
+ interface GroupModelItem {
19
+ field: string;
20
+ }
21
+ /** What the grid asks a server for. Row indexes are zero-based and `endRow` is exclusive. */
22
+ interface GetRowsRequest {
23
+ startRow: number;
24
+ endRow: number;
25
+ sort: SortModelItem[];
26
+ filter: FilterModelItem[];
27
+ group: GroupModelItem[];
28
+ }
29
+ interface GetRowsResult<Row> {
30
+ rows: Row[];
31
+ /** Total rows matching the filter, so the grid can size its scrollbar. */
32
+ total: number;
33
+ }
34
+ interface GetRowsOptions {
35
+ /** Aborted when the grid no longer needs the answer, for example after a new sort. */
36
+ signal?: AbortSignal;
37
+ }
38
+ /** The server data source: `getRows({ startRow, endRow, sort, filter, group })` returns `{ rows, total }`. */
39
+ interface ServerDataSource<Row> {
40
+ getRows(request: GetRowsRequest, options?: GetRowsOptions): Promise<GetRowsResult<Row>>;
41
+ }
42
+ /** Cell renderers the grid ships (spec section 7). */
43
+ type CellType = "text" | "number" | "currency" | "percent" | "date" | "status" | "avatar" | "progress" | "sparkline" | "link" | "actions";
44
+ /** Logical sides, so a pinned column follows the reading direction in RTL. */
45
+ type ColumnPin = "start" | "end";
46
+ interface ColumnDef<Row> {
47
+ /** Stable identifier, also used in saved views. */
48
+ id: string;
49
+ /** Header text. Pass a translated string. */
50
+ header: string;
51
+ /** Property of the row to read. */
52
+ field?: Extract<keyof Row, string>;
53
+ cellType?: CellType;
54
+ /** An `Intl`-based format name or options key, by cell type. */
55
+ format?: string;
56
+ width?: number;
57
+ minWidth?: number;
58
+ pinned?: ColumnPin;
59
+ sortable?: boolean;
60
+ filterable?: boolean;
61
+ resizable?: boolean;
62
+ editable?: boolean;
63
+ }
64
+ /** Identity helper that infers `Row` for column authoring. */
65
+ declare function defineColumns<Row>(columns: ColumnDef<Row>[]): ColumnDef<Row>[];
66
+ interface ColumnState {
67
+ id: string;
68
+ width?: number;
69
+ hidden?: boolean;
70
+ pinned?: ColumnPin;
71
+ }
72
+ declare const SAVED_VIEW_VERSION = 1;
73
+ /** Column state, filters and sort, serialized to JSON. */
74
+ interface SavedView {
75
+ version: typeof SAVED_VIEW_VERSION;
76
+ name?: string;
77
+ columns: ColumnState[];
78
+ sort: SortModelItem[];
79
+ filter: FilterModelItem[];
80
+ group?: GroupModelItem[];
81
+ }
82
+ /** Every filter operator, as a runtime list for validation and pickers. */
83
+ declare const FILTER_OPERATORS: readonly ["contains", "not-contains", "starts-with", "equals", "not-equals", "gt", "gte", "lt", "lte", "between", "in", "before", "after", "is-empty", "is-not-empty"];
84
+ /**
85
+ * Reads a saved view from untrusted JSON (storage, a URL, a server). Returns
86
+ * `null` when the value is not a view this version understands, so a bad or
87
+ * newer record is ignored instead of crashing the grid.
88
+ */
89
+ declare function parseSavedView(value: unknown): SavedView | null;
90
+ /** One saved view in a list, without loading its body. */
91
+ interface SavedViewSummary {
92
+ id: string;
93
+ name?: string;
94
+ }
95
+ /**
96
+ * Where an app keeps saved views. The grid does not care: pass any
97
+ * implementation (local storage, your API, `@x12i/flowix-ui`'s Flowix adapter).
98
+ */
99
+ interface SavedViewStore {
100
+ list(): Promise<SavedViewSummary[]>;
101
+ /** `null` when the id does not exist or holds something `parseSavedView` rejects. */
102
+ load(id: string): Promise<SavedView | null>;
103
+ save(id: string, view: SavedView): Promise<void>;
104
+ delete(id: string): Promise<void>;
105
+ }
106
+
107
+ export { FILTER_OPERATORS, SAVED_VIEW_VERSION, defineColumns, parseSavedView };
108
+ export type { CellType, ColumnDef, ColumnPin, ColumnState, FilterModelItem, FilterOperator, GetRowsOptions, GetRowsRequest, GetRowsResult, GroupModelItem, SavedView, SavedViewStore, SavedViewSummary, ServerDataSource, SortDirection, SortModelItem };
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ // src/index.ts
2
+ function defineColumns(columns) {
3
+ return columns;
4
+ }
5
+ var SAVED_VIEW_VERSION = 1;
6
+ var FILTER_OPERATORS = [
7
+ "contains",
8
+ "not-contains",
9
+ "starts-with",
10
+ "equals",
11
+ "not-equals",
12
+ "gt",
13
+ "gte",
14
+ "lt",
15
+ "lte",
16
+ "between",
17
+ "in",
18
+ "before",
19
+ "after",
20
+ "is-empty",
21
+ "is-not-empty"
22
+ ];
23
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24
+ var isOptionalNumber = (value) => value === void 0 || typeof value === "number" && Number.isFinite(value);
25
+ function parseSavedView(value) {
26
+ if (!isRecord(value) || value.version !== SAVED_VIEW_VERSION) return null;
27
+ if (value.name !== void 0 && typeof value.name !== "string") return null;
28
+ const { columns, sort, filter, group } = value;
29
+ if (!Array.isArray(columns) || !Array.isArray(sort) || !Array.isArray(filter)) return null;
30
+ if (group !== void 0 && !Array.isArray(group)) return null;
31
+ for (const column of columns) {
32
+ if (!isRecord(column) || typeof column.id !== "string") return null;
33
+ if (!isOptionalNumber(column.width)) return null;
34
+ if (column.hidden !== void 0 && typeof column.hidden !== "boolean") return null;
35
+ if (column.pinned !== void 0 && column.pinned !== "start" && column.pinned !== "end") {
36
+ return null;
37
+ }
38
+ }
39
+ for (const item of sort) {
40
+ if (!isRecord(item) || typeof item.field !== "string") return null;
41
+ if (item.direction !== "asc" && item.direction !== "desc") return null;
42
+ }
43
+ for (const item of filter) {
44
+ if (!isRecord(item) || typeof item.field !== "string") return null;
45
+ if (!FILTER_OPERATORS.includes(item.operator)) return null;
46
+ }
47
+ for (const item of group ?? []) {
48
+ if (!isRecord(item) || typeof item.field !== "string") return null;
49
+ }
50
+ return value;
51
+ }
52
+
53
+ export { FILTER_OPERATORS, SAVED_VIEW_VERSION, defineColumns, parseSavedView };
54
+ //# sourceMappingURL=index.js.map
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAuGO,SAAS,cAAmB,OAAA,EAA6C;AAC9E,EAAA,OAAO,OAAA;AACT;AASO,IAAM,kBAAA,GAAqB;AAa3B,IAAM,gBAAA,GAAmB;AAAA,EAC9B,UAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;AASA,IAAM,QAAA,GAAW,CAAC,KAAA,KAChB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAErE,IAAM,gBAAA,GAAmB,CAAC,KAAA,KACxB,KAAA,KAAU,MAAA,IAAc,OAAO,KAAA,KAAU,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA;AAOrE,SAAS,eAAe,KAAA,EAAkC;AAC/D,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,KAAK,KAAA,CAAM,OAAA,KAAY,oBAAoB,OAAO,IAAA;AACrE,EAAA,IAAI,MAAM,IAAA,KAAS,MAAA,IAAa,OAAO,KAAA,CAAM,IAAA,KAAS,UAAU,OAAO,IAAA;AAEvE,EAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAM,MAAA,EAAQ,OAAM,GAAI,KAAA;AACzC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,KAAK,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,KAAK,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,GAAG,OAAO,IAAA;AACtF,EAAA,IAAI,UAAU,MAAA,IAAa,CAAC,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,IAAA;AAEzD,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,CAAC,SAAS,MAAM,CAAA,IAAK,OAAO,MAAA,CAAO,EAAA,KAAO,UAAU,OAAO,IAAA;AAC/D,IAAA,IAAI,CAAC,gBAAA,CAAiB,MAAA,CAAO,KAAK,GAAG,OAAO,IAAA;AAC5C,IAAA,IAAI,OAAO,MAAA,KAAW,MAAA,IAAa,OAAO,MAAA,CAAO,MAAA,KAAW,WAAW,OAAO,IAAA;AAC9E,IAAA,IAAI,MAAA,CAAO,WAAW,MAAA,IAAa,MAAA,CAAO,WAAW,OAAA,IAAW,MAAA,CAAO,WAAW,KAAA,EAAO;AACvF,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,IAAA,IAAI,CAAC,SAAS,IAAI,CAAA,IAAK,OAAO,IAAA,CAAK,KAAA,KAAU,UAAU,OAAO,IAAA;AAC9D,IAAA,IAAI,KAAK,SAAA,KAAc,KAAA,IAAS,IAAA,CAAK,SAAA,KAAc,QAAQ,OAAO,IAAA;AAAA,EACpE;AACA,EAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,IAAA,IAAI,CAAC,SAAS,IAAI,CAAA,IAAK,OAAO,IAAA,CAAK,KAAA,KAAU,UAAU,OAAO,IAAA;AAC9D,IAAA,IAAI,CAAE,gBAAA,CAAwC,QAAA,CAAS,IAAA,CAAK,QAAQ,GAAG,OAAO,IAAA;AAAA,EAChF;AACA,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,IAAS,EAAC,EAAG;AAC9B,IAAA,IAAI,CAAC,SAAS,IAAI,CAAA,IAAK,OAAO,IAAA,CAAK,KAAA,KAAU,UAAU,OAAO,IAAA;AAAA,EAChE;AAEA,EAAA,OAAO,KAAA;AACT","file":"index.js","sourcesContent":["/**\r\n * Contracts for the kit's DataGrid (spec section 7). The grid is built on\r\n * TanStack Table and TanStack Virtual; these types are the stable surface that\r\n * apps, reports and charts depend on.\r\n */\r\n\r\nexport type SortDirection = \"asc\" | \"desc\";\r\n\r\nexport interface SortModelItem {\r\n field: string;\r\n direction: SortDirection;\r\n}\r\n\r\nexport type FilterOperator =\r\n | \"contains\"\r\n | \"not-contains\"\r\n | \"starts-with\"\r\n | \"equals\"\r\n | \"not-equals\"\r\n | \"gt\"\r\n | \"gte\"\r\n | \"lt\"\r\n | \"lte\"\r\n | \"between\"\r\n | \"in\"\r\n | \"before\"\r\n | \"after\"\r\n | \"is-empty\"\r\n | \"is-not-empty\";\r\n\r\nexport interface FilterModelItem {\r\n field: string;\r\n operator: FilterOperator;\r\n /** Absent for `is-empty` and `is-not-empty`. An array for `in` and `between`. */\r\n value?: unknown;\r\n}\r\n\r\nexport interface GroupModelItem {\r\n field: string;\r\n}\r\n\r\n/** What the grid asks a server for. Row indexes are zero-based and `endRow` is exclusive. */\r\nexport interface GetRowsRequest {\r\n startRow: number;\r\n endRow: number;\r\n sort: SortModelItem[];\r\n filter: FilterModelItem[];\r\n group: GroupModelItem[];\r\n}\r\n\r\nexport interface GetRowsResult<Row> {\r\n rows: Row[];\r\n /** Total rows matching the filter, so the grid can size its scrollbar. */\r\n total: number;\r\n}\r\n\r\nexport interface GetRowsOptions {\r\n /** Aborted when the grid no longer needs the answer, for example after a new sort. */\r\n signal?: AbortSignal;\r\n}\r\n\r\n/** The server data source: `getRows({ startRow, endRow, sort, filter, group })` returns `{ rows, total }`. */\r\nexport interface ServerDataSource<Row> {\r\n getRows(request: GetRowsRequest, options?: GetRowsOptions): Promise<GetRowsResult<Row>>;\r\n}\r\n\r\n/** Cell renderers the grid ships (spec section 7). */\r\nexport type CellType =\r\n | \"text\"\r\n | \"number\"\r\n | \"currency\"\r\n | \"percent\"\r\n | \"date\"\r\n | \"status\"\r\n | \"avatar\"\r\n | \"progress\"\r\n | \"sparkline\"\r\n | \"link\"\r\n | \"actions\";\r\n\r\n/** Logical sides, so a pinned column follows the reading direction in RTL. */\r\nexport type ColumnPin = \"start\" | \"end\";\r\n\r\nexport interface ColumnDef<Row> {\r\n /** Stable identifier, also used in saved views. */\r\n id: string;\r\n /** Header text. Pass a translated string. */\r\n header: string;\r\n /** Property of the row to read. */\r\n field?: Extract<keyof Row, string>;\r\n cellType?: CellType;\r\n /** An `Intl`-based format name or options key, by cell type. */\r\n format?: string;\r\n width?: number;\r\n minWidth?: number;\r\n pinned?: ColumnPin;\r\n sortable?: boolean;\r\n filterable?: boolean;\r\n resizable?: boolean;\r\n editable?: boolean;\r\n}\r\n\r\n/** Identity helper that infers `Row` for column authoring. */\r\nexport function defineColumns<Row>(columns: ColumnDef<Row>[]): ColumnDef<Row>[] {\r\n return columns;\r\n}\r\n\r\nexport interface ColumnState {\r\n id: string;\r\n width?: number;\r\n hidden?: boolean;\r\n pinned?: ColumnPin;\r\n}\r\n\r\nexport const SAVED_VIEW_VERSION = 1;\r\n\r\n/** Column state, filters and sort, serialized to JSON. */\r\nexport interface SavedView {\r\n version: typeof SAVED_VIEW_VERSION;\r\n name?: string;\r\n columns: ColumnState[];\r\n sort: SortModelItem[];\r\n filter: FilterModelItem[];\r\n group?: GroupModelItem[];\r\n}\r\n\n/** Every filter operator, as a runtime list for validation and pickers. */\nexport const FILTER_OPERATORS = [\n \"contains\",\n \"not-contains\",\n \"starts-with\",\n \"equals\",\n \"not-equals\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"between\",\n \"in\",\n \"before\",\n \"after\",\n \"is-empty\",\n \"is-not-empty\",\n] as const satisfies readonly FilterOperator[];\n\n// Compile-time guard: adding an operator to `FilterOperator` without listing it\n// above makes this line fail to type-check.\nconst _everyOperatorListed: Exclude<FilterOperator, (typeof FILTER_OPERATORS)[number]> extends never\n ? true\n : never = true;\nvoid _everyOperatorListed;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isOptionalNumber = (value: unknown) =>\n value === undefined || (typeof value === \"number\" && Number.isFinite(value));\n\n/**\n * Reads a saved view from untrusted JSON (storage, a URL, a server). Returns\n * `null` when the value is not a view this version understands, so a bad or\n * newer record is ignored instead of crashing the grid.\n */\nexport function parseSavedView(value: unknown): SavedView | null {\n if (!isRecord(value) || value.version !== SAVED_VIEW_VERSION) return null;\n if (value.name !== undefined && typeof value.name !== \"string\") return null;\n\n const { columns, sort, filter, group } = value;\n if (!Array.isArray(columns) || !Array.isArray(sort) || !Array.isArray(filter)) return null;\n if (group !== undefined && !Array.isArray(group)) return null;\n\n for (const column of columns) {\n if (!isRecord(column) || typeof column.id !== \"string\") return null;\n if (!isOptionalNumber(column.width)) return null;\n if (column.hidden !== undefined && typeof column.hidden !== \"boolean\") return null;\n if (column.pinned !== undefined && column.pinned !== \"start\" && column.pinned !== \"end\") {\n return null;\n }\n }\n for (const item of sort) {\n if (!isRecord(item) || typeof item.field !== \"string\") return null;\n if (item.direction !== \"asc\" && item.direction !== \"desc\") return null;\n }\n for (const item of filter) {\n if (!isRecord(item) || typeof item.field !== \"string\") return null;\n if (!(FILTER_OPERATORS as readonly unknown[]).includes(item.operator)) return null;\n }\n for (const item of group ?? []) {\n if (!isRecord(item) || typeof item.field !== \"string\") return null;\n }\n\n return value as unknown as SavedView;\n}\n\n/** One saved view in a list, without loading its body. */\nexport interface SavedViewSummary {\n id: string;\n name?: string;\n}\n\n/**\n * Where an app keeps saved views. The grid does not care: pass any\n * implementation (local storage, your API, `@x12i/flowix-ui`'s Flowix adapter).\n */\nexport interface SavedViewStore {\n list(): Promise<SavedViewSummary[]>;\n /** `null` when the id does not exist or holds something `parseSavedView` rejects. */\n load(id: string): Promise<SavedView | null>;\n save(id: string, view: SavedView): Promise<void>;\n delete(id: string): Promise<void>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@x12i/data",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0",
4
+ "description": "Data grid contracts for the Unified UI Kit: server data source, column definitions and saved views. The DataGrid itself (on TanStack Table) is planned.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/x12i/unified-ui-kit.git",
9
+ "directory": "packages/data"
10
+ },
11
+ "homepage": "https://github.com/x12i/unified-ui-kit/tree/main/packages/data#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/x12i/unified-ui-kit/issues"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "scripts": {
32
+ "build": "tsup",
33
+ "typecheck": "tsc --noEmit",
34
+ "lint": "eslint .",
35
+ "test": "vitest run --passWithNoTests"
36
+ }
6
37
  }