@forestadmin/datasource-replica 1.0.0 → 1.0.2-alpha-widgets.1
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/cache-interface/collection.d.ts +54 -0
- package/dist/cache-interface/collection.js +89 -0
- package/dist/cache-interface/datasource.d.ts +14 -0
- package/dist/cache-interface/datasource.js +33 -0
- package/dist/decorators/schema/collection.d.ts +8 -0
- package/dist/decorators/schema/collection.js +35 -0
- package/dist/decorators/schema/data-source.d.ts +9 -0
- package/dist/decorators/schema/data-source.js +18 -0
- package/dist/decorators/sync/collection.d.ts +15 -0
- package/dist/decorators/sync/collection.js +107 -0
- package/dist/decorators/sync/data-source.d.ts +9 -0
- package/dist/decorators/sync/data-source.js +15 -0
- package/dist/decorators/write/collection.d.ts +11 -0
- package/dist/decorators/write/collection.js +54 -0
- package/dist/decorators/write/data-source.d.ts +8 -0
- package/dist/decorators/write/data-source.js +23 -0
- package/dist/flattener.d.ts +3 -0
- package/dist/flattener.js +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/options/flattener/options.d.ts +5 -0
- package/dist/options/flattener/options.js +103 -0
- package/dist/options/flattener/schema.d.ts +8 -0
- package/dist/options/flattener/schema.js +39 -0
- package/dist/options/index.d.ts +5 -0
- package/dist/options/index.js +37 -0
- package/dist/options/schema/analyzer.d.ts +11 -0
- package/dist/options/schema/analyzer.js +53 -0
- package/dist/options/schema/index.d.ts +6 -0
- package/dist/options/schema/index.js +43 -0
- package/dist/options/utils.d.ts +3 -0
- package/dist/options/utils.js +8 -0
- package/dist/sequelize.d.ts +6 -0
- package/dist/sequelize.js +122 -0
- package/dist/synchronization/analysis-passthrough.d.ts +20 -0
- package/dist/synchronization/analysis-passthrough.js +79 -0
- package/dist/synchronization/cache-target.d.ts +15 -0
- package/dist/synchronization/cache-target.js +85 -0
- package/dist/synchronization/customer-source.d.ts +31 -0
- package/dist/synchronization/customer-source.js +188 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.js +11 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +35 -0
- package/package.json +7 -7
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const types_1 = require("../../types");
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
function listFields(field, depth) {
|
|
6
|
+
if (depth === 0)
|
|
7
|
+
return [];
|
|
8
|
+
if (Array.isArray(field))
|
|
9
|
+
return listFields(field[0], depth);
|
|
10
|
+
if ((0, types_1.isLeafField)(field))
|
|
11
|
+
return [''];
|
|
12
|
+
return Object.entries(field).flatMap(([fieldName, rawSubField]) => {
|
|
13
|
+
return listFields(rawSubField, depth - 1).map(f => (f ? `${fieldName}.${f}` : fieldName));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function getField(field, path) {
|
|
17
|
+
if (!path)
|
|
18
|
+
return field;
|
|
19
|
+
const [prefix, suffix] = path.split(/\.(.*)/);
|
|
20
|
+
const subField = field[prefix];
|
|
21
|
+
if (!subField)
|
|
22
|
+
throw new Error(`Field ${prefix} not found in ${JSON.stringify(field)}}`);
|
|
23
|
+
return getField(subField, suffix);
|
|
24
|
+
}
|
|
25
|
+
function getAutoFlattenHelper(field, distance) {
|
|
26
|
+
const options = { asModels: [], asFields: [] };
|
|
27
|
+
if (!(0, types_1.isLeafField)(field)) {
|
|
28
|
+
for (const [fieldName, subField] of Object.entries(field)) {
|
|
29
|
+
let subOptions;
|
|
30
|
+
if ((0, types_1.isLeafField)(subField)) {
|
|
31
|
+
subOptions = { asFields: [], asModels: [] };
|
|
32
|
+
if (distance > 0)
|
|
33
|
+
options.asFields.push(fieldName);
|
|
34
|
+
}
|
|
35
|
+
else if (Array.isArray(subField)) {
|
|
36
|
+
subOptions = getAutoFlattenHelper(subField[0], 0);
|
|
37
|
+
options.asModels.push(fieldName);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
subOptions = getAutoFlattenHelper(subField, distance + 1);
|
|
41
|
+
}
|
|
42
|
+
options.asFields.push(...subOptions.asFields.map(f => `${fieldName}.${f}`));
|
|
43
|
+
options.asModels.push(...subOptions.asModels.map(f => `${fieldName}.${f}`));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
}
|
|
48
|
+
function getAutoFlattenOptions(schema) {
|
|
49
|
+
return Object.fromEntries(schema.map(({ name, fields }) => {
|
|
50
|
+
const { asFields, asModels } = getAutoFlattenHelper(fields, 0);
|
|
51
|
+
asFields.sort();
|
|
52
|
+
asModels.sort();
|
|
53
|
+
return [name, { asFields, asModels }];
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
async function getManualFlattenOptions(schema, rawOptions) {
|
|
57
|
+
var _a;
|
|
58
|
+
const rawFlattenOptions = await (0, utils_1.resolveValueOrPromiseOrFactory)(rawOptions.flattenOptions);
|
|
59
|
+
const result = {};
|
|
60
|
+
for (const [collectionName, collectionOptions] of Object.entries(rawFlattenOptions ?? {})) {
|
|
61
|
+
const field = schema.find(s => s.name === collectionName)?.fields;
|
|
62
|
+
if (!field)
|
|
63
|
+
throw new Error(`Collection ${collectionName} not found in schema`);
|
|
64
|
+
const asModels = [...(collectionOptions.asModels ?? [])].sort();
|
|
65
|
+
const asFields = (collectionOptions.asFields ?? [])
|
|
66
|
+
// expand fields and objects to a list of absolute paths
|
|
67
|
+
.flatMap(entry => {
|
|
68
|
+
const path = typeof entry === 'string' ? entry : entry.field;
|
|
69
|
+
const depth = typeof entry === 'string' ? 99 : entry.level;
|
|
70
|
+
const expanded = listFields(getField(field, path), depth);
|
|
71
|
+
return expanded.map(f => (f ? `${path}.${f}` : path));
|
|
72
|
+
})
|
|
73
|
+
// Keep only the paths which do something.
|
|
74
|
+
.filter(fullPath => {
|
|
75
|
+
// get the longest path in asModels which is a prefix of path
|
|
76
|
+
const prefix = collectionOptions.asModels
|
|
77
|
+
.filter(p => fullPath.startsWith(p))
|
|
78
|
+
.sort((a, b) => b.length - a.length)?.[0];
|
|
79
|
+
const suffix = prefix ? fullPath.substring(prefix.length + 1) : fullPath;
|
|
80
|
+
return suffix.includes('.');
|
|
81
|
+
})
|
|
82
|
+
.sort();
|
|
83
|
+
result[collectionName] = { asModels, asFields };
|
|
84
|
+
}
|
|
85
|
+
for (const collection of schema) {
|
|
86
|
+
result[_a = collection.name] ?? (result[_a] = { asFields: [], asModels: [] });
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
async function computeFlattenOptions(schema, rawOptions) {
|
|
91
|
+
if (rawOptions.flattenMode === 'auto') {
|
|
92
|
+
return getAutoFlattenOptions(schema);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
return await getManualFlattenOptions(schema, rawOptions);
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
e.message = `Error while computing flattenOptions: ${e.message}`;
|
|
99
|
+
throw e;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.default = computeFlattenOptions;
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vcHRpb25zL2ZsYXR0ZW5lci9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBT0EsdUNBQTBDO0FBQzFDLG9DQUEwRDtBQUsxRCxTQUFTLFVBQVUsQ0FBQyxLQUFZLEVBQUUsS0FBYTtJQUM3QyxJQUFJLEtBQUssS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDM0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM3RCxJQUFJLElBQUEsbUJBQVcsRUFBQyxLQUFLLENBQUM7UUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFcEMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxFQUFFLEVBQUU7UUFDaEUsT0FBTyxVQUFVLENBQUMsV0FBVyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDNUYsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsS0FBWSxFQUFFLElBQVk7SUFDMUMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUV4QixNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFD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
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CollectionReplicaSchema, ResolvedOptions } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Abuse the flattenRecordRec logic with ❤️
|
|
4
|
+
* And then fix the _fpid and _fid fields which are not correct
|
|
5
|
+
*/
|
|
6
|
+
export declare function flattenCollectionSchema(schema: CollectionReplicaSchema, asFields: string[], asModels: string[]): CollectionReplicaSchema[];
|
|
7
|
+
export declare function flattenSchema(schema: CollectionReplicaSchema[], flattenOptions: ResolvedOptions['flattenOptions']): CollectionReplicaSchema[];
|
|
8
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.flattenSchema = exports.flattenCollectionSchema = void 0;
|
|
7
|
+
const flattener_1 = __importDefault(require("../../flattener"));
|
|
8
|
+
const types_1 = require("../../types");
|
|
9
|
+
/**
|
|
10
|
+
* Abuse the flattenRecordRec logic with ❤️
|
|
11
|
+
* And then fix the _fpid and _fid fields which are not correct
|
|
12
|
+
*/
|
|
13
|
+
function flattenCollectionSchema(schema, asFields, asModels) {
|
|
14
|
+
const recordWithCollection = { collection: schema.name, record: schema.fields };
|
|
15
|
+
const output = (0, flattener_1.default)(recordWithCollection, schema.fields, asFields, asModels);
|
|
16
|
+
for (let i = output.length - 2; i >= 0; i -= 1) {
|
|
17
|
+
const { collection, record } = output[i];
|
|
18
|
+
const parent = output.slice(i + 1).find(r => collection.startsWith(r.collection));
|
|
19
|
+
const [parentPkName, parentPkField] = Object.entries(parent.record).find(([, v]) => (0, types_1.isLeafField)(v) ? v.isPrimaryKey : false) ?? ['_fid', { type: 'String', isPrimaryKey: true }];
|
|
20
|
+
record._fpid = {
|
|
21
|
+
type: parentPkField.type,
|
|
22
|
+
unique: !record._fid.endsWith('.0'),
|
|
23
|
+
reference: {
|
|
24
|
+
targetCollection: parent.collection,
|
|
25
|
+
targetField: parentPkName,
|
|
26
|
+
relationName: 'parent',
|
|
27
|
+
relationInverse: collection.substring(parent.collection.length + 1),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
record._fid = { type: 'String', isPrimaryKey: true };
|
|
31
|
+
}
|
|
32
|
+
return output.map(({ collection, record }) => ({ name: collection, fields: record }));
|
|
33
|
+
}
|
|
34
|
+
exports.flattenCollectionSchema = flattenCollectionSchema;
|
|
35
|
+
function flattenSchema(schema, flattenOptions) {
|
|
36
|
+
return schema.flatMap(collectionSchema => flattenCollectionSchema(collectionSchema, flattenOptions?.[collectionSchema.name]?.asFields ?? [], flattenOptions?.[collectionSchema.name]?.asModels ?? []));
|
|
37
|
+
}
|
|
38
|
+
exports.flattenSchema = flattenSchema;
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29wdGlvbnMvZmxhdHRlbmVyL3NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQSxnRUFBNEM7QUFDNUMsdUNBQTBDO0FBRTFDOzs7R0FHRztBQUNILFNBQWdCLHVCQUF1QixDQUNyQyxNQUErQixFQUMvQixRQUFrQixFQUNsQixRQUFrQjtJQUVsQixNQUFNLG9CQUFvQixHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoRixNQUFNLE1BQU0sR0FBRyxJQUFBLG1CQUFhLEVBQUMsb0JBQW9CLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFdEYsS0FBSyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDOUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNsRixNQUFNLENBQUMsWUFBWSxFQUFFLGFBQWEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ2pGLElBQUEsbUJBQVcsRUFBQyxDQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUNqRCxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUV0RCxNQUFNLENBQUMsS0FBSyxHQUFHO1lBQ2IsSUFBSSxFQUFFLGFBQWEsQ0FBQyxJQUFJO1lBQ3hCLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztZQUNuQyxTQUFTLEVBQUU7Z0JBQ1QsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLFVBQVU7Z0JBQ25DLFdBQVcsRUFBRSxZQUFZO2dCQUN6QixZQUFZLEVBQUUsUUFBUTtnQkFDdEIsZUFBZSxFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2FBQ3BFO1NBQ0YsQ0FBQztRQUNGLE1BQU0sQ0FBQyxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztLQUN0RDtJQUVELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hGLENBQUM7QUE3QkQsMERBNkJDO0FBRUQsU0FBZ0IsYUFBYSxDQUMzQixNQUFpQyxFQUNqQyxjQUFpRDtJQUVqRCxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUN2Qyx1QkFBdUIsQ0FDckIsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsSUFBSSxFQUFFLEVBQ3ZELGNBQWMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsSUFBSSxFQUFFLENBQ3hELENBQ0YsQ0FBQztBQUNKLENBQUM7QUFYRCxzQ0FXQyJ9
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ReplicaDataSourceOptions, ResolvedOptions } from '../types';
|
|
2
|
+
import type { Logger } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import type { Sequelize } from 'sequelize';
|
|
4
|
+
export default function resolveOptions(options: ReplicaDataSourceOptions, logger: Logger, connection: Sequelize): Promise<ResolvedOptions>;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const options_1 = __importDefault(require("./flattener/options"));
|
|
7
|
+
const schema_1 = require("./flattener/schema");
|
|
8
|
+
const schema_2 = require("./schema");
|
|
9
|
+
const analysis_passthrough_1 = __importDefault(require("../synchronization/analysis-passthrough"));
|
|
10
|
+
const customer_source_1 = __importDefault(require("../synchronization/customer-source"));
|
|
11
|
+
async function resolveOptions(options, logger, connection) {
|
|
12
|
+
let source = new customer_source_1.default(connection, options, logger);
|
|
13
|
+
let resolvedSchema = await (0, schema_2.getSchema)(options, connection);
|
|
14
|
+
if (!resolvedSchema) {
|
|
15
|
+
const passThrough = new analysis_passthrough_1.default(connection, source, options.cacheNamespace);
|
|
16
|
+
await source.start(passThrough); // This should block until the analysis is done.
|
|
17
|
+
source = passThrough;
|
|
18
|
+
resolvedSchema = await (0, schema_2.buildSchema)(passThrough.nodes);
|
|
19
|
+
}
|
|
20
|
+
const flattenOptions = await (0, options_1.default)(resolvedSchema, options);
|
|
21
|
+
return {
|
|
22
|
+
cacheInto: options.cacheInto,
|
|
23
|
+
cacheNamespace: options.cacheNamespace,
|
|
24
|
+
createRecordHandler: options.createRecordHandler,
|
|
25
|
+
deleteRecordHandler: options.deleteRecordHandler,
|
|
26
|
+
flattenOptions,
|
|
27
|
+
flattenSchema: (0, schema_1.flattenSchema)(resolvedSchema, flattenOptions),
|
|
28
|
+
logger,
|
|
29
|
+
pullDeltaOnAfterWrite: options.pullDeltaHandler && options.pullDeltaOnAfterWrite,
|
|
30
|
+
pullDeltaOnBeforeAccess: options.pullDeltaHandler && options.pullDeltaOnBeforeAccess,
|
|
31
|
+
schema: resolvedSchema,
|
|
32
|
+
source,
|
|
33
|
+
updateRecordHandler: options.updateRecordHandler,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
exports.default = resolveOptions;
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3B0aW9ucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVNBLGtFQUF3RDtBQUN4RCwrQ0FBbUQ7QUFDbkQscUNBQWtEO0FBQ2xELG1HQUF5RTtBQUN6RSx5RkFBZ0U7QUFFakQsS0FBSyxVQUFVLGNBQWMsQ0FDMUMsT0FBaUMsRUFDakMsTUFBYyxFQUNkLFVBQXFCO0lBRXJCLElBQUksTUFBTSxHQUEwQixJQUFJLHlCQUFjLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNwRixJQUFJLGNBQWMsR0FBOEIsTUFBTSxJQUFBLGtCQUFTLEVBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRXJGLElBQUksQ0FBQyxjQUFjLEVBQUU7UUFDbkIsTUFBTSxXQUFXLEdBQUcsSUFBSSw4QkFBa0IsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN2RixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxnREFBZ0Q7UUFFakYsTUFBTSxHQUFHLFdBQVcsQ0FBQztRQUNyQixjQUFjLEdBQUcsTUFBTSxJQUFBLG9CQUFXLEVBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3ZEO0lBRUQsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFBLGlCQUFxQixFQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUU1RSxPQUFPO1FBQ0wsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1FBQzVCLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztRQUN0QyxtQkFBbUIsRUFBRSxPQUFPLENBQUMsbUJBQW1CO1FBQ2hELG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxtQkFBbUI7UUFDaEQsY0FBYztRQUNkLGFBQWEsRUFBRSxJQUFBLHNCQUFhLEVBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQztRQUM1RCxNQUFNO1FBQ04scUJBQXFCLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxxQkFBcUI7UUFDaEYsdUJBQXVCLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixJQUFJLE9BQU8sQ0FBQyx1QkFBdUI7UUFDcEYsTUFBTSxFQUFFLGNBQWM7UUFDdEIsTUFBTTtRQUNOLG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxtQkFBbUI7S0FDakQsQ0FBQztBQUNKLENBQUM7QUFoQ0QsaUNBZ0NDIn0=
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PrimitiveTypes } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
export type Primitive = 'Null' | 'Object' | 'Array' | 'Integer' | PrimitiveTypes;
|
|
3
|
+
export type NodeStudy = {
|
|
4
|
+
types: Partial<Record<Primitive, number>>;
|
|
5
|
+
seen: number;
|
|
6
|
+
object?: Record<string, NodeStudy>;
|
|
7
|
+
arrayElement?: NodeStudy;
|
|
8
|
+
};
|
|
9
|
+
export declare function createNode(): NodeStudy;
|
|
10
|
+
export declare function walkNode(node: NodeStudy, sample: unknown): void;
|
|
11
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.walkNode = exports.createNode = void 0;
|
|
4
|
+
function getSampleType(sample) {
|
|
5
|
+
if (sample === null)
|
|
6
|
+
return 'Null';
|
|
7
|
+
if (sample instanceof Buffer)
|
|
8
|
+
return 'Binary';
|
|
9
|
+
if (sample instanceof Date)
|
|
10
|
+
return 'Date';
|
|
11
|
+
if (Array.isArray(sample))
|
|
12
|
+
return 'Array';
|
|
13
|
+
if (sample?.constructor === Object)
|
|
14
|
+
return 'Object';
|
|
15
|
+
if (Number.isInteger(sample))
|
|
16
|
+
return 'Integer';
|
|
17
|
+
const type = typeof sample;
|
|
18
|
+
return (type[0].toUpperCase() + type.slice(1));
|
|
19
|
+
}
|
|
20
|
+
function annotateNode(node, sample) {
|
|
21
|
+
const type = getSampleType(sample);
|
|
22
|
+
// Increment counters
|
|
23
|
+
node.seen += 1;
|
|
24
|
+
node.types[type] = (node.types[type] || 0) + 1;
|
|
25
|
+
}
|
|
26
|
+
function walkArrayNode(node, sample) {
|
|
27
|
+
if (!node.arrayElement)
|
|
28
|
+
node.arrayElement = createNode();
|
|
29
|
+
for (const subSample of sample)
|
|
30
|
+
walkNode(node.arrayElement, subSample);
|
|
31
|
+
}
|
|
32
|
+
function walkObjectNode(node, sample) {
|
|
33
|
+
if (!node.object)
|
|
34
|
+
node.object = {};
|
|
35
|
+
for (const [key, subSample] of Object.entries(sample)) {
|
|
36
|
+
if (!node.object[key])
|
|
37
|
+
node.object[key] = createNode();
|
|
38
|
+
walkNode(node.object[key], subSample);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function createNode() {
|
|
42
|
+
return { types: {}, seen: 0 };
|
|
43
|
+
}
|
|
44
|
+
exports.createNode = createNode;
|
|
45
|
+
function walkNode(node, sample) {
|
|
46
|
+
if (Array.isArray(sample))
|
|
47
|
+
walkArrayNode(node, sample);
|
|
48
|
+
if (sample?.constructor === Object)
|
|
49
|
+
walkObjectNode(node, sample);
|
|
50
|
+
annotateNode(node, sample);
|
|
51
|
+
}
|
|
52
|
+
exports.walkNode = walkNode;
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3B0aW9ucy9zY2hlbWEvYW5hbHl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBWUEsU0FBUyxhQUFhLENBQUMsTUFBZTtJQUNwQyxJQUFJLE1BQU0sS0FBSyxJQUFJO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDbkMsSUFBSSxNQUFNLFlBQVksTUFBTTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQzlDLElBQUksTUFBTSxZQUFZLElBQUk7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUMxQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxPQUFPLENBQUM7SUFDMUMsSUFBSSxNQUFNLEVBQUUsV0FBVyxLQUFLLE1BQU07UUFBRSxPQUFPLFFBQVEsQ0FBQztJQUNwRCxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFFL0MsTUFBTSxJQUFJLEdBQUcsT0FBTyxNQUFNLENBQUM7SUFFM0IsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFjLENBQUM7QUFDOUQsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLElBQWUsRUFBRSxNQUFlO0lBQ3BELE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVuQyxxQkFBcUI7SUFDckIsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7SUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakQsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLElBQWUsRUFBRSxNQUFpQjtJQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVk7UUFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQ3pELEtBQUssTUFBTSxTQUFTLElBQUksTUFBTTtRQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3pFLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxJQUFlLEVBQUUsTUFBK0I7SUFDdEUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1FBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFFbkMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1lBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQztRQUN2RCxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUN2QztBQUNILENBQUM7QUFFRCxTQUFnQixVQUFVO0lBQ3hCLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBRkQsZ0NBRUM7QUFFRCxTQUFnQixRQUFRLENBQUMsSUFBZSxFQUFFLE1BQWU7SUFDdkQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUFFLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdkQsSUFBSSxNQUFNLEVBQUUsV0FBVyxLQUFLLE1BQU07UUFBRSxjQUFjLENBQUMsSUFBSSxFQUFFLE1BQWlDLENBQUMsQ0FBQztJQUU1RixZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFMRCw0QkFLQyJ9
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NodeStudy } from './analyzer';
|
|
2
|
+
import type { CollectionReplicaSchema, ReplicaDataSourceOptions } from '../../types';
|
|
3
|
+
import type { Sequelize } from 'sequelize';
|
|
4
|
+
export declare function getSchema(rawOptions: ReplicaDataSourceOptions, connection: Sequelize): Promise<CollectionReplicaSchema[]>;
|
|
5
|
+
export declare function buildSchema(analysis: Record<string, NodeStudy>): Promise<CollectionReplicaSchema[]>;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildSchema = exports.getSchema = void 0;
|
|
4
|
+
const types_1 = require("../../types");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
function convertAnalysisToSchema(node) {
|
|
7
|
+
const types = Object.keys(node.types).filter(t => t !== 'null');
|
|
8
|
+
if (types.length > 1)
|
|
9
|
+
return { type: 'Json' };
|
|
10
|
+
if (types[0] === 'Object') {
|
|
11
|
+
const entries = Object.entries(node.object).map(([k, v]) => [k, convertAnalysisToSchema(v)]);
|
|
12
|
+
return Object.fromEntries(entries);
|
|
13
|
+
}
|
|
14
|
+
if (types[0] === 'Array') {
|
|
15
|
+
return [convertAnalysisToSchema(node.arrayElement)];
|
|
16
|
+
}
|
|
17
|
+
return { type: types[0] };
|
|
18
|
+
}
|
|
19
|
+
async function getSchema(rawOptions, connection) {
|
|
20
|
+
// Schema is provided by the user
|
|
21
|
+
if (rawOptions.schema) {
|
|
22
|
+
return (0, utils_1.resolveValueOrPromiseOrFactory)(rawOptions.schema);
|
|
23
|
+
}
|
|
24
|
+
// Schema was already computed and cached
|
|
25
|
+
const metadata = connection.model(`${rawOptions.cacheNamespace}_metadata`);
|
|
26
|
+
const schemaFromDb = await metadata.findByPk('schema');
|
|
27
|
+
if (schemaFromDb)
|
|
28
|
+
return schemaFromDb.dataValues.content;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
exports.getSchema = getSchema;
|
|
32
|
+
async function buildSchema(analysis) {
|
|
33
|
+
return Object.entries(analysis).map(([name, node]) => {
|
|
34
|
+
const fields = convertAnalysisToSchema(node);
|
|
35
|
+
if ((0, types_1.isLeafField)(fields.id))
|
|
36
|
+
fields.id.isPrimaryKey = true;
|
|
37
|
+
else
|
|
38
|
+
throw new Error(`No primary key found in the schema of the collection ${name}`);
|
|
39
|
+
return { name, fields };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
exports.buildSchema = buildSchema;
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3B0aW9ucy9zY2hlbWEvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0EsdUNBQTBDO0FBQzFDLG9DQUEwRDtBQUUxRCxTQUFTLHVCQUF1QixDQUFDLElBQWU7SUFDOUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBRWhFLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUU5QyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLEVBQUU7UUFDekIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDcEM7SUFFRCxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxPQUFPLEVBQUU7UUFDeEIsT0FBTyxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0tBQ3JEO0lBRUQsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFtQixFQUFFLENBQUM7QUFDOUMsQ0FBQztBQUVNLEtBQUssVUFBVSxTQUFTLENBQzdCLFVBQW9DLEVBQ3BDLFVBQXFCO0lBRXJCLGlDQUFpQztJQUNqQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7UUFDckIsT0FBTyxJQUFBLHNDQUE4QixFQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUMxRDtJQUVELHlDQUF5QztJQUN6QyxNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsVUFBVSxDQUFDLGNBQWMsV0FBVyxDQUFDLENBQUM7SUFDM0UsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZELElBQUksWUFBWTtRQUFFLE9BQU8sWUFBWSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7SUFFekQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBZkQsOEJBZUM7QUFFTSxLQUFLLFVBQVUsV0FBVyxDQUMvQixRQUFtQztJQUVuQyxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNuRCxNQUFNLE1BQU0sR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQTBCLENBQUM7UUFFdEUsSUFBSSxJQUFBLG1CQUFXLEVBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzs7WUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyx3REFBd0QsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUVyRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQzFCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQVhELGtDQVdDIn0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveValueOrPromiseOrFactory = void 0;
|
|
4
|
+
async function resolveValueOrPromiseOrFactory(v) {
|
|
5
|
+
return typeof v === 'function' ? v() : v;
|
|
6
|
+
}
|
|
7
|
+
exports.resolveValueOrPromiseOrFactory = resolveValueOrPromiseOrFactory;
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3B0aW9ucy91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFHTyxLQUFLLFVBQVUsOEJBQThCLENBQ2xELENBQTZCO0lBRTdCLE9BQU8sT0FBTyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFKRCx3RUFJQyJ9
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ReplicaDataSourceOptions, ResolvedOptions } from './types';
|
|
2
|
+
import type { Logger } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import type { Sequelize } from 'sequelize';
|
|
4
|
+
export declare function createSequelize(logger: Logger, options: ReplicaDataSourceOptions): Promise<Sequelize>;
|
|
5
|
+
export declare function createModels(sequelize: Sequelize, options: ResolvedOptions): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=sequelize.d.ts.map
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createModels = exports.createSequelize = void 0;
|
|
4
|
+
const datasource_sql_1 = require("@forestadmin/datasource-sql");
|
|
5
|
+
const sequelize_1 = require("sequelize");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
function convertField(field) {
|
|
8
|
+
if ((0, types_1.isLeafField)(field)) {
|
|
9
|
+
let type = sequelize_1.DataTypes.JSON;
|
|
10
|
+
if (field.type === 'Binary')
|
|
11
|
+
type = sequelize_1.DataTypes.BLOB('long');
|
|
12
|
+
if (field.type === 'Boolean')
|
|
13
|
+
type = sequelize_1.DataTypes.BOOLEAN;
|
|
14
|
+
if (field.type === 'Date')
|
|
15
|
+
type = sequelize_1.DataTypes.DATE;
|
|
16
|
+
if (field.type === 'Dateonly')
|
|
17
|
+
type = sequelize_1.DataTypes.DATEONLY;
|
|
18
|
+
if (field.type === 'Integer')
|
|
19
|
+
type = sequelize_1.DataTypes.INTEGER;
|
|
20
|
+
if (field.type === 'Number')
|
|
21
|
+
type = sequelize_1.DataTypes.DOUBLE;
|
|
22
|
+
if (field.type === 'String')
|
|
23
|
+
type = sequelize_1.DataTypes.TEXT;
|
|
24
|
+
if (field.type === 'Enum')
|
|
25
|
+
type = new sequelize_1.DataTypes.ENUM(...field.enumValues);
|
|
26
|
+
return {
|
|
27
|
+
type,
|
|
28
|
+
allowNull: true,
|
|
29
|
+
primaryKey: field.isPrimaryKey,
|
|
30
|
+
defaultValue: field.defaultValue,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return { type: sequelize_1.DataTypes.JSON, allowNull: true, primaryKey: false };
|
|
34
|
+
}
|
|
35
|
+
async function defineModels(sync, namespace, schema, sequelize) {
|
|
36
|
+
for (const model of schema) {
|
|
37
|
+
const attributes = {};
|
|
38
|
+
for (const [name, field] of Object.entries(model.fields)) {
|
|
39
|
+
attributes[name] = convertField(field);
|
|
40
|
+
}
|
|
41
|
+
const sequelizeModel = sequelize.define(model.name, attributes, {
|
|
42
|
+
timestamps: false,
|
|
43
|
+
tableName: `${namespace}_${model.name}`,
|
|
44
|
+
indexes: Object.entries(model.fields)
|
|
45
|
+
.filter(([, field]) => (0, types_1.isLeafField)(field) && field.reference)
|
|
46
|
+
.map(([name]) => ({ fields: [name] })),
|
|
47
|
+
});
|
|
48
|
+
// eslint-disable-next-line no-await-in-loop
|
|
49
|
+
if (sync)
|
|
50
|
+
await sequelizeModel.sync({ force: true });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function defineRelationships(schema, sequelize) {
|
|
54
|
+
for (const model of schema) {
|
|
55
|
+
const sequelizeModel = sequelize.model(model.name);
|
|
56
|
+
for (const [name, field] of Object.entries(model.fields)) {
|
|
57
|
+
if ((0, types_1.isLeafField)(field) && field.reference) {
|
|
58
|
+
const otherSequelizeModel = sequelize.model(field.reference.targetCollection);
|
|
59
|
+
sequelizeModel.belongsTo(otherSequelizeModel, {
|
|
60
|
+
as: field.reference.relationName,
|
|
61
|
+
foreignKey: name,
|
|
62
|
+
targetKey: field.reference.targetField,
|
|
63
|
+
});
|
|
64
|
+
if (field.reference.relationInverse) {
|
|
65
|
+
const handler = field.unique ? otherSequelizeModel.hasOne : otherSequelizeModel.hasMany;
|
|
66
|
+
handler.call(otherSequelizeModel, sequelizeModel, {
|
|
67
|
+
as: field.reference.relationInverse,
|
|
68
|
+
foreignKey: name,
|
|
69
|
+
sourceKey: field.reference.targetField,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function createSequelize(logger, options) {
|
|
77
|
+
const sequelize = await (0, datasource_sql_1.buildSequelizeInstance)(options.cacheInto, logger, []);
|
|
78
|
+
// This table should never need to change => use normal sync
|
|
79
|
+
await sequelize
|
|
80
|
+
.define(`${options.cacheNamespace}_metadata`, {
|
|
81
|
+
id: { type: sequelize_1.DataTypes.STRING, primaryKey: true },
|
|
82
|
+
content: sequelize_1.DataTypes.JSON,
|
|
83
|
+
})
|
|
84
|
+
.sync();
|
|
85
|
+
// This table should never be reused between runs => force: true
|
|
86
|
+
await sequelize
|
|
87
|
+
.define(`${options.cacheNamespace}_pending_operations`, {
|
|
88
|
+
id: { type: sequelize_1.DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
89
|
+
type: sequelize_1.DataTypes.ENUM('dump', 'delta'),
|
|
90
|
+
content: sequelize_1.DataTypes.JSON,
|
|
91
|
+
})
|
|
92
|
+
.sync({ force: true });
|
|
93
|
+
return sequelize;
|
|
94
|
+
}
|
|
95
|
+
exports.createSequelize = createSequelize;
|
|
96
|
+
async function createModels(sequelize, options) {
|
|
97
|
+
const metadata = sequelize.model(`${options.cacheNamespace}_metadata`);
|
|
98
|
+
const replicaSchema = (await metadata.findByPk('flat_schema'))?.dataValues?.content;
|
|
99
|
+
const sync = JSON.stringify(replicaSchema) !== JSON.stringify(options.flattenSchema);
|
|
100
|
+
// Tell the use what we are doing
|
|
101
|
+
const level = options.cacheInto !== 'sqlite::memory:' ? 'Info' : 'Debug';
|
|
102
|
+
if (!replicaSchema) {
|
|
103
|
+
options.logger(level, `${options.cacheNamespace}: Initializing cache.`);
|
|
104
|
+
}
|
|
105
|
+
else if (sync) {
|
|
106
|
+
options.logger(level, `${options.cacheNamespace}: Schema changed, reinitializing cache.`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
options.logger(level, `${options.cacheNamespace}: Cache already initialized.`);
|
|
110
|
+
}
|
|
111
|
+
// Sync
|
|
112
|
+
await defineModels(sync, options.cacheNamespace, options.flattenSchema, sequelize);
|
|
113
|
+
defineRelationships(options.flattenSchema, sequelize);
|
|
114
|
+
// Set up metadata depending on the type of sync we did
|
|
115
|
+
if (sync) {
|
|
116
|
+
await metadata.truncate();
|
|
117
|
+
await metadata.create({ id: 'schema', content: options.schema });
|
|
118
|
+
await metadata.create({ id: 'flat_schema', content: options.flattenSchema });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.createModels = createModels;
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVsaXplLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NlcXVlbGl6ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFTQSxnRUFBcUU7QUFDckUseUNBQXNDO0FBRXRDLG1DQUFzQztBQUV0QyxTQUFTLFlBQVksQ0FBQyxLQUFZO0lBQ2hDLElBQUksSUFBQSxtQkFBVyxFQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ3RCLElBQUksSUFBSSxHQUFhLHFCQUFTLENBQUMsSUFBSSxDQUFDO1FBQ3BDLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsT0FBTyxDQUFDO1FBQ3ZELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsSUFBSSxDQUFDO1FBQ2pELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxVQUFVO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsUUFBUSxDQUFDO1FBQ3pELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsT0FBTyxDQUFDO1FBQ3ZELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsTUFBTSxDQUFDO1FBQ3JELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRO1lBQUUsSUFBSSxHQUFHLHFCQUFTLENBQUMsSUFBSSxDQUFDO1FBQ25ELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNO1lBQUUsSUFBSSxHQUFHLElBQUkscUJBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFMUUsT0FBTztZQUNM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
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type CacheDataSourceInterface from '../cache-interface/datasource';
|
|
2
|
+
import type { NodeStudy } from '../options/schema/analyzer';
|
|
3
|
+
import type { PullDeltaReason, PullDumpReason, PullDumpResponse, PushDeltaResponse, SynchronizationSource, SynchronizationTarget } from '../types';
|
|
4
|
+
import type { Model, ModelStatic, Sequelize } from 'sequelize';
|
|
5
|
+
export default class AnalysisPassThough implements SynchronizationTarget, SynchronizationSource {
|
|
6
|
+
recordCache: ModelStatic<Model>;
|
|
7
|
+
nodes: Record<string, NodeStudy>;
|
|
8
|
+
target: SynchronizationTarget;
|
|
9
|
+
source: SynchronizationSource;
|
|
10
|
+
namespace: string;
|
|
11
|
+
get requestCache(): CacheDataSourceInterface;
|
|
12
|
+
set requestCache(value: CacheDataSourceInterface);
|
|
13
|
+
constructor(connection: Sequelize, source: SynchronizationSource, namespace: string);
|
|
14
|
+
start(target: SynchronizationTarget): Promise<void>;
|
|
15
|
+
queuePullDump(reason: PullDumpReason): Promise<void>;
|
|
16
|
+
queuePullDelta(reason: PullDeltaReason): Promise<void>;
|
|
17
|
+
applyDump(changes: PullDumpResponse, firstPage: boolean): Promise<void>;
|
|
18
|
+
applyDelta(changes: PushDeltaResponse): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=analysis-passthrough.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const sequelize_1 = require("sequelize");
|
|
4
|
+
const analyzer_1 = require("../options/schema/analyzer");
|
|
5
|
+
class AnalysisPassThough {
|
|
6
|
+
get requestCache() {
|
|
7
|
+
return this.source?.requestCache;
|
|
8
|
+
}
|
|
9
|
+
set requestCache(value) {
|
|
10
|
+
this.source.requestCache = value;
|
|
11
|
+
}
|
|
12
|
+
constructor(connection, source, namespace) {
|
|
13
|
+
this.target = null;
|
|
14
|
+
this.source = source;
|
|
15
|
+
this.recordCache = connection.model(`${namespace}_pending_operations`);
|
|
16
|
+
this.namespace = namespace;
|
|
17
|
+
this.nodes = {};
|
|
18
|
+
}
|
|
19
|
+
async start(target) {
|
|
20
|
+
if (!this.target) {
|
|
21
|
+
// Replay dump/delta that we received while analyzing the schema
|
|
22
|
+
let record = { dataValues: { id: 0 } };
|
|
23
|
+
while (record) {
|
|
24
|
+
// eslint-disable-next-line no-await-in-loop
|
|
25
|
+
record = await this.recordCache.findOne({
|
|
26
|
+
where: { id: { [sequelize_1.Op.gt]: record.dataValues.id } },
|
|
27
|
+
order: [['id', 'ASC']],
|
|
28
|
+
});
|
|
29
|
+
if (record)
|
|
30
|
+
// eslint-disable-next-line no-await-in-loop
|
|
31
|
+
await (record.dataValues.type === 'dump'
|
|
32
|
+
? target.applyDump(...record.dataValues.content)
|
|
33
|
+
: target.applyDelta(...record.dataValues.content));
|
|
34
|
+
}
|
|
35
|
+
await this.recordCache.truncate();
|
|
36
|
+
// Set target so that from now on we just forward the requests
|
|
37
|
+
this.target = target;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error('Already started');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
queuePullDump(reason) {
|
|
44
|
+
return this.source.queuePullDump(reason);
|
|
45
|
+
}
|
|
46
|
+
queuePullDelta(reason) {
|
|
47
|
+
return this.source.queuePullDelta(reason);
|
|
48
|
+
}
|
|
49
|
+
async applyDump(changes, firstPage) {
|
|
50
|
+
if (this.target) {
|
|
51
|
+
await this.target.applyDump(changes, firstPage);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
for (const record of changes.entries) {
|
|
55
|
+
if (!this.nodes[record.collection]) {
|
|
56
|
+
this.nodes[record.collection] = (0, analyzer_1.createNode)();
|
|
57
|
+
}
|
|
58
|
+
(0, analyzer_1.walkNode)(this.nodes[record.collection], record.record);
|
|
59
|
+
}
|
|
60
|
+
await this.recordCache.create({ type: 'dump', content: [changes, firstPage] });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async applyDelta(changes) {
|
|
64
|
+
if (this.target) {
|
|
65
|
+
await this.target.applyDelta(changes);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
for (const record of changes.newOrUpdatedEntries) {
|
|
69
|
+
if (!this.nodes[record.collection]) {
|
|
70
|
+
this.nodes[record.collection] = (0, analyzer_1.createNode)();
|
|
71
|
+
}
|
|
72
|
+
(0, analyzer_1.walkNode)(this.nodes[record.collection], record.record);
|
|
73
|
+
}
|
|
74
|
+
await this.recordCache.create({ type: 'delta', content: [changes] });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.default = AnalysisPassThough;
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHlzaXMtcGFzc3Rocm91Z2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3luY2hyb25pemF0aW9uL2FuYWx5c2lzLXBhc3N0aHJvdWdoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBWUEseUNBQStCO0FBRS9CLHlEQUFrRTtBQUVsRSxNQUFxQixrQkFBa0I7SUFPckMsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQztJQUNuQyxDQUFDO0lBRUQsSUFBSSxZQUFZLENBQUMsS0FBK0I7UUFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ25DLENBQUM7SUFFRCxZQUFZLFVBQXFCLEVBQUUsTUFBNkIsRUFBRSxTQUFpQjtRQVpuRixXQUFNLEdBQTBCLElBQUksQ0FBQztRQWFuQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxTQUFTLHFCQUFxQixDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBNkI7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsZ0VBQWdFO1lBQ2hFLElBQUksTUFBTSxHQUFVLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFXLENBQUM7WUFFdkQsT0FBTyxNQUFNLEVBQUU7Z0JBQ2IsNENBQTRDO2dCQUM1QyxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztvQkFDdEMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxjQUFFLENBQUMsRUFBRSxDQUFD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
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PullDumpResponse, PushDeltaResponse, ResolvedOptions, SynchronizationTarget } from '../types';
|
|
2
|
+
import type { Logger } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import type { Sequelize } from 'sequelize';
|
|
4
|
+
export default class CacheTarget implements SynchronizationTarget {
|
|
5
|
+
connection: Sequelize;
|
|
6
|
+
options: ResolvedOptions;
|
|
7
|
+
logger: Logger;
|
|
8
|
+
constructor(connection: Sequelize, options: ResolvedOptions, logger: Logger);
|
|
9
|
+
applyDump(changes: PullDumpResponse, firstPage: boolean): Promise<void>;
|
|
10
|
+
applyDelta(changes: PushDeltaResponse): Promise<void>;
|
|
11
|
+
private flattenRecord;
|
|
12
|
+
private destroySubModels;
|
|
13
|
+
private checkCollection;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=cache-target.d.ts.map
|