@firecms/data_import_export 3.0.0-canary.19 → 3.0.0-canary.191

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.
Files changed (45) hide show
  1. package/LICENSE +114 -21
  2. package/README.md +1 -4
  3. package/dist/index.d.ts +2 -4
  4. package/dist/index.es.js +12 -994
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +29 -2
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/useImportExportPlugin.d.ts +6 -4
  9. package/package.json +17 -34
  10. package/src/index.ts +2 -4
  11. package/src/useImportExportPlugin.tsx +10 -6
  12. package/dist/components/DataNewPropertiesMapping.d.ts +0 -15
  13. package/dist/components/ImportFileUpload.d.ts +0 -3
  14. package/dist/components/ImportNewPropertyFieldPreview.d.ts +0 -10
  15. package/dist/components/ImportSaveInProgress.d.ts +0 -8
  16. package/dist/components/index.d.ts +0 -4
  17. package/dist/export_import/ExportCollectionAction.d.ts +0 -11
  18. package/dist/export_import/ImportCollectionAction.d.ts +0 -15
  19. package/dist/export_import/export.d.ts +0 -10
  20. package/dist/hooks/index.d.ts +0 -1
  21. package/dist/hooks/useImportConfig.d.ts +0 -2
  22. package/dist/types/column_mapping.d.ts +0 -22
  23. package/dist/types/index.d.ts +0 -1
  24. package/dist/utils/data.d.ts +0 -11
  25. package/dist/utils/file_to_json.d.ts +0 -11
  26. package/dist/utils/get_import_inference_type.d.ts +0 -2
  27. package/dist/utils/get_properties_mapping.d.ts +0 -3
  28. package/dist/utils/index.d.ts +0 -4
  29. package/src/components/DataNewPropertiesMapping.tsx +0 -128
  30. package/src/components/ImportFileUpload.tsx +0 -34
  31. package/src/components/ImportNewPropertyFieldPreview.tsx +0 -55
  32. package/src/components/ImportSaveInProgress.tsx +0 -122
  33. package/src/components/index.ts +0 -4
  34. package/src/export_import/ExportCollectionAction.tsx +0 -252
  35. package/src/export_import/ImportCollectionAction.tsx +0 -442
  36. package/src/export_import/export.ts +0 -200
  37. package/src/hooks/index.ts +0 -1
  38. package/src/hooks/useImportConfig.tsx +0 -28
  39. package/src/types/column_mapping.ts +0 -32
  40. package/src/types/index.ts +0 -1
  41. package/src/utils/data.ts +0 -223
  42. package/src/utils/file_to_json.ts +0 -88
  43. package/src/utils/get_import_inference_type.ts +0 -27
  44. package/src/utils/get_properties_mapping.ts +0 -59
  45. package/src/utils/index.ts +0 -4
