@mostajs/octoswitcher 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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Minimal dialect interface — same contract as IDialect in @mostajs/orm.
3
+ * Both ORM dialects and NET proxies implement this.
4
+ */
5
+ export interface IDataDialect {
6
+ readonly dialectType: string;
7
+ find<T = Record<string, unknown>>(schema: any, filter: any, options?: any): Promise<T[]>;
8
+ findOne<T = Record<string, unknown>>(schema: any, filter: any, options?: any): Promise<T | null>;
9
+ findById<T = Record<string, unknown>>(schema: any, id: string, options?: any): Promise<T | null>;
10
+ create<T = Record<string, unknown>>(schema: any, data: Record<string, unknown>): Promise<T>;
11
+ update<T = Record<string, unknown>>(schema: any, id: string, data: Record<string, unknown>): Promise<T | null>;
12
+ updateMany(schema: any, filter: any, data: Record<string, unknown>): Promise<number>;
13
+ delete(schema: any, id: string): Promise<boolean>;
14
+ deleteMany(schema: any, filter: any): Promise<number>;
15
+ count(schema: any, filter: any): Promise<number>;
16
+ distinct(schema: any, field: string, filter: any): Promise<unknown[]>;
17
+ aggregate<T = Record<string, unknown>>(schema: any, stages: any[]): Promise<T[]>;
18
+ findWithRelations<T = Record<string, unknown>>(schema: any, filter: any, relations: string[], options?: any): Promise<T[]>;
19
+ findByIdWithRelations<T = Record<string, unknown>>(schema: any, id: string, relations: string[], options?: any): Promise<T | null>;
20
+ upsert<T = Record<string, unknown>>(schema: any, filter: any, data: Record<string, unknown>): Promise<T>;
21
+ increment(schema: any, id: string, field: string, amount: number): Promise<Record<string, unknown>>;
22
+ addToSet(schema: any, id: string, field: string, value: unknown): Promise<Record<string, unknown> | null>;
23
+ pull(schema: any, id: string, field: string, value: unknown): Promise<Record<string, unknown> | null>;
24
+ search<T = Record<string, unknown>>(schema: any, query: string, fields: string[], options?: any): Promise<T[]>;
25
+ }
26
+ export type DataMode = 'orm' | 'net';
27
+ /**
28
+ * Detect data mode from environment.
29
+ * MOSTA_DATA=net → remote transport (REST, GraphQL, gRPC, WS, MCP, etc.)
30
+ * MOSTA_DATA=orm (or unset) → direct database access via ORM dialect
31
+ */
32
+ export declare function getDataMode(): DataMode;
33
+ export declare function isNetMode(): boolean;
34
+ export declare function isOrmMode(): boolean;
35
+ /**
36
+ * Get the data dialect — ORM or NET, determined by MOSTA_DATA env var.
37
+ *
38
+ * - MOSTA_DATA=orm (default): loads @mostajs/orm, connects via DB_DIALECT + SGBD_URI
39
+ * - MOSTA_DATA=net: loads @mostajs/net/client, creates NetDialectProxy via MOSTA_NET_URL + MOSTA_NET_TRANSPORT
40
+ *
41
+ * Singleton — first call initializes, subsequent calls return cached instance.
42
+ * All @mostajs modules (auth, rbac, audit, settings) call this function.
43
+ */
44
+ export declare function getDialect(): Promise<IDataDialect>;
45
+ /**
46
+ * Inject an external dialect (for testing or custom implementations).
47
+ * After this call, getDialect() returns the injected dialect.
48
+ */
49
+ export declare function setDialect(dialect: IDataDialect): void;
50
+ /**
51
+ * Reset the singleton (for testing).
52
+ */
53
+ export declare function resetDialect(): void;
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ // OctoSwitcher — Data access switcher for @mostajs ecosystem
2
+ // Switches between ORM (direct DB) and NET (remote transport) based on MOSTA_DATA env var
3
+ // All modules import getDialect() from here — never from @mostajs/orm or @mostajs/net directly
4
+ // Author: Dr Hamid MADANI drmdh@msn.com
5
+ /**
6
+ * Detect data mode from environment.
7
+ * MOSTA_DATA=net → remote transport (REST, GraphQL, gRPC, WS, MCP, etc.)
8
+ * MOSTA_DATA=orm (or unset) → direct database access via ORM dialect
9
+ */
10
+ export function getDataMode() {
11
+ return process.env.MOSTA_DATA === 'net' ? 'net' : 'orm';
12
+ }
13
+ export function isNetMode() {
14
+ return getDataMode() === 'net';
15
+ }
16
+ export function isOrmMode() {
17
+ return getDataMode() === 'orm';
18
+ }
19
+ // ============================================================
20
+ // Singleton dialect
21
+ // ============================================================
22
+ let _dialect = null;
23
+ /**
24
+ * Get the data dialect — ORM or NET, determined by MOSTA_DATA env var.
25
+ *
26
+ * - MOSTA_DATA=orm (default): loads @mostajs/orm, connects via DB_DIALECT + SGBD_URI
27
+ * - MOSTA_DATA=net: loads @mostajs/net/client, creates NetDialectProxy via MOSTA_NET_URL + MOSTA_NET_TRANSPORT
28
+ *
29
+ * Singleton — first call initializes, subsequent calls return cached instance.
30
+ * All @mostajs modules (auth, rbac, audit, settings) call this function.
31
+ */
32
+ export async function getDialect() {
33
+ if (_dialect)
34
+ return _dialect;
35
+ if (isNetMode()) {
36
+ _dialect = await initNetDialect();
37
+ }
38
+ else {
39
+ _dialect = await initOrmDialect();
40
+ }
41
+ return _dialect;
42
+ }
43
+ /**
44
+ * Inject an external dialect (for testing or custom implementations).
45
+ * After this call, getDialect() returns the injected dialect.
46
+ */
47
+ export function setDialect(dialect) {
48
+ _dialect = dialect;
49
+ }
50
+ /**
51
+ * Reset the singleton (for testing).
52
+ */
53
+ export function resetDialect() {
54
+ _dialect = null;
55
+ }
56
+ // ============================================================
57
+ // ORM mode — direct database access
58
+ // ============================================================
59
+ async function initOrmDialect() {
60
+ try {
61
+ const orm = await import(/* webpackIgnore: true */ '@mostajs/orm');
62
+ return await orm.getDialect();
63
+ }
64
+ catch (err) {
65
+ throw new Error(`[OctoSwitcher] ORM mode requires @mostajs/orm. Install it: npm install @mostajs/orm\n` +
66
+ `Original error: ${err instanceof Error ? err.message : String(err)}`);
67
+ }
68
+ }
69
+ // ============================================================
70
+ // NET mode — remote transport via @mostajs/net client
71
+ // ============================================================
72
+ async function initNetDialect() {
73
+ const url = process.env.MOSTA_NET_URL;
74
+ if (!url) {
75
+ throw new Error('[OctoSwitcher] NET mode requires MOSTA_NET_URL env var.\n' +
76
+ 'Example: MOSTA_NET_URL=https://mcp.amia.fr/astro_08/');
77
+ }
78
+ try {
79
+ const net = await import(/* webpackIgnore: true */ '@mostajs/net/client');
80
+ const apiKey = process.env.MOSTA_NET_API_KEY;
81
+ const client = new net.NetClient({ url, apiKey });
82
+ const proxy = net.createNetDialectProxy(client);
83
+ return proxy;
84
+ }
85
+ catch (err) {
86
+ throw new Error(`[OctoSwitcher] NET mode requires @mostajs/net. Install it: npm install @mostajs/net\n` +
87
+ `Original error: ${err instanceof Error ? err.message : String(err)}`);
88
+ }
89
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@mostajs/octoswitcher",
3
+ "version": "1.0.0",
4
+ "description": "Data access switcher — ORM direct or NET transport, one interface, zero config in modules",
5
+ "author": "Dr Hamid MADANI <drmdh@msn.com>",
6
+ "license": "AGPL-3.0-or-later",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "LICENSE",
20
+ "README.md"
21
+ ],
22
+ "keywords": [
23
+ "mostajs",
24
+ "orm",
25
+ "net",
26
+ "switcher",
27
+ "dialect",
28
+ "transport",
29
+ "rest",
30
+ "graphql",
31
+ "grpc",
32
+ "websocket",
33
+ "mcp"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/apolocine/octoswitcher"
38
+ },
39
+ "homepage": "https://mostajs.dev",
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc",
45
+ "prepublishOnly": "npm run build"
46
+ },
47
+ "peerDependencies": {
48
+ "@mostajs/net": ">=2.0.0",
49
+ "@mostajs/orm": ">=1.8.0"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "@mostajs/orm": {
53
+ "optional": true
54
+ },
55
+ "@mostajs/net": {
56
+ "optional": true
57
+ }
58
+ },
59
+ "devDependencies": {
60
+ "@mostajs/net": "^2.0.73",
61
+ "@mostajs/orm": "^1.8.0",
62
+ "@types/node": "^25.5.2",
63
+ "typescript": "^5.6.0"
64
+ }
65
+ }