@chelone/core 0.5.0 → 0.7.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/assistant/assistant-session.d.ts +28 -0
- package/dist/assistant/assistant-session.js +208 -0
- package/dist/assistant/echo-transport.d.ts +7 -0
- package/dist/assistant/echo-transport.js +28 -0
- package/dist/assistant/http-transport.d.ts +10 -0
- package/dist/assistant/http-transport.js +98 -0
- package/dist/assistant/types.d.ts +54 -0
- package/dist/auth/access-control.d.ts +13 -5
- package/dist/auth/access-control.js +25 -21
- package/dist/auth/auth-options.d.ts +21 -17
- package/dist/auth/auth-options.js +80 -48
- package/dist/auth/permission-matrix.d.ts +12 -0
- package/dist/auth/permission-matrix.js +67 -0
- package/dist/auth/types.d.ts +14 -4
- package/dist/block-editor/block-document.d.ts +60 -0
- package/dist/block-editor/block-document.js +143 -0
- package/dist/block-editor/data-blocks.d.ts +63 -0
- package/dist/block-editor/data-blocks.js +117 -0
- package/dist/chart/chart-data.d.ts +25 -0
- package/dist/chart/chart-data.js +61 -0
- package/dist/command-menu/hotkey.js +58 -47
- package/dist/command-menu/recents.js +8 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.js +82 -113
- package/dist/controller/calendar-events.js +93 -88
- package/dist/controller/client-list-controller.d.ts +2 -2
- package/dist/controller/client-list-controller.js +251 -254
- package/dist/controller/data-table-columns.d.ts +2 -0
- package/dist/controller/data-table-columns.js +50 -56
- package/dist/controller/deep-equal.d.ts +1 -0
- package/dist/controller/deep-equal.js +14 -0
- package/dist/controller/filter-toggle.js +36 -44
- package/dist/controller/in-place-editor.d.ts +42 -0
- package/dist/controller/in-place-editor.js +42 -0
- package/dist/controller/infinite-list-controller.js +220 -190
- package/dist/controller/inspector.d.ts +49 -0
- package/dist/controller/inspector.js +64 -0
- package/dist/controller/job-monitor.d.ts +41 -0
- package/dist/controller/job-monitor.js +49 -0
- package/dist/controller/kanban-board.d.ts +2 -3
- package/dist/controller/kanban-board.js +43 -24
- package/dist/controller/list-controller.d.ts +5 -5
- package/dist/controller/list-controller.js +444 -400
- package/dist/controller/list-params.js +96 -87
- package/dist/controller/pivot-grid.d.ts +36 -0
- package/dist/controller/pivot-grid.js +99 -0
- package/dist/controller/prev-next.d.ts +2 -2
- package/dist/controller/prev-next.js +74 -54
- package/dist/controller/record-controllers.d.ts +14 -6
- package/dist/controller/record-controllers.js +288 -257
- package/dist/controller/record-diff.d.ts +21 -0
- package/dist/controller/record-diff.js +50 -0
- package/dist/controller/record-timeline.d.ts +35 -0
- package/dist/controller/record-timeline.js +48 -0
- package/dist/controller/record-tree.js +57 -47
- package/dist/controller/record-workflow.d.ts +38 -16
- package/dist/controller/record-workflow.js +85 -64
- package/dist/controller/reference-many-controller.js +198 -192
- package/dist/controller/reference-one-controller.d.ts +1 -1
- package/dist/controller/reference-one-controller.js +63 -56
- package/dist/controller/saved-queries.js +104 -91
- package/dist/controller/translate-fallback.js +10 -6
- package/dist/csv/export.d.ts +2 -1
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.js +185 -169
- package/dist/csv/match-headers.js +29 -22
- package/dist/csv/parse-with.js +60 -54
- package/dist/csv/run-import.js +69 -72
- package/dist/csv/validate-rows.d.ts +1 -1
- package/dist/csv/validate-rows.js +65 -52
- package/dist/data/cache-ops.d.ts +5 -4
- package/dist/data/cache-ops.js +208 -190
- package/dist/data/combine-data-providers.js +25 -23
- package/dist/data/data-provider-log.d.ts +45 -0
- package/dist/data/data-provider-log.js +93 -0
- package/dist/data/errors.js +14 -10
- package/dist/data/fake-provider.d.ts +6 -3
- package/dist/data/fake-provider.js +129 -114
- package/dist/data/fetch-utils.js +61 -44
- package/dist/data/filter-branch.d.ts +5 -0
- package/dist/data/filter-branch.js +10 -0
- package/dist/data/get-many-aggregate.js +84 -76
- package/dist/data/http-error.js +17 -12
- package/dist/data/keys.js +50 -36
- package/dist/data/mutation-options.d.ts +14 -9
- package/dist/data/mutation-options.js +93 -109
- package/dist/data/query-options.js +73 -68
- package/dist/data/remove-empty.d.ts +3 -0
- package/dist/data/remove-empty.js +11 -0
- package/dist/data/undoable.d.ts +2 -2
- package/dist/data/undoable.js +190 -174
- package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
- package/dist/data/with-lifecycle-callbacks.js +66 -52
- package/dist/environment/application-update-store.js +58 -55
- package/dist/environment/offline-store.js +21 -21
- package/dist/form/array-binding.d.ts +30 -11
- package/dist/form/array-binding.js +184 -166
- package/dist/form/choice-ids.d.ts +7 -0
- package/dist/form/choice-ids.js +11 -0
- package/dist/form/choices-controller.d.ts +3 -2
- package/dist/form/choices-controller.js +302 -275
- package/dist/form/date-format.d.ts +38 -0
- package/dist/form/date-format.js +89 -0
- package/dist/form/dirty-values.d.ts +2 -2
- package/dist/form/dirty-values.js +22 -11
- package/dist/form/duration.d.ts +22 -0
- package/dist/form/duration.js +49 -0
- package/dist/form/edit-create-form.d.ts +12 -5
- package/dist/form/edit-create-form.js +243 -188
- package/dist/form/event-value.d.ts +6 -0
- package/dist/form/event-value.js +17 -0
- package/dist/form/field-error.d.ts +14 -0
- package/dist/form/field-error.js +28 -0
- package/dist/form/field-name.d.ts +20 -0
- package/dist/form/field-name.js +6 -0
- package/dist/form/filter-form-values.js +63 -49
- package/dist/form/form-controller.d.ts +9 -1
- package/dist/form/form-controller.js +165 -160
- package/dist/form/form-groups.d.ts +4 -3
- package/dist/form/form-groups.js +79 -79
- package/dist/form/form-handle.d.ts +175 -0
- package/dist/form/form-handle.js +68 -0
- package/dist/form/input-binding.d.ts +56 -31
- package/dist/form/input-binding.js +169 -118
- package/dist/form/input-values.d.ts +130 -0
- package/dist/form/input-values.js +177 -0
- package/dist/form/json-text.js +51 -37
- package/dist/form/save-pipeline.d.ts +6 -8
- package/dist/form/save-pipeline.js +91 -82
- package/dist/form/set-form-values.d.ts +6 -0
- package/dist/form/set-form-values.js +10 -0
- package/dist/form/source.js +97 -65
- package/dist/form/text-of.d.ts +2 -0
- package/dist/form/text-of.js +7 -0
- package/dist/form/validators.d.ts +58 -19
- package/dist/form/validators.js +97 -71
- package/dist/geo/bbox.d.ts +5 -4
- package/dist/geo/bbox.js +69 -48
- package/dist/geo/bounds.d.ts +14 -3
- package/dist/geo/bounds.js +98 -68
- package/dist/geo/constraints.js +88 -93
- package/dist/geo/coordinates.js +31 -23
- package/dist/geo/editor.d.ts +13 -13
- package/dist/geo/editor.js +176 -153
- package/dist/geo/geocoding.d.ts +4 -4
- package/dist/geo/geocoding.js +38 -41
- package/dist/geo/geojson.d.ts +12 -74
- package/dist/geo/geojson.js +52 -40
- package/dist/geo/geometry-math.d.ts +4 -4
- package/dist/geo/geometry-math.js +100 -93
- package/dist/geo/index.d.ts +7 -6
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.js +31 -32
- package/dist/geo/messages.js +48 -45
- package/dist/geo/nominatim.js +88 -80
- package/dist/geo/osm-presets.d.ts +4 -3
- package/dist/geo/osm-presets.js +108 -86
- package/dist/geo/osm-tags.js +14 -12
- package/dist/geo/overpass.d.ts +14 -2
- package/dist/geo/overpass.js +83 -90
- package/dist/geo/shape-value.d.ts +9 -5
- package/dist/geo/shape-value.js +169 -146
- package/dist/geo/snap-to-roads.d.ts +3 -3
- package/dist/geo/snap-to-roads.js +55 -50
- package/dist/geo/throttle.js +36 -39
- package/dist/guards.d.ts +37 -0
- package/dist/guards.js +62 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.js +187 -189
- package/dist/i18n/i18n.d.ts +8 -2
- package/dist/i18n/i18n.js +47 -48
- package/dist/i18n/inflection.d.ts +34 -0
- package/dist/i18n/inflection.js +82 -0
- package/dist/i18n/messages.d.ts +10 -2
- package/dist/i18n/messages.js +17 -4
- package/dist/i18n/missing-keys.d.ts +19 -0
- package/dist/i18n/missing-keys.js +68 -0
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +96 -22
- package/dist/index.js +52 -257
- package/dist/json/deep-equal.d.ts +8 -0
- package/dist/json/deep-equal.js +24 -0
- package/dist/json/strip-json-comments.js +38 -42
- package/dist/noop.d.ts +2 -0
- package/dist/noop.js +4 -0
- package/dist/notification/error-message.d.ts +2 -0
- package/dist/notification/error-message.js +10 -0
- package/dist/notification/notification-store.d.ts +3 -2
- package/dist/notification/notification-store.js +41 -45
- package/dist/onboarding-tour/placement.d.ts +34 -0
- package/dist/onboarding-tour/placement.js +67 -0
- package/dist/onboarding-tour/tour-controller.d.ts +25 -0
- package/dist/onboarding-tour/tour-controller.js +50 -0
- package/dist/realtime/add-events-for-mutations.js +75 -81
- package/dist/realtime/announce-lock.d.ts +7 -0
- package/dist/realtime/announce-lock.js +18 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +14 -0
- package/dist/realtime/broadcast-channel-transport.js +69 -0
- package/dist/realtime/copy-members.js +22 -14
- package/dist/realtime/in-memory-lock-provider.js +41 -60
- package/dist/realtime/live.js +95 -101
- package/dist/realtime/lock-options.js +16 -16
- package/dist/realtime/lock-session.js +91 -78
- package/dist/realtime/memory-transport.js +26 -67
- package/dist/realtime/presence.js +120 -122
- package/dist/realtime/realtime-data-provider.d.ts +10 -0
- package/dist/realtime/realtime-data-provider.js +45 -42
- package/dist/realtime/reconnect-backoff.d.ts +15 -0
- package/dist/realtime/reconnect-backoff.js +17 -0
- package/dist/realtime/sse-transport.d.ts +31 -0
- package/dist/realtime/sse-transport.js +235 -0
- package/dist/realtime/status-store.js +23 -28
- package/dist/realtime/topic-hub.d.ts +24 -0
- package/dist/realtime/topic-hub.js +66 -0
- package/dist/realtime/topics.js +10 -12
- package/dist/realtime/types.js +10 -12
- package/dist/realtime/unread-count.js +21 -21
- package/dist/realtime/websocket-transport.d.ts +32 -0
- package/dist/realtime/websocket-transport.js +306 -0
- package/dist/resource/describe-resource.d.ts +2 -0
- package/dist/resource/describe-resource.js +232 -219
- package/dist/resource/get-at-path.js +29 -14
- package/dist/resource/identifier.d.ts +18 -0
- package/dist/resource/identifier.js +27 -0
- package/dist/resource/record.d.ts +4 -0
- package/dist/resource/record.js +10 -0
- package/dist/resource/register.d.ts +7 -0
- package/dist/resource/registry-store.d.ts +45 -15
- package/dist/resource/registry-store.js +67 -60
- package/dist/resource/registry.d.ts +10 -0
- package/dist/resource/registry.js +8 -4
- package/dist/resource/source-path.d.ts +16 -1
- package/dist/rich-text/rich-text-extras.d.ts +132 -0
- package/dist/rich-text/rich-text-extras.js +179 -0
- package/dist/rich-text/rich-text-image.d.ts +124 -0
- package/dist/rich-text/rich-text-image.js +163 -0
- package/dist/rich-text/rich-text.d.ts +62 -0
- package/dist/rich-text/rich-text.js +142 -0
- package/dist/router/location.d.ts +22 -4
- package/dist/router/location.js +41 -18
- package/dist/router/match.js +47 -39
- package/dist/router/paths.js +40 -34
- package/dist/router/record-from-location.d.ts +1 -1
- package/dist/router/record-from-location.js +25 -17
- package/dist/store/adapters.js +51 -55
- package/dist/store/micro-store.js +57 -59
- package/dist/store/shallow-equal.d.ts +12 -0
- package/dist/store/shallow-equal.js +20 -0
- package/dist/store/store.js +54 -57
- package/package.json +13 -11
|
@@ -1,104 +1,117 @@
|
|
|
1
|
+
import { isPlainObject, isRecord } from "../guards.js";
|
|
1
2
|
import { createMicroStore } from "../store/micro-store.js";
|
|
3
|
+
// src/controller/saved-queries.ts
|
|
4
|
+
/** The key ra-core's `useSavedQueries` uses. */
|
|
2
5
|
function savedQueriesKey(storeKey) {
|
|
3
|
-
|
|
6
|
+
return `${storeKey}.savedQueries`;
|
|
4
7
|
}
|
|
5
|
-
|
|
6
|
-
const isSortPayload = (value) => isRecord(value) && typeof value.field === "string" && (value.order === "ASC" || value.order === "DESC");
|
|
8
|
+
var isSortPayload = (value) => isRecord(value) && typeof value.field === "string" && (value.order === "ASC" || value.order === "DESC");
|
|
7
9
|
function isSavedQueryValue(value) {
|
|
8
|
-
|
|
9
|
-
(flag) => typeof flag === "boolean"
|
|
10
|
-
) && Array.isArray(value.sort) && value.sort.every(isSortPayload) && typeof value.perPage === "number" && Number.isInteger(value.perPage) && value.perPage > 0;
|
|
10
|
+
return isRecord(value) && isRecord(value.filter) && isRecord(value.displayedFilters) && Object.values(value.displayedFilters).every((flag) => typeof flag === "boolean") && Array.isArray(value.sort) && value.sort.every(isSortPayload) && typeof value.perPage === "number" && Number.isInteger(value.perPage) && value.perPage > 0;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Reads whatever storage holds: non-arrays give `[]`, malformed entries are
|
|
14
|
+
* dropped, labels are trimmed, and a repeated label keeps its first entry.
|
|
15
|
+
*/
|
|
12
16
|
function extractValidSavedQueries(raw) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
if (!Array.isArray(raw)) return [];
|
|
18
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19
|
+
const queries = [];
|
|
20
|
+
for (const entry of raw) {
|
|
21
|
+
if (!isRecord(entry) || typeof entry.label !== "string") continue;
|
|
22
|
+
const label = entry.label.trim();
|
|
23
|
+
if (!label || seen.has(label) || !isSavedQueryValue(entry.value)) continue;
|
|
24
|
+
seen.add(label);
|
|
25
|
+
queries.push({
|
|
26
|
+
label,
|
|
27
|
+
value: entry.value
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return queries;
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Structural equality; object key order is irrelevant, array order is not.
|
|
34
|
+
* Only plain objects, arrays and dates compare by content: any other class
|
|
35
|
+
* instance is equal to itself alone.
|
|
36
|
+
*/
|
|
30
37
|
function isDeepEqual(a, b) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
if (!isPlainObject(a) || !isPlainObject(b)) return false;
|
|
39
|
-
const keys = Object.keys(a);
|
|
40
|
-
return keys.length === Object.keys(b).length && keys.every((key) => key in b && isDeepEqual(a[key], b[key]));
|
|
38
|
+
if (Object.is(a, b)) return true;
|
|
39
|
+
if (a instanceof Date || b instanceof Date) return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
|
|
40
|
+
if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => isDeepEqual(item, b[index]));
|
|
41
|
+
if (!isPlainObject(a) || !isPlainObject(b)) return false;
|
|
42
|
+
const keys = Object.keys(a);
|
|
43
|
+
return keys.length === Object.keys(b).length && keys.every((key) => key in b && isDeepEqual(a[key], b[key]));
|
|
41
44
|
}
|
|
45
|
+
/** Whether `current` list params are the saved query. `displayedFilters` is ignored. */
|
|
42
46
|
function isSavedQueryActive(query, current) {
|
|
43
|
-
|
|
47
|
+
return query.perPage === current.perPage && isDeepEqual(query.sort, current.sort) && isDeepEqual(query.filter, current.filter);
|
|
44
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Named filter/sort sets persisted in the KV store.
|
|
51
|
+
*
|
|
52
|
+
* Lifecycle (Task 4R): construction is inert. The first subscriber subscribes
|
|
53
|
+
* to the store key and re-reads it; the last unsubscribe releases it. Detached,
|
|
54
|
+
* a write still updates local state, and the next attach picks up whatever the
|
|
55
|
+
* store holds.
|
|
56
|
+
*/
|
|
45
57
|
function createSavedQueriesController(ctx, resource, options = {}) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
58
|
+
const key = savedQueriesKey(options.storeKey ?? resource);
|
|
59
|
+
const kv = ctx.store;
|
|
60
|
+
/** The raw value the state was last derived from, to skip no-op resyncs. */
|
|
61
|
+
let lastRaw = kv?.getItem(key);
|
|
62
|
+
const store = createMicroStore({ queries: extractValidSavedQueries(lastRaw) }, { onSubscribed: () => {
|
|
63
|
+
if (!kv) return;
|
|
64
|
+
resync();
|
|
65
|
+
return kv.subscribe(key, resync);
|
|
66
|
+
} });
|
|
67
|
+
/** Brings state in line with the store; a no-op when nothing changed. */
|
|
68
|
+
function resync() {
|
|
69
|
+
if (!kv) return;
|
|
70
|
+
const raw = kv.getItem(key);
|
|
71
|
+
if (raw === lastRaw) return;
|
|
72
|
+
lastRaw = raw;
|
|
73
|
+
const queries = extractValidSavedQueries(raw);
|
|
74
|
+
if (isDeepEqual(queries, store.getSnapshot().queries)) return;
|
|
75
|
+
store.setState({ queries });
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Detached, nothing keeps state current, so every action starts from the
|
|
79
|
+
* store: a stale snapshot would write over another controller's queries.
|
|
80
|
+
*/
|
|
81
|
+
const current = () => {
|
|
82
|
+
resync();
|
|
83
|
+
return store.getSnapshot().queries;
|
|
84
|
+
};
|
|
85
|
+
const write = (queries) => {
|
|
86
|
+
if (!kv) {
|
|
87
|
+
store.setState({ queries });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
kv.setItem(key, queries);
|
|
91
|
+
resync();
|
|
92
|
+
};
|
|
93
|
+
const save = (label, value) => {
|
|
94
|
+
const trimmed = label.trim();
|
|
95
|
+
if (!trimmed) return;
|
|
96
|
+
if (!isSavedQueryValue(value)) return;
|
|
97
|
+
const next = {
|
|
98
|
+
label: trimmed,
|
|
99
|
+
value: structuredClone(value)
|
|
100
|
+
};
|
|
101
|
+
const queries = current();
|
|
102
|
+
const index = queries.findIndex((query) => query.label === trimmed);
|
|
103
|
+
write(index === -1 ? [...queries, next] : queries.map((query, i) => i === index ? next : query));
|
|
104
|
+
};
|
|
105
|
+
const remove = (label) => {
|
|
106
|
+
const trimmed = label.trim();
|
|
107
|
+
const queries = current();
|
|
108
|
+
if (!queries.some((query) => query.label === trimmed)) return;
|
|
109
|
+
write(queries.filter((query) => query.label !== trimmed));
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
...store,
|
|
113
|
+
save,
|
|
114
|
+
remove
|
|
115
|
+
};
|
|
98
116
|
}
|
|
99
|
-
export {
|
|
100
|
-
createSavedQueriesController,
|
|
101
|
-
extractValidSavedQueries,
|
|
102
|
-
isSavedQueryActive,
|
|
103
|
-
savedQueriesKey
|
|
104
|
-
};
|
|
117
|
+
export { createSavedQueriesController, extractValidSavedQueries, isSavedQueryActive, savedQueriesKey };
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
// src/controller/translate-fallback.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resource-scoped notification key with global fallback. A translator that
|
|
4
|
+
* returns the key unchanged (Chelone i18n's missing-key behavior) means
|
|
5
|
+
* "not translated" — fall back to the global key.
|
|
6
|
+
*/
|
|
1
7
|
function resolveNotificationKey(translate, resource, event) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
8
|
+
const scoped = `resources.${resource}.notifications.${event}`;
|
|
9
|
+
if (translate && translate(scoped) !== scoped) return scoped;
|
|
10
|
+
return `chelone.notification.${event}`;
|
|
5
11
|
}
|
|
6
|
-
export {
|
|
7
|
-
resolveNotificationKey
|
|
8
|
-
};
|
|
12
|
+
export { resolveNotificationKey };
|
package/dist/csv/export.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { DataProvider } from "../data/types.js";
|
|
21
21
|
import type { LooseRecord } from "../resource/record.js";
|
|
22
|
+
import type { CsvRow } from "./types.js";
|
|
22
23
|
/**
|
|
23
24
|
* Turns a page of records into a downloaded file. Called by the export buttons
|
|
24
25
|
* with the fetched rows, the raw dataProvider (for follow-up fetches), and the
|
|
@@ -30,7 +31,7 @@ export type Exporter<TRecord extends LooseRecord = LooseRecord> = (data: TRecord
|
|
|
30
31
|
* in first-seen order — so a sparse record still lines up under the right
|
|
31
32
|
* header. Returns an empty string for an empty dataset.
|
|
32
33
|
*/
|
|
33
|
-
export declare function recordsToCSV(data: readonly
|
|
34
|
+
export declare function recordsToCSV(data: readonly CsvRow[]): string;
|
|
34
35
|
/**
|
|
35
36
|
* Trigger a browser download of `csv` as `<filename>.csv`. A DOM-guarded no-op
|
|
36
37
|
* when there is no `document` (SSR / non-jsdom test env) so callers never crash
|
package/dist/csv/export.js
CHANGED
|
@@ -1,47 +1,50 @@
|
|
|
1
|
+
// src/csv/export.ts
|
|
2
|
+
/** Escape one CSV cell: wrap in quotes + double any embedded quote when needed. */
|
|
1
3
|
function csvCell(value) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
return raw;
|
|
4
|
+
if (value == null) return "";
|
|
5
|
+
const raw = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
6
|
+
if (/[",\n\r]/.test(raw)) return `"${raw.replace(/"/g, "\"\"")}"`;
|
|
7
|
+
return raw;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Serialize records to CSV text. Columns are the UNION of every record's keys,
|
|
11
|
+
* in first-seen order — so a sparse record still lines up under the right
|
|
12
|
+
* header. Returns an empty string for an empty dataset.
|
|
13
|
+
*/
|
|
9
14
|
function recordsToCSV(data) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const header = columns.map(csvCell).join(",");
|
|
22
|
-
const rows = data.map(
|
|
23
|
-
(record) => columns.map((col) => csvCell(record[col])).join(",")
|
|
24
|
-
);
|
|
25
|
-
return [header, ...rows].join("\n");
|
|
15
|
+
if (data.length === 0) return "";
|
|
16
|
+
const columns = [];
|
|
17
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18
|
+
for (const record of data) for (const key of Object.keys(record)) if (!seen.has(key)) {
|
|
19
|
+
seen.add(key);
|
|
20
|
+
columns.push(key);
|
|
21
|
+
}
|
|
22
|
+
return [columns.map(csvCell).join(","), ...data.map((record) => columns.map((col) => csvCell(record[col])).join(","))].join("\n");
|
|
26
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Trigger a browser download of `csv` as `<filename>.csv`. A DOM-guarded no-op
|
|
26
|
+
* when there is no `document` (SSR / non-jsdom test env) so callers never crash
|
|
27
|
+
* off-DOM.
|
|
28
|
+
*/
|
|
27
29
|
function downloadCSV(csv, filename) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
if (typeof document === "undefined") return;
|
|
31
|
+
const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
|
|
32
|
+
const url = URL.createObjectURL(blob);
|
|
33
|
+
const link = document.createElement("a");
|
|
34
|
+
link.href = url;
|
|
35
|
+
link.download = `${filename}.csv`;
|
|
36
|
+
link.style.display = "none";
|
|
37
|
+
document.body.appendChild(link);
|
|
38
|
+
link.click();
|
|
39
|
+
document.body.removeChild(link);
|
|
40
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
39
41
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The built-in exporter: serialize `data` to CSV (union-of-keys columns) and
|
|
44
|
+
* download it as `<resource>.csv`. Apps needing nested/related data pass a
|
|
45
|
+
* custom `exporter` prop instead.
|
|
46
|
+
*/
|
|
47
|
+
var defaultExporter = (data, _dataProvider, resource) => {
|
|
48
|
+
downloadCSV(recordsToCSV(data), resource);
|
|
47
49
|
};
|
|
50
|
+
export { defaultExporter, downloadCSV, recordsToCSV };
|