@forestadmin-experimental/datasource-cosmos 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/README.md +512 -0
- package/dist/collection.d.ts +14 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +90 -0
- package/dist/datasource.d.ts +26 -0
- package/dist/datasource.d.ts.map +1 -0
- package/dist/datasource.js +87 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/introspection/builder.d.ts +68 -0
- package/dist/introspection/builder.d.ts.map +1 -0
- package/dist/introspection/builder.js +31 -0
- package/dist/introspection/container-introspector.d.ts +27 -0
- package/dist/introspection/container-introspector.d.ts.map +1 -0
- package/dist/introspection/container-introspector.js +168 -0
- package/dist/introspection/introspector.d.ts +18 -0
- package/dist/introspection/introspector.d.ts.map +1 -0
- package/dist/introspection/introspector.js +55 -0
- package/dist/model-builder/model.d.ts +79 -0
- package/dist/model-builder/model.d.ts.map +1 -0
- package/dist/model-builder/model.js +176 -0
- package/dist/utils/aggregation-converter.d.ts +30 -0
- package/dist/utils/aggregation-converter.d.ts.map +1 -0
- package/dist/utils/aggregation-converter.js +181 -0
- package/dist/utils/model-to-collection-schema-converter.d.ts +9 -0
- package/dist/utils/model-to-collection-schema-converter.d.ts.map +1 -0
- package/dist/utils/model-to-collection-schema-converter.js +72 -0
- package/dist/utils/query-converter.d.ts +38 -0
- package/dist/utils/query-converter.d.ts.map +1 -0
- package/dist/utils/query-converter.js +199 -0
- package/dist/utils/serializer.d.ts +6 -0
- package/dist/utils/serializer.d.ts.map +1 -0
- package/dist/utils/serializer.js +29 -0
- package/dist/utils/type-converter.d.ts +43 -0
- package/dist/utils/type-converter.d.ts.map +1 -0
- package/dist/utils/type-converter.js +157 -0
- package/package.json +36 -0
|
@@ -0,0 +1,87 @@
|
|
|
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 datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_1 = __importDefault(require("./collection"));
|
|
8
|
+
class CosmosDataSource extends datasource_toolkit_1.BaseDataSource {
|
|
9
|
+
constructor(cosmosClient, collectionModels, logger, options) {
|
|
10
|
+
super();
|
|
11
|
+
if (!cosmosClient)
|
|
12
|
+
throw new Error('Invalid (null) CosmosClient instance.');
|
|
13
|
+
this.cosmosClient = cosmosClient;
|
|
14
|
+
// Creating collections
|
|
15
|
+
this.createCollections(collectionModels, logger);
|
|
16
|
+
if (options?.liveQueryConnections && options?.liveQueryDatabase) {
|
|
17
|
+
this.addNativeQueryConnection(options.liveQueryConnections, {
|
|
18
|
+
instance: this.cosmosClient,
|
|
19
|
+
databaseName: options.liveQueryDatabase,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
logger?.('Info', 'CosmosDataSource - Built');
|
|
23
|
+
}
|
|
24
|
+
async createCollections(collectionModels, logger) {
|
|
25
|
+
collectionModels
|
|
26
|
+
// avoid schema reordering
|
|
27
|
+
.sort((modelA, modelB) => (modelA.name > modelB.name ? 1 : -1))
|
|
28
|
+
.forEach(model => {
|
|
29
|
+
const collection = new collection_1.default(this, model, logger, this.cosmosClient);
|
|
30
|
+
this.addCollection(collection);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async executeNativeQuery(connectionName, query, contextVariables = {}) {
|
|
34
|
+
if (!this.nativeQueryConnections[connectionName]) {
|
|
35
|
+
throw new Error(`Unknown connection name '${connectionName}'`);
|
|
36
|
+
}
|
|
37
|
+
const connection = this.nativeQueryConnections[connectionName];
|
|
38
|
+
const { querySpec, containerName } = this.parseQuery(query, contextVariables);
|
|
39
|
+
// Execute the query on the specified container
|
|
40
|
+
const database = connection.instance.database(connection.databaseName);
|
|
41
|
+
const container = database.container(containerName);
|
|
42
|
+
const { resources } = await container.items.query(querySpec).fetchAll();
|
|
43
|
+
return resources;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse the query string and extract container name and build SqlQuerySpec
|
|
47
|
+
* Expected format: "SELECT * FROM containerName WHERE ..."
|
|
48
|
+
*/
|
|
49
|
+
parseQuery(query, contextVariables) {
|
|
50
|
+
// Extract container name from query (simple regex-based approach)
|
|
51
|
+
const fromMatch = query.match(/FROM\s+(\w+)/i);
|
|
52
|
+
if (!fromMatch) {
|
|
53
|
+
throw new Error('Invalid query: could not extract container name from FROM clause');
|
|
54
|
+
}
|
|
55
|
+
const containerName = fromMatch[1];
|
|
56
|
+
// Replace placeholders in query with parameterized values
|
|
57
|
+
const { parameterizedQuery, parameters } = this.replacePlaceholders(query, contextVariables);
|
|
58
|
+
const querySpec = {
|
|
59
|
+
query: parameterizedQuery,
|
|
60
|
+
parameters,
|
|
61
|
+
};
|
|
62
|
+
return { querySpec, containerName };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Replace placeholders ($variableName) with Cosmos DB parameters (@paramN)
|
|
66
|
+
*/
|
|
67
|
+
replacePlaceholders(query, values) {
|
|
68
|
+
const parameters = [];
|
|
69
|
+
let paramCounter = 0;
|
|
70
|
+
const placeholderRegex = /\$(\w+)/g;
|
|
71
|
+
const parameterizedQuery = query.replace(placeholderRegex, (match, key) => {
|
|
72
|
+
if (key in values) {
|
|
73
|
+
const paramName = `@param${paramCounter}`;
|
|
74
|
+
paramCounter += 1;
|
|
75
|
+
// Type assertion: contextVariables should contain JSON-serializable values
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
|
+
parameters.push({ name: paramName, value: values[key] });
|
|
78
|
+
return paramName;
|
|
79
|
+
}
|
|
80
|
+
// If the variable is not in contextVariables, keep the original placeholder
|
|
81
|
+
return match;
|
|
82
|
+
});
|
|
83
|
+
return { parameterizedQuery, parameters };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.default = CosmosDataSource;
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0Esd0VBQXlFO0FBRXpFLDhEQUE0QztBQVE1QyxNQUFxQixnQkFBaUIsU0FBUSxtQ0FBZ0M7SUFNNUUsWUFDRSxZQUEwQixFQUMxQixnQkFBK0IsRUFDL0IsTUFBYyxFQUNkLE9BQXVFO1FBRXZFLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxDQUFDLFlBQVk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFFakMsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVqRCxJQUFJLE9BQU8sRUFBRSxvQkFBb0IsSUFBSSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQztZQUNoRSxJQUFJLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDLG9CQUFvQixFQUFFO2dCQUMxRCxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVk7Z0JBQzNCLFlBQVksRUFBRSxPQUFPLENBQUMsaUJBQWlCO2FBQ3hDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxNQUFNLEVBQUUsQ0FBQyxNQUFNLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRVMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLGdCQUErQixFQUFFLE1BQWM7UUFDL0UsZ0JBQWdCO1lBQ2QsMEJBQTBCO2FBQ3pCLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDOUQsT0FBTyxDQUFD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
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CosmosClient, CosmosClientOptions } from '@azure/cosmos';
|
|
2
|
+
import { DataSourceFactory } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import { ConfigurationOptions } from './introspection/builder';
|
|
4
|
+
export { default as CosmosCollection } from './collection';
|
|
5
|
+
export { default as CosmosDataSource } from './datasource';
|
|
6
|
+
export { default as TypeConverter } from './utils/type-converter';
|
|
7
|
+
export { default as ModelCosmos } from './model-builder/model';
|
|
8
|
+
export type { CosmosSchema } from './model-builder/model';
|
|
9
|
+
/**
|
|
10
|
+
* Create a Cosmos DB datasource with an existing CosmosClient instance
|
|
11
|
+
* @param client Existing CosmosClient instance
|
|
12
|
+
* @param databaseName The Cosmos DB database name to introspect
|
|
13
|
+
* @param options Optional configuration options
|
|
14
|
+
* @example
|
|
15
|
+
* .createCosmosDataSourceWithExistingClient(existingClient, 'myDatabase', configurator =>
|
|
16
|
+
* configurator.addCollectionFromContainer({
|
|
17
|
+
* name: 'Users',
|
|
18
|
+
* databaseName: 'myDatabase',
|
|
19
|
+
* containerName: 'users-container'
|
|
20
|
+
* })
|
|
21
|
+
* )
|
|
22
|
+
*/
|
|
23
|
+
export declare function createCosmosDataSourceWithExistingClient(client: CosmosClient, databaseName?: string): DataSourceFactory;
|
|
24
|
+
/**
|
|
25
|
+
* Create a Cosmos DB datasource with connection details
|
|
26
|
+
* @param endpoint The Cosmos DB endpoint URL
|
|
27
|
+
* @param key The Cosmos DB access key
|
|
28
|
+
* @param databaseName Optional database name for auto-introspection
|
|
29
|
+
* @param options Optional configuration options
|
|
30
|
+
* @example
|
|
31
|
+
* .createCosmosDataSource(
|
|
32
|
+
* 'https://myaccount.documents.azure.com:443/',
|
|
33
|
+
* 'myAccessKey',
|
|
34
|
+
* 'myDatabase',
|
|
35
|
+
* {
|
|
36
|
+
* builder: configurator =>
|
|
37
|
+
* configurator.addCollectionFromContainer({
|
|
38
|
+
* name: 'Users',
|
|
39
|
+
* databaseName: 'myDatabase',
|
|
40
|
+
* containerName: 'users-container'
|
|
41
|
+
* })
|
|
42
|
+
* }
|
|
43
|
+
* )
|
|
44
|
+
*/
|
|
45
|
+
export declare function createCosmosDataSource(endpoint: string, key: string, databaseName?: string, options?: {
|
|
46
|
+
liveQueryConnections?: string;
|
|
47
|
+
liveQueryDatabase?: string;
|
|
48
|
+
builder?: ConfigurationOptions;
|
|
49
|
+
clientOptions?: CosmosClientOptions;
|
|
50
|
+
}): DataSourceFactory;
|
|
51
|
+
/**
|
|
52
|
+
* Create a Cosmos DB datasource for the local emulator
|
|
53
|
+
* @param databaseName Optional database name for auto-introspection
|
|
54
|
+
* @param options Optional configuration options
|
|
55
|
+
* @example
|
|
56
|
+
* .createCosmosDataSourceForEmulator('myDatabase', {
|
|
57
|
+
* builder: configurator =>
|
|
58
|
+
* configurator.addCollectionFromContainer({
|
|
59
|
+
* name: 'Users',
|
|
60
|
+
* databaseName: 'myDatabase',
|
|
61
|
+
* containerName: 'users'
|
|
62
|
+
* })
|
|
63
|
+
* })
|
|
64
|
+
*/
|
|
65
|
+
export declare function createCosmosDataSourceForEmulator(databaseName?: string, options?: {
|
|
66
|
+
liveQueryConnections?: string;
|
|
67
|
+
liveQueryDatabase?: string;
|
|
68
|
+
builder?: ConfigurationOptions;
|
|
69
|
+
clientOptions?: CosmosClientOptions;
|
|
70
|
+
}): DataSourceFactory;
|
|
71
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAU,MAAM,iCAAiC,CAAC;AAG5E,OAAO,EAAE,oBAAoB,EAA2B,MAAM,yBAAyB,CAAC;AAGxF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wCAAwC,CACtD,MAAM,EAAE,YAAY,EACpB,YAAY,CAAC,EAAE,MAAM,GACpB,iBAAiB,CAqBnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC,GACA,iBAAiB,CAkCnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iCAAiC,CAC/C,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC,GACA,iBAAiB,CAOnB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
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.createCosmosDataSourceForEmulator = exports.createCosmosDataSource = exports.createCosmosDataSourceWithExistingClient = exports.ModelCosmos = exports.TypeConverter = exports.CosmosDataSource = exports.CosmosCollection = void 0;
|
|
7
|
+
const cosmos_1 = require("@azure/cosmos");
|
|
8
|
+
const datasource_1 = __importDefault(require("./datasource"));
|
|
9
|
+
const builder_1 = require("./introspection/builder");
|
|
10
|
+
const introspector_1 = __importDefault(require("./introspection/introspector"));
|
|
11
|
+
var collection_1 = require("./collection");
|
|
12
|
+
Object.defineProperty(exports, "CosmosCollection", { enumerable: true, get: function () { return __importDefault(collection_1).default; } });
|
|
13
|
+
var datasource_2 = require("./datasource");
|
|
14
|
+
Object.defineProperty(exports, "CosmosDataSource", { enumerable: true, get: function () { return __importDefault(datasource_2).default; } });
|
|
15
|
+
var type_converter_1 = require("./utils/type-converter");
|
|
16
|
+
Object.defineProperty(exports, "TypeConverter", { enumerable: true, get: function () { return __importDefault(type_converter_1).default; } });
|
|
17
|
+
var model_1 = require("./model-builder/model");
|
|
18
|
+
Object.defineProperty(exports, "ModelCosmos", { enumerable: true, get: function () { return __importDefault(model_1).default; } });
|
|
19
|
+
/**
|
|
20
|
+
* Create a Cosmos DB datasource with an existing CosmosClient instance
|
|
21
|
+
* @param client Existing CosmosClient instance
|
|
22
|
+
* @param databaseName The Cosmos DB database name to introspect
|
|
23
|
+
* @param options Optional configuration options
|
|
24
|
+
* @example
|
|
25
|
+
* .createCosmosDataSourceWithExistingClient(existingClient, 'myDatabase', configurator =>
|
|
26
|
+
* configurator.addCollectionFromContainer({
|
|
27
|
+
* name: 'Users',
|
|
28
|
+
* databaseName: 'myDatabase',
|
|
29
|
+
* containerName: 'users-container'
|
|
30
|
+
* })
|
|
31
|
+
* )
|
|
32
|
+
*/
|
|
33
|
+
function createCosmosDataSourceWithExistingClient(client, databaseName) {
|
|
34
|
+
return async (logger, options) => {
|
|
35
|
+
let collectionModels;
|
|
36
|
+
if (options) {
|
|
37
|
+
const builder = options(new builder_1.CosmosDatasourceBuilder(client));
|
|
38
|
+
collectionModels = await builder.createCollectionsFromConfiguration();
|
|
39
|
+
}
|
|
40
|
+
else if (databaseName) {
|
|
41
|
+
collectionModels = await introspector_1.default.introspect(client, databaseName, logger);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
collectionModels = [];
|
|
45
|
+
}
|
|
46
|
+
if (collectionModels.length === 0 && !options) {
|
|
47
|
+
const message = 'No collections were introspected. Please provide a databaseName or use the builder.';
|
|
48
|
+
logger?.('Warn', message);
|
|
49
|
+
}
|
|
50
|
+
return new datasource_1.default(client, collectionModels, logger);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
exports.createCosmosDataSourceWithExistingClient = createCosmosDataSourceWithExistingClient;
|
|
54
|
+
/**
|
|
55
|
+
* Create a Cosmos DB datasource with connection details
|
|
56
|
+
* @param endpoint The Cosmos DB endpoint URL
|
|
57
|
+
* @param key The Cosmos DB access key
|
|
58
|
+
* @param databaseName Optional database name for auto-introspection
|
|
59
|
+
* @param options Optional configuration options
|
|
60
|
+
* @example
|
|
61
|
+
* .createCosmosDataSource(
|
|
62
|
+
* 'https://myaccount.documents.azure.com:443/',
|
|
63
|
+
* 'myAccessKey',
|
|
64
|
+
* 'myDatabase',
|
|
65
|
+
* {
|
|
66
|
+
* builder: configurator =>
|
|
67
|
+
* configurator.addCollectionFromContainer({
|
|
68
|
+
* name: 'Users',
|
|
69
|
+
* databaseName: 'myDatabase',
|
|
70
|
+
* containerName: 'users-container'
|
|
71
|
+
* })
|
|
72
|
+
* }
|
|
73
|
+
* )
|
|
74
|
+
*/
|
|
75
|
+
function createCosmosDataSource(endpoint, key, databaseName, options) {
|
|
76
|
+
return async (logger) => {
|
|
77
|
+
const client = new cosmos_1.CosmosClient({
|
|
78
|
+
endpoint,
|
|
79
|
+
key,
|
|
80
|
+
...options?.clientOptions,
|
|
81
|
+
});
|
|
82
|
+
const { liveQueryConnections, liveQueryDatabase, builder } = options || {};
|
|
83
|
+
let collectionModels;
|
|
84
|
+
if (builder) {
|
|
85
|
+
const datasourceBuilder = builder(new builder_1.CosmosDatasourceBuilder(client));
|
|
86
|
+
collectionModels = await datasourceBuilder.createCollectionsFromConfiguration();
|
|
87
|
+
}
|
|
88
|
+
else if (databaseName) {
|
|
89
|
+
collectionModels = await introspector_1.default.introspect(client, databaseName, logger);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
collectionModels = [];
|
|
93
|
+
}
|
|
94
|
+
if (collectionModels.length === 0 && !builder) {
|
|
95
|
+
const message = 'No collections were introspected. Please provide a databaseName or use the builder.';
|
|
96
|
+
logger?.('Warn', message);
|
|
97
|
+
}
|
|
98
|
+
return new datasource_1.default(client, collectionModels, logger, {
|
|
99
|
+
liveQueryConnections,
|
|
100
|
+
liveQueryDatabase,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
exports.createCosmosDataSource = createCosmosDataSource;
|
|
105
|
+
/**
|
|
106
|
+
* Create a Cosmos DB datasource for the local emulator
|
|
107
|
+
* @param databaseName Optional database name for auto-introspection
|
|
108
|
+
* @param options Optional configuration options
|
|
109
|
+
* @example
|
|
110
|
+
* .createCosmosDataSourceForEmulator('myDatabase', {
|
|
111
|
+
* builder: configurator =>
|
|
112
|
+
* configurator.addCollectionFromContainer({
|
|
113
|
+
* name: 'Users',
|
|
114
|
+
* databaseName: 'myDatabase',
|
|
115
|
+
* containerName: 'users'
|
|
116
|
+
* })
|
|
117
|
+
* })
|
|
118
|
+
*/
|
|
119
|
+
function createCosmosDataSourceForEmulator(databaseName, options) {
|
|
120
|
+
// Default emulator connection details
|
|
121
|
+
const endpoint = 'https://localhost:8081';
|
|
122
|
+
const key = 'C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==';
|
|
123
|
+
return createCosmosDataSource(endpoint, key, databaseName, options);
|
|
124
|
+
}
|
|
125
|
+
exports.createCosmosDataSourceForEmulator = createCosmosDataSourceForEmulator;
|
|
126
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsMENBQWtFO0FBR2xFLDhEQUE0QztBQUM1QyxxREFBd0Y7QUFDeEYsZ0ZBQXdEO0FBRXhELDJDQUEyRDtBQUFsRCwrSEFBQSxPQUFPLE9BQW9CO0FBQ3BDLDJDQUEyRDtBQUFsRCwrSEFBQSxPQUFPLE9BQW9CO0FBQ3BDLHlEQUFrRTtBQUF6RCxnSUFBQSxPQUFPLE9BQWlCO0FBQ2pDLCtDQUErRDtBQUF0RCxxSEFBQSxPQUFPLE9BQWU7QUFHL0I7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQWdCLHdDQUF3QyxDQUN0RCxNQUFvQixFQUNwQixZQUFxQjtJQUVyQixPQUFPLEtBQUssRUFBRSxNQUFjLEVBQUUsT0FBOEIsRUFBRSxFQUFFO1FBQzlELElBQUksZ0JBQWdCLENBQUM7UUFFckIsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLGlDQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUE0QixDQUFDO1lBQ3hGLGdCQUFnQixHQUFHLE1BQU0sT0FBTyxDQUFDLGtDQUFrQyxFQUFFLENBQUM7UUFDeEUsQ0FBQzthQUFNLElBQUksWUFBWSxFQUFFLENBQUM7WUFDeEIsZ0JBQWdCLEdBQUcsTUFBTSxzQkFBWSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pGLENBQUM7YUFBTSxDQUFDO1lBQ04sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLENBQUM7UUFFRCxJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM5QyxNQUFNLE9BQU8sR0FDWCxxRkFBcUYsQ0FBQztZQUN4RixNQUFNLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUVELE9BQU8sSUFBSSxvQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDaEUsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQXhCRCw0RkF3QkM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxTQUFnQixzQkFBc0IsQ0FDcEMsUUFBZ0IsRUFDaEIsR0FBVyxFQUNYLFlBQXFCLEVBQ3JCLE9BS0M7SUFFRCxPQUFPLEtBQUssRUFBRSxNQUFjLEVBQUUsRUFBRTtRQUM5QixNQUFNLE1BQU0sR0FBRyxJQUFJLHFCQUFZLENBQUM7WUFDOUIsUUFBUTtZQUNSLEdBQUc7WUFDSCxHQUFHLE9BQU8sRUFBRSxhQUFhO1NBQzFCLENBQUMsQ0FBQztRQUVILE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLElBQUksRUFBRSxDQUFDO1FBRTNFLElBQUksZ0JBQWdCLENBQUM7UUFFckIsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUMvQixJQUFJLGlDQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUNULENBQUM7WUFDN0IsZ0JBQWdCLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO1FBQ2xGLENBQUM7YUFBTSxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ3hCLGdCQUFnQixHQUFHLE1BQU0sc0JBQVksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNqRixDQUFDO2FBQU0sQ0FBQztZQUNOLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUN4QixDQUFDO1FBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUMsTUFBTSxPQUFPLEdBQ1gscUZBQXFGLENBQUM7WUFDeEYsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFFRCxPQUFPLElBQUksb0JBQWdCLENBQUMsTUFBTSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRTtZQUM1RCxvQkFBb0I7WUFDcEIsaUJBQWlCO1NBQ2xCLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztBQUNKLENBQUM7QUE1Q0Qsd0RBNENDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQWdCLGlDQUFpQyxDQUMvQyxZQUFxQixFQUNyQixPQUtDO0lBRUQsc0NBQXNDO0lBQ3RDLE1BQU0sUUFBUSxHQUFHLHdCQUF3QixDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUNQLDBGQUEwRixDQUFDO0lBRTdGLE9BQU8sc0JBQXNCLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdEUsQ0FBQztBQWZELDhFQWVDIn0=
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { CosmosClient } from '@azure/cosmos';
|
|
2
|
+
import { FieldSchema } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import ModelCosmos from '../model-builder/model';
|
|
4
|
+
export type OverrideTypeConverter = (field: {
|
|
5
|
+
fieldName: string;
|
|
6
|
+
attribute: {
|
|
7
|
+
type: string;
|
|
8
|
+
nullable?: boolean;
|
|
9
|
+
indexed?: boolean;
|
|
10
|
+
};
|
|
11
|
+
generatedFieldSchema: FieldSchema;
|
|
12
|
+
}) => void | FieldSchema;
|
|
13
|
+
export type CosmosCollectionBase = {
|
|
14
|
+
/**
|
|
15
|
+
* Give the name of the collection (Forest Admin collection name)
|
|
16
|
+
*/
|
|
17
|
+
name: string;
|
|
18
|
+
/**
|
|
19
|
+
* Allow to override the type converter
|
|
20
|
+
*/
|
|
21
|
+
overrideTypeConverter?: OverrideTypeConverter;
|
|
22
|
+
/**
|
|
23
|
+
* Enabling `enableCount` allows the pagination widget to display the total number of pages
|
|
24
|
+
* in this collection while browsing records.
|
|
25
|
+
*
|
|
26
|
+
* _It is enabled by default but can be disabled for performance reasons._
|
|
27
|
+
*/
|
|
28
|
+
enableCount?: boolean;
|
|
29
|
+
};
|
|
30
|
+
export type CosmosCollectionFromContainerOptions = {
|
|
31
|
+
/**
|
|
32
|
+
* The Cosmos DB database name
|
|
33
|
+
*/
|
|
34
|
+
databaseName: string;
|
|
35
|
+
/**
|
|
36
|
+
* The Cosmos DB container name
|
|
37
|
+
*/
|
|
38
|
+
containerName: string;
|
|
39
|
+
/**
|
|
40
|
+
* The partition key path for this container (e.g., "/userId")
|
|
41
|
+
*/
|
|
42
|
+
partitionKeyPath?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Number of sample documents to analyze for schema inference (default: 100)
|
|
45
|
+
*/
|
|
46
|
+
sampleSize?: number;
|
|
47
|
+
} & CosmosCollectionBase;
|
|
48
|
+
export type ConfigurationOptions = (configurator: CosmosDatasourceOptionsBuilder) => CosmosDatasourceOptionsBuilder;
|
|
49
|
+
export interface CosmosDatasourceOptionsBuilder {
|
|
50
|
+
/**
|
|
51
|
+
* Add a collection from a Cosmos DB container
|
|
52
|
+
*/
|
|
53
|
+
addCollectionFromContainer(options: CosmosCollectionFromContainerOptions): this;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Builder pattern to ease adding collections from Cosmos DB
|
|
57
|
+
*/
|
|
58
|
+
export declare class CosmosDatasourceBuilder implements CosmosDatasourceOptionsBuilder {
|
|
59
|
+
private readonly cosmosClient;
|
|
60
|
+
protected collectionsPromises: Array<Promise<ModelCosmos>>;
|
|
61
|
+
constructor(cosmosClient: CosmosClient);
|
|
62
|
+
addCollectionFromContainer({ name, databaseName, containerName, partitionKeyPath, overrideTypeConverter, enableCount, sampleSize, }: CosmosCollectionFromContainerOptions): this;
|
|
63
|
+
/**
|
|
64
|
+
* Internal usages only - the client only sees CosmosDatasourceOptionsBuilder interface
|
|
65
|
+
*/
|
|
66
|
+
createCollectionsFromConfiguration(): Promise<ModelCosmos[]>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/introspection/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAG9D,OAAO,WAAW,MAAM,wBAAwB,CAAC;AAEjD,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACnE,oBAAoB,EAAE,WAAW,CAAC;CACnC,KAAK,IAAI,GAAG,WAAW,CAAC;AAEzB,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAE9C;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,oBAAoB,CAAC;AAEzB,MAAM,MAAM,oBAAoB,GAAG,CACjC,YAAY,EAAE,8BAA8B,KACzC,8BAA8B,CAAC;AAEpC,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,0BAA0B,CAAC,OAAO,EAAE,oCAAoC,GAAG,IAAI,CAAC;CACjF;AAED;;GAEG;AACH,qBAAa,uBAAwB,YAAW,8BAA8B;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAM;gBAEpD,YAAY,EAAE,YAAY;IAI/B,0BAA0B,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EACX,UAAgB,GACjB,EAAE,oCAAoC,GAAG,IAAI;IAqB9C;;OAEG;IACU,kCAAkC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;CAG1E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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.CosmosDatasourceBuilder = void 0;
|
|
7
|
+
const container_introspector_1 = __importDefault(require("./container-introspector"));
|
|
8
|
+
/**
|
|
9
|
+
* Builder pattern to ease adding collections from Cosmos DB
|
|
10
|
+
*/
|
|
11
|
+
class CosmosDatasourceBuilder {
|
|
12
|
+
constructor(cosmosClient) {
|
|
13
|
+
this.collectionsPromises = [];
|
|
14
|
+
this.cosmosClient = cosmosClient;
|
|
15
|
+
}
|
|
16
|
+
addCollectionFromContainer({ name, databaseName, containerName, partitionKeyPath, overrideTypeConverter, enableCount, sampleSize = 100, }) {
|
|
17
|
+
this.collectionsPromises.push((async () => {
|
|
18
|
+
const model = await (0, container_introspector_1.default)(this.cosmosClient, name, databaseName, containerName, partitionKeyPath, sampleSize, overrideTypeConverter, enableCount);
|
|
19
|
+
return model;
|
|
20
|
+
})());
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Internal usages only - the client only sees CosmosDatasourceOptionsBuilder interface
|
|
25
|
+
*/
|
|
26
|
+
async createCollectionsFromConfiguration() {
|
|
27
|
+
return Promise.all(this.collectionsPromises);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.CosmosDatasourceBuilder = CosmosDatasourceBuilder;
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbnRyb3NwZWN0aW9uL2J1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0Esc0ZBQTJEO0FBOEQzRDs7R0FFRztBQUNILE1BQWEsdUJBQXVCO0lBS2xDLFlBQVksWUFBMEI7UUFGNUIsd0JBQW1CLEdBQWdDLEVBQUUsQ0FBQztRQUc5RCxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztJQUNuQyxDQUFDO0lBRU0sMEJBQTBCLENBQUMsRUFDaEMsSUFBSSxFQUNKLFlBQVksRUFDWixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLHFCQUFxQixFQUNyQixXQUFXLEVBQ1gsVUFBVSxHQUFHLEdBQUcsR0FDcUI7UUFDckMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FDM0IsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUNWLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBQSxnQ0FBbUIsRUFDckMsSUFBSSxDQUFDLFlBQVksRUFDakIsSUFBSSxFQUNKLFlBQVksRUFDWixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLFVBQVUsRUFDVixxQkFBcUIsRUFDckIsV0FBVyxDQUNaLENBQUM7WUFFRixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUVGLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGtDQUFrQztRQUM3QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDL0MsQ0FBQztDQUNGO0FBNUNELDBEQTRDQyJ9
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CosmosClient } from '@azure/cosmos';
|
|
2
|
+
import { OverrideTypeConverter } from './builder';
|
|
3
|
+
import ModelCosmos from '../model-builder/model';
|
|
4
|
+
export interface IntrospectionOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to flatten nested objects into dot-notation fields
|
|
7
|
+
* Example: { address: { city: 'NYC' } } becomes { 'address.city': 'NYC' }
|
|
8
|
+
* Default: true (recommended for Forest Admin compatibility)
|
|
9
|
+
*/
|
|
10
|
+
flattenNestedObjects?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum depth for nested object introspection
|
|
13
|
+
* Default: 5
|
|
14
|
+
*/
|
|
15
|
+
maxDepth?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Whether to include array items introspection
|
|
18
|
+
* Default: false (arrays are treated as Json type)
|
|
19
|
+
*/
|
|
20
|
+
introspectArrayItems?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Introspect a Cosmos DB container to infer the schema from sample documents
|
|
24
|
+
* with support for complex nested objects
|
|
25
|
+
*/
|
|
26
|
+
export default function introspectContainerV2(cosmosClient: CosmosClient, collectionName: string, databaseName: string, containerName: string, partitionKeyPath?: string, sampleSize?: number, overrideTypeConverter?: OverrideTypeConverter, enableCount?: boolean, options?: IntrospectionOptions): Promise<ModelCosmos>;
|
|
27
|
+
//# sourceMappingURL=container-introspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-introspector.d.ts","sourceRoot":"","sources":["../../src/introspection/container-introspector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,WAA6B,MAAM,wBAAwB,CAAC;AAGnE,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,wBAA8B,qBAAqB,CACjD,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,gBAAgB,CAAC,EAAE,MAAM,EACzB,UAAU,SAAM,EAChB,qBAAqB,CAAC,EAAE,qBAAqB,EAC7C,WAAW,CAAC,EAAE,OAAO,EACrB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,WAAW,CAAC,CAuCtB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
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 model_1 = __importDefault(require("../model-builder/model"));
|
|
7
|
+
const type_converter_1 = __importDefault(require("../utils/type-converter"));
|
|
8
|
+
/**
|
|
9
|
+
* Introspect a Cosmos DB container to infer the schema from sample documents
|
|
10
|
+
* with support for complex nested objects
|
|
11
|
+
*/
|
|
12
|
+
async function introspectContainerV2(cosmosClient, collectionName, databaseName, containerName, partitionKeyPath, sampleSize = 100, overrideTypeConverter, enableCount, options = {}) {
|
|
13
|
+
const { flattenNestedObjects = true, maxDepth = 5, introspectArrayItems = false } = options;
|
|
14
|
+
const database = cosmosClient.database(databaseName);
|
|
15
|
+
const container = database.container(containerName);
|
|
16
|
+
// Get container metadata to determine partition key if not provided
|
|
17
|
+
let actualPartitionKeyPath = partitionKeyPath;
|
|
18
|
+
if (!actualPartitionKeyPath) {
|
|
19
|
+
const { resource: containerDef } = await container.read();
|
|
20
|
+
actualPartitionKeyPath = containerDef.partitionKey?.paths?.[0] || '/id';
|
|
21
|
+
}
|
|
22
|
+
// Sample documents to infer schema
|
|
23
|
+
const querySpec = {
|
|
24
|
+
query: `SELECT TOP ${sampleSize} * FROM c`,
|
|
25
|
+
};
|
|
26
|
+
const { resources: sampleDocuments } = await container.items.query(querySpec).fetchAll();
|
|
27
|
+
// Infer schema from sample documents with nested object support
|
|
28
|
+
const schema = inferSchemaFromDocuments(sampleDocuments, flattenNestedObjects, maxDepth, introspectArrayItems);
|
|
29
|
+
return new model_1.default(cosmosClient, collectionName, databaseName, containerName, actualPartitionKeyPath, schema, overrideTypeConverter, enableCount);
|
|
30
|
+
}
|
|
31
|
+
exports.default = introspectContainerV2;
|
|
32
|
+
/**
|
|
33
|
+
* Infer schema from a collection of sample documents with nested support
|
|
34
|
+
*/
|
|
35
|
+
function inferSchemaFromDocuments(
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
documents, flattenNestedObjects, maxDepth, introspectArrayItems) {
|
|
38
|
+
if (documents.length === 0) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
const schema = {};
|
|
42
|
+
const fieldTypes = {};
|
|
43
|
+
const fieldPresence = {}; // Track how many docs have each field
|
|
44
|
+
// Analyze each document to collect field types
|
|
45
|
+
for (const doc of documents) {
|
|
46
|
+
const fieldsInDoc = new Set();
|
|
47
|
+
analyzeDocument(doc, fieldTypes, '', 0, maxDepth, flattenNestedObjects, introspectArrayItems, fieldsInDoc);
|
|
48
|
+
// Track field presence
|
|
49
|
+
for (const field of fieldsInDoc) {
|
|
50
|
+
fieldPresence[field] = (fieldPresence[field] || 0) + 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Convert collected field types to schema
|
|
54
|
+
for (const [fieldName, types] of Object.entries(fieldTypes)) {
|
|
55
|
+
// Skip Cosmos DB system fields (start with _)
|
|
56
|
+
if (!fieldName.startsWith('_') || fieldName === '_id') {
|
|
57
|
+
// Get the most specific common type
|
|
58
|
+
const commonType = type_converter_1.default.getMostSpecificType(types);
|
|
59
|
+
// Field is nullable if it contains null OR is not present in all documents
|
|
60
|
+
const nullable = types.includes('null') || fieldPresence[fieldName] < documents.length;
|
|
61
|
+
schema[fieldName] = {
|
|
62
|
+
type: commonType,
|
|
63
|
+
nullable,
|
|
64
|
+
indexed: true, // Assume all fields can be indexed in Cosmos DB
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return schema;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Recursively analyze a document to collect field types with nested object support
|
|
72
|
+
*/
|
|
73
|
+
function analyzeDocument(
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
+
obj, fieldTypes, prefix, depth, maxDepth, flattenNestedObjects, introspectArrayItems, fieldsInDoc) {
|
|
76
|
+
// Helper to record a field type
|
|
77
|
+
const recordField = (fieldName, type) => {
|
|
78
|
+
if (!fieldTypes[fieldName]) {
|
|
79
|
+
fieldTypes[fieldName] = [];
|
|
80
|
+
}
|
|
81
|
+
fieldTypes[fieldName].push(type);
|
|
82
|
+
if (fieldsInDoc && fieldName) {
|
|
83
|
+
fieldsInDoc.add(fieldName);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (obj === null || obj === undefined) {
|
|
87
|
+
if (prefix) {
|
|
88
|
+
recordField(prefix, 'null');
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Stop recursion if max depth reached
|
|
93
|
+
if (depth >= maxDepth) {
|
|
94
|
+
if (prefix) {
|
|
95
|
+
recordField(prefix, 'object');
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Handle arrays
|
|
100
|
+
if (Array.isArray(obj)) {
|
|
101
|
+
if (prefix) {
|
|
102
|
+
recordField(prefix, 'array');
|
|
103
|
+
}
|
|
104
|
+
// Optionally introspect array items
|
|
105
|
+
if (introspectArrayItems && obj.length > 0) {
|
|
106
|
+
// Analyze first few items to infer array item type
|
|
107
|
+
const itemsToAnalyze = obj.slice(0, Math.min(5, obj.length));
|
|
108
|
+
for (const item of itemsToAnalyze) {
|
|
109
|
+
if (typeof item === 'object' && item !== null) {
|
|
110
|
+
analyzeDocument(item, fieldTypes, `${prefix}[]`, depth + 1, maxDepth, flattenNestedObjects, introspectArrayItems, fieldsInDoc);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Handle objects
|
|
117
|
+
if (typeof obj === 'object') {
|
|
118
|
+
// Check for special types first
|
|
119
|
+
if (obj instanceof Date) {
|
|
120
|
+
if (prefix) {
|
|
121
|
+
recordField(prefix, 'date');
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (isGeoPoint(obj)) {
|
|
126
|
+
if (prefix) {
|
|
127
|
+
recordField(prefix, 'point');
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Regular object - recursively analyze properties
|
|
132
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
133
|
+
const fieldName = prefix ? `${prefix}.${key}` : key;
|
|
134
|
+
if (value &&
|
|
135
|
+
typeof value === 'object' &&
|
|
136
|
+
!Array.isArray(value) &&
|
|
137
|
+
flattenNestedObjects &&
|
|
138
|
+
!(value instanceof Date) &&
|
|
139
|
+
!isGeoPoint(value)) {
|
|
140
|
+
// Recursively analyze nested objects if flattening is enabled
|
|
141
|
+
analyzeDocument(value, fieldTypes, fieldName, depth + 1, maxDepth, flattenNestedObjects, introspectArrayItems, fieldsInDoc);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
// For non-nested or non-flatten mode
|
|
145
|
+
const inferredType = type_converter_1.default.inferTypeFromValue(value);
|
|
146
|
+
recordField(fieldName, inferredType);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Primitive values
|
|
152
|
+
if (prefix) {
|
|
153
|
+
const inferredType = type_converter_1.default.inferTypeFromValue(obj);
|
|
154
|
+
recordField(prefix, inferredType);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if an object is a GeoJSON Point
|
|
159
|
+
*/
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
161
|
+
function isGeoPoint(value) {
|
|
162
|
+
return (value &&
|
|
163
|
+
typeof value === 'object' &&
|
|
164
|
+
value.type === 'Point' &&
|
|
165
|
+
Array.isArray(value.coordinates) &&
|
|
166
|
+
value.coordinates.length === 2);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLWludHJvc3BlY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbnRyb3NwZWN0aW9uL2NvbnRhaW5lci1pbnRyb3NwZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFJQSxtRUFBbUU7QUFDbkUsNkVBQXdFO0FBdUJ4RTs7O0dBR0c7QUFDWSxLQUFLLFVBQVUscUJBQXFCLENBQ2pELFlBQTBCLEVBQzFCLGNBQXNCLEVBQ3RCLFlBQW9CLEVBQ3BCLGFBQXFCLEVBQ3JCLGdCQUF5QixFQUN6QixVQUFVLEdBQUcsR0FBRyxFQUNoQixxQkFBNkMsRUFDN0MsV0FBcUIsRUFDckIsVUFBZ0MsRUFBRTtJQUVsQyxNQUFNLEVBQUUsb0JBQW9CLEdBQUcsSUFBSSxFQUFFLFFBQVEsR0FBRyxDQUFDLEVBQUUsb0JBQW9CLEdBQUcsS0FBSyxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRTVGLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDckQsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUVwRCxvRUFBb0U7SUFDcEUsSUFBSSxzQkFBc0IsR0FBRyxnQkFBZ0IsQ0FBQztJQUU5QyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM1QixNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzFELHNCQUFzQixHQUFHLFlBQVksQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO0lBQzFFLENBQUM7SUFFRCxtQ0FBbUM7SUFDbkMsTUFBTSxTQUFTLEdBQUc7UUFDaEIsS0FBSyxFQUFFLGNBQWMsVUFBVSxXQUFXO0tBQzNDLENBQUM7SUFFRixNQUFNLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxH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
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CosmosClient } from '@azure/cosmos';
|
|
2
|
+
import { Logger } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import ModelCosmos from '../model-builder/model';
|
|
4
|
+
export default class Introspector {
|
|
5
|
+
/**
|
|
6
|
+
* Introspect all containers in a Cosmos DB database
|
|
7
|
+
*/
|
|
8
|
+
static introspect(cosmosClient: CosmosClient, databaseName: string, logger?: Logger): Promise<ModelCosmos[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Introspect all containers in the specified database
|
|
11
|
+
*/
|
|
12
|
+
private static introspectAll;
|
|
13
|
+
/**
|
|
14
|
+
* Introspect a specific container
|
|
15
|
+
*/
|
|
16
|
+
static introspectContainer(cosmosClient: CosmosClient, databaseName: string, containerName: string, sampleSize?: number, logger?: Logger): Promise<ModelCosmos>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=introspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspector.d.ts","sourceRoot":"","sources":["../../src/introspection/introspector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAGzD,OAAO,WAAW,MAAM,wBAAwB,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B;;OAEG;WACU,UAAU,CACrB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,CAAC;IAMzB;;OAEG;mBACkB,aAAa;IAuDlC;;OAEG;WACU,mBAAmB,CAC9B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC;CAgBxB"}
|