@@ -1,32 +0,0 @@
1
- import React from "react";
2
- import { DataType, Entity, Property } from "@firecms/core";
3
-
4
- export type ImportConfig = {
5
-
6
- inUse: boolean;
7
- setInUse: React.Dispatch<React.SetStateAction<boolean>>;
8
-
9
- idColumn: string | undefined;
10
- setIdColumn: React.Dispatch<React.SetStateAction<string | undefined>>;
11
-
12
- importData: object[];
13
- setImportData: React.Dispatch<React.SetStateAction<object[]>>;
14
-
15
- entities: Entity<any>[];
16
- setEntities: React.Dispatch<React.SetStateAction<Entity<any>[]>>;
17
-
18
- // mapping of the column name in the import file to the property key in the data model
19
- headersMapping: Record<string, string | null>;
20
- setHeadersMapping: React.Dispatch<React.SetStateAction<Record<string, string | null>>>;
21
-
22
- originProperties: Record<string, Property>;
23
- setOriginProperties: React.Dispatch<React.SetStateAction<Record<string, Property>>>;
24
-
25
- }
26
-
27
- export type DataTypeMapping = {
28
- from: DataType;
29
- fromSubtype?: DataType;
30
- to: DataType;
31
- toSubtype?: DataType;
32
- }
@@ -1 +0,0 @@
1
- export * from "./column_mapping";
package/src/utils/data.ts DELETED
@@ -1,223 +0,0 @@
1
- import { DataType, Entity, EntityReference, getPropertyInPath, Properties } from "@firecms/core";
2
- import { unflattenObject } from "./file_to_json";
3
-
4
- type DataTypeMapping = {
5
- from: DataType;
6
- fromSubtype?: DataType;
7
- to: DataType;
8
- toSubtype?: DataType;
9
- }
10
-
11
- export function convertDataToEntity(data: Record<any, any>,
12
- idColumn: string | undefined,
13
- headersMapping: Record<string, string | null>,
14
- properties: Properties,
15
- propertiesMapping: Record<string, DataTypeMapping>,
16
- path: string): Entity<any> {
17
- const flatObject = flattenEntry(data);
18
- if (idColumn)
19
- delete flatObject[idColumn];
20
- const mappedKeysObject = Object.entries(flatObject)
21
- .map(([key, value]) => {
22
- const mappedKey = headersMapping[key] ?? key;
23
-
24
- const mappedProperty = getPropertyInPath(properties, mappedKey);
25
- if (!mappedProperty)
26
- return {};
27
-
28
- const propertyMapping = propertiesMapping[mappedKey];
29
- let valueResult = value;
30
- if (propertyMapping) {
31
- valueResult = processValueMapping(value, propertyMapping);
32
- }
33
- return ({
34
- [mappedKey]: valueResult
35
- });
36
- })
37
- .reduce((acc, curr) => ({ ...acc, ...curr }), {});
38
- const values = unflattenObject(mappedKeysObject);
39
- let id = idColumn ? data[idColumn] : undefined;
40
- if (typeof id === "string") {
41
- id = id.trim();
42
- } else if (typeof id === "number") {
43
- id = id.toString();
44
- } else if (typeof id === "boolean") {
45
- id = id.toString();
46
- } else if (id instanceof Date) {
47
- id = id.toISOString();
48
- } else if (id && "toString" in id) {
49
- id = id.toString();
50
- }
51
-
52
- return {
53
- id,
54
- values,
55
- path
56
- };
57
- }
58
-
59
- export function flattenEntry(obj: any, parent = ""): any {
60
- return Object.keys(obj).reduce((acc, key) => {
61
- const prefixedKey = parent ? `${parent}.${key}` : key;
62
-
63
- if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) {
64
- Object.assign(acc, flattenEntry(obj[key], prefixedKey));
65
- } else {
66
- // @ts-ignore
67
- acc[prefixedKey] = obj[key];
68
- }
69
-
70
- return acc;
71
- }, {});
72
- }
73
-
74
- // export function convertDataEntryValue({
75
- // key,
76
- // fullKey,
77
- // value,
78
- // idColumn,
79
- // headersMapping,
80
- // properties,
81
- // propertiesMapping
82
- // }: {
83
- // key?: string,
84
- // fullKey: string,
85
- // value: any,
86
- // idColumn?: string,
87
- // headersMapping: Record<string, string | null>,
88
- // properties: Properties,
89
- // propertiesMapping: Record<string, DataTypeMapping>
90
- // }): any {
91
- //
92
- // if (value === undefined) return value;
93
- // if (value === null) return value;
94
- //
95
- // if (Array.isArray(value)) {
96
- // const mappedKey = headersMapping[fullKey] || fullKey;
97
- // const valueMapping = propertiesMapping[mappedKey];
98
- // return processValueMapping(value, valueMapping);
99
- // // return value.map(v => convertDataEntryValue({ value: v, fullKey, idColumn, headersMapping, propertiesMapping }));
100
- // } else if (typeof value === "object") {
101
- // return convertDataObjectValue({
102
- // key,
103
- // fullKey,
104
- // value,
105
- // idColumn,
106
- // headersMapping,
107
- // properties,
108
- // propertiesMapping
109
- // });
110
- // } else {
111
- // const mappedKey = headersMapping[fullKey] || fullKey;
112
- // const valueMapping = propertiesMapping[mappedKey];
113
- // return processValueMapping(value, valueMapping);
114
- // }
115
- // }
116
-
117
- // export function convertDataObjectValue({
118
- // key,
119
- // fullKey,
120
- // value,
121
- // idColumn,
122
- // headersMapping,
123
- // properties,
124
- // propertiesMapping
125
- // }: {
126
- // key?: string,
127
- // fullKey?: string,
128
- // value: object,
129
- // idColumn?: string,
130
- // headersMapping: Record<string, string | null>,
131
- // properties: Properties,
132
- // propertiesMapping: Record<string, DataTypeMapping>
133
- // }): object {
134
- //
135
- // if (value instanceof Date) {
136
- // const mappedKey = fullKey ? headersMapping[fullKey] || fullKey : undefined;
137
- // const valueMapping = mappedKey ? propertiesMapping[mappedKey] : undefined;
138
- // return processValueMapping(value, valueMapping);
139
- // }
140
- //
141
- // return Object.entries(value)
142
- // .map(([childKey, childValue]) => {
143
- // const childFullKey = fullKey ? `${fullKey}.${childKey}` : childKey;
144
- // const mappedKey = headersMapping[childFullKey] ?? childFullKey;
145
- // const mappedKeyLastPart = mappedKey.split(".").slice(-1)[0];
146
- // const property = getPropertyInPath(properties, mappedKey);
147
- // // if (!property) {
148
- // // console.log("ppp", { properties, mappedKey, })
149
- // // return {};
150
- // // }
151
- // return ({
152
- // [mappedKeyLastPart]: convertDataEntryValue({
153
- // key: childKey,
154
- // fullKey: childFullKey,
155
- // value: childValue,
156
- // idColumn,
157
- // headersMapping,
158
- // properties,
159
- // propertiesMapping
160
- // })
161
- // });
162
- // })
163
- // .reduce((acc, curr) => ({ ...acc, ...curr }), {});
164
- // }
165
-
166
- export function processValueMapping(value: any, valueMapping?: DataTypeMapping): any {
167
- if (valueMapping === undefined) return value;
168
- const {
169
- from,
170
- to
171
- } = valueMapping;
172
- if (from === "array" && to === "array" && valueMapping.fromSubtype && valueMapping.toSubtype && Array.isArray(value)) {
173
- return value.map(v => processValueMapping(v, {
174
- from: valueMapping.fromSubtype!,
175
- to: valueMapping.toSubtype!
176
- }));
177
- } else if (from === "string" && to === "number" && typeof value === "string") {
178
- return Number(value);
179
- } else if (from === "string" && to === "array" && valueMapping.toSubtype && typeof value === "string") {
180
- return value.split(",").map((v: string) => processValueMapping(v, {
181
- from: "string",
182
- to: valueMapping.toSubtype!
183
- }));
184
- } else if (from === "string" && to === "boolean") {
185
- return value === "true";
186
- } else if (from === "number" && to === "boolean") {
187
- return value === 1;
188
- } else if (from === "boolean" && to === "number") {
189
- return value ? 1 : 0;
190
- } else if (from === "boolean" && to === "string") {
191
- return value ? "true" : "false";
192
- } else if (from === "number" && to === "string" && typeof value === "number") {
193
- return value.toString();
194
- } else if (from === "string" && to === "array" && typeof value === "string") {
195
- return value.split(",").map((v: string) => v.trim());
196
- } else if (from === "string" && to === "date" && typeof value === "string") {
197
- try {
198
- return new Date(value);
199
- } catch (e) {
200
- return value;
201
- }
202
- } else if (from === "date" && to === "string") {
203
- return value instanceof Date && value.toISOString();
204
- } else if (from === "number" && to === "date" && typeof value === "number") {
205
- try {
206
- return new Date(value);
207
- } catch (e) {
208
- return value;
209
- }
210
- } else if (from === "string" && to === "reference" && typeof value === "string") {
211
- // split value into path and entityId (entityId is the last part of the path, after the last /)
212
- const path = value.split("/").slice(0, -1).join("/");
213
- const entityId = value.split("/").slice(-1)[0];
214
- return new EntityReference(entityId, path);
215
-
216
- } else if (from === to) {
217
- return value;
218
- } else if (from === "array" && to === "string" && Array.isArray(value)) {
219
- return value.join(",");
220
- }
221
-
222
- return value;
223
- }
@@ -1,88 +0,0 @@
1
- import * as XLSX from "xlsx";
2
-
3
- export function convertFileToJson(file: File): Promise<object[]> {
4
- return new Promise((resolve, reject) => {
5
- // check if file is a JSON file
6
- if (file.type === "application/json") {
7
- console.debug("Converting JSON file to JSON", file.name);
8
- const reader = new FileReader();
9
- reader.onload = function (e) {
10
- const data = e.target?.result as string;
11
- const jsonData = JSON.parse(data);
12
- if (!Array.isArray(jsonData)) {
13
- reject(new Error("JSON file should contain an array of objects"));
14
- }
15
- resolve(jsonData);
16
- };
17
- reader.readAsText(file);
18
- } else {
19
- console.debug("Converting Excel file to JSON", file.name);
20
- const reader = new FileReader();
21
- reader.onload = function (e) {
22
-
23
- const data = new Uint8Array(e.target?.result as ArrayBuffer);
24
- const workbook = XLSX.read(data,
25
- {
26
- type: "array",
27
- codepage: 65001,
28
- cellDates: true,
29
- });
30
- const worksheetName = workbook.SheetNames[0];
31
- const worksheet = workbook.Sheets[worksheetName];
32
- const parsedData: Array<any> = XLSX.utils.sheet_to_json(worksheet);
33
- const cleanedData = parsedData.map(mapJsonParse);
34
- const jsonData = cleanedData.map(unflattenObject);
35
- resolve(jsonData);
36
- };
37
- reader.readAsArrayBuffer(file);
38
- }
39
- });
40
- }
41
-
42
- function mapJsonParse(obj: Record<string, any>) {
43
- return Object.keys(obj).reduce((acc: Record<string, any>, key) => {
44
- try {
45
- acc[key] = JSON.parse(obj[key]);
46
- } catch (e) {
47
- acc[key] = obj[key];
48
- }
49
- return acc;
50
- }, {});
51
- }
52
-
53
- /**
54
- * Take an object with keys of type `address.street`, `address.city` and
55
- * convert it to an object with nested objects like `{ address: { street: ..., city: ... } }`
56
- * @param flatObj
57
- */
58
- export function unflattenObject(flatObj: { [key: string]: any }) {
59
- return Object.keys(flatObj).reduce((nestedObj, key) => {
60
- let currentObj = nestedObj;
61
- const keyParts = key.split(".");
62
- keyParts.forEach((keyPart, i) => {
63
-
64
- if (/^[\w]+\[\d+\]$/.test(keyPart)) {
65
- const mainPropertyName = keyPart.slice(0, keyPart.indexOf("["));
66
- const index = parseInt(keyPart.slice(keyPart.indexOf("[") + 1, keyPart.indexOf("]")));
67
-
68
- if (!currentObj[mainPropertyName]) {
69
- currentObj[mainPropertyName] = []
70
- }
71
-
72
- if (i !== keyParts.length - 1) {
73
- currentObj[mainPropertyName][index] = currentObj[mainPropertyName][index] || {};
74
- currentObj = currentObj[mainPropertyName][index];
75
- } else {
76
- currentObj[mainPropertyName][index] = flatObj[key];
77
- }
78
- } else if (i !== keyParts.length - 1) {
79
- currentObj[keyPart] = currentObj[keyPart] || {};
80
- currentObj = currentObj[keyPart];
81
- } else {
82
- currentObj[keyPart] = flatObj[key];
83
- }
84
-
85
- });
86
- return nestedObj;
87
- }, {} as { [key: string]: any });
88
- }
@@ -1,27 +0,0 @@
1
- import { DataType } from "@firecms/core";
2
-
3
- export function getInferenceType(value: any): DataType {
4
- if (typeof value === "number")
5
- return "number";
6
- else if (typeof value === "string")
7
- return "string";
8
- else if (typeof value === "boolean")
9
- return "boolean";
10
- else if (value instanceof Date)
11
- return "date";
12
- else if (Array.isArray(value))
13
- return "array";
14
- return "map";
15
- }
16
-
17
-
18
- function isUnixTimestamp(num: number): boolean {
19
- const numString = num.toString();
20
- // check if the number has 13 digits
21
- const isLengthValid = numString.length === 13;
22
-
23
- // check if it falls in the expected Unix timestamp range (from 1970 to 2100)
24
- const isInRange = num >= 0 && num <= 4102444800000;
25
-
26
- return isLengthValid && isInRange;
27
- }
@@ -1,59 +0,0 @@
1
- import { DataType, getPropertyInPath, Properties, Property } from "@firecms/core";
2
- import { DataTypeMapping } from "../types";
3
-
4
- export function getPropertiesMapping(originProperties: Properties, newProperties: Properties): Record<string, DataTypeMapping> {
5
-
6
- function updateMapping(properties: Record<string, Property>, namespace?: string): Record<string, DataTypeMapping> {
7
-
8
- const dataMapping: Record<string, DataTypeMapping> = {};
9
-
10
- Object.keys(properties).forEach((key) => {
11
-
12
- const currentKey = namespace ? `${namespace}.${key}` : key;
13
-
14
- const property = getPropertyInPath(properties, key) as Property;
15
- const inferredProperty = getPropertyInPath(originProperties, currentKey) as Property;
16
-
17
- if (property) {
18
- if (property.dataType === "map" && property.properties) {
19
- const nestedMapping = updateMapping(property.properties as Record<string, Property>, currentKey);
20
- Object.keys(nestedMapping).forEach((nestedKey) => {
21
- dataMapping[`${currentKey}.${nestedKey}`] = nestedMapping[nestedKey];
22
- });
23
- return;
24
- }
25
-
26
- if (inferredProperty) {
27
-
28
- const from = inferredProperty.dataType;
29
- const to = property.dataType;
30
- let fromSubtype: DataType | undefined;
31
- let toSubtype: DataType | undefined;
32
-
33
- if (property.dataType === "array" && property.of) {
34
- toSubtype = (property.of as Property).dataType;
35
- }
36
-
37
- if (inferredProperty?.dataType === "array" && inferredProperty?.of) {
38
- fromSubtype = (inferredProperty.of as Property).dataType;
39
- }
40
-
41
- if (from !== to || fromSubtype !== toSubtype) {
42
- dataMapping[key] = {
43
- from,
44
- to,
45
- fromSubtype,
46
- toSubtype
47
- };
48
- }
49
- }
50
-
51
- }
52
-
53
- });
54
-
55
- return dataMapping;
56
- }
57
-
58
- return updateMapping(newProperties);
59
- }
@@ -1,4 +0,0 @@
1
- export * from "./file_to_json";
2
- export * from "./data";
3
- export * from "./get_import_inference_type";
4
- export * from "./get_properties_mapping";