@stonyx/orm 0.3.2-alpha.1 → 0.3.2-alpha.11

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/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "stonyx-async",
5
5
  "stonyx-module"
6
6
  ],
7
- "version": "0.3.2-alpha.1",
7
+ "version": "0.3.2-alpha.11",
8
8
  "description": "",
9
9
  "main": "dist/index.js",
10
10
  "type": "module",
@@ -61,16 +61,24 @@
61
61
  },
62
62
  "homepage": "https://github.com/abofs/stonyx-orm#readme",
63
63
  "dependencies": {
64
- "@stonyx/cron": "0.2.1-beta.29",
65
- "@stonyx/events": "0.1.1-beta.9",
66
- "stonyx": "0.2.3-beta.11"
64
+ "@stonyx/cron": "0.2.1-beta.66",
65
+ "@stonyx/events": "0.1.1-beta.49",
66
+ "stonyx": "0.2.3-beta.66"
67
67
  },
68
68
  "peerDependencies": {
69
+ "@aws-sdk/client-dynamodb": "^3.0.0",
70
+ "@aws-sdk/lib-dynamodb": "^3.0.0",
69
71
  "@stonyx/rest-server": ">=0.2.1-beta.14",
70
72
  "mysql2": "^3.0.0",
71
73
  "pg": "^8.0.0"
72
74
  },
73
75
  "peerDependenciesMeta": {
76
+ "@aws-sdk/client-dynamodb": {
77
+ "optional": true
78
+ },
79
+ "@aws-sdk/lib-dynamodb": {
80
+ "optional": true
81
+ },
74
82
  "mysql2": {
75
83
  "optional": true
76
84
  },
@@ -82,18 +90,19 @@
82
90
  }
83
91
  },
84
92
  "devDependencies": {
85
- "@stonyx/rest-server": "0.2.1-beta.30",
86
- "@stonyx/utils": "0.2.3-beta.7",
93
+ "@stonyx/rest-server": "0.2.1-beta.67",
94
+ "@stonyx/utils": "0.2.3-beta.24",
87
95
  "@types/node": "^25.6.0",
88
96
  "mysql2": "^3.20.0",
89
97
  "pg": "^8.20.0",
90
98
  "qunit": "^2.24.1",
91
99
  "sinon": "^21.0.0",
100
+ "tsx": "^4.21.0",
92
101
  "typescript": "^5.8.3"
93
102
  },
94
103
  "scripts": {
95
104
  "build": "tsc",
96
105
  "build:test": "tsc -p tsconfig.test.json",
97
- "test": "npm run build && npm run build:test && stonyx test 'dist-test/test/**/*-test.js'"
106
+ "test": "pnpm build && NODE_ENV=test node --import tsx/esm --import ./test/setup.ts node_modules/qunit/bin/qunit.js 'test/**/*-test.ts'"
98
107
  }
99
108
  }
package/src/commands.ts CHANGED
@@ -28,6 +28,13 @@ const commands: Record<string, Command> = {
28
28
  description: 'Generate a MySQL migration from current model schemas',
29
29
  bootstrap: true,
30
30
  run: async (args) => {
31
+ const config = (await import('stonyx/config')).default;
32
+
33
+ if (config.orm.dynamodb) {
34
+ console.log('DynamoDB does not use file-based migrations. Use db:sync to provision tables.');
35
+ return;
36
+ }
37
+
31
38
  const description = args?.join(' ') || 'migration';
32
39
  const { generateMigration } = await import('./mysql/migration-generator.js');
33
40
  const result = await generateMigration(description);
@@ -39,6 +46,25 @@ const commands: Record<string, Command> = {
39
46
  }
40
47
  }
41
48
  },
49
+ 'db:sync': {
50
+ description: 'Provision DynamoDB tables and GSIs from current model schemas',
51
+ bootstrap: true,
52
+ run: async () => {
53
+ const config = (await import('stonyx/config')).default;
54
+
55
+ if (!config.orm.dynamodb) {
56
+ console.error('DynamoDB is not configured. Set DYNAMODB_REGION (and optionally DYNAMODB_ENDPOINT) to enable DynamoDB mode.');
57
+ process.exit(1);
58
+ }
59
+
60
+ const { default: DynamoDBDB } = await import('./dynamodb/dynamodb-db.js');
61
+ const db = new DynamoDBDB();
62
+ await db.init();
63
+ await db.startup();
64
+ await db.shutdown();
65
+ console.log('DynamoDB tables synced successfully.');
66
+ }
67
+ },
42
68
  'db:migrate': {
43
69
  description: 'Apply pending MySQL migrations',
44
70
  bootstrap: true,
@@ -46,6 +72,11 @@ const commands: Record<string, Command> = {
46
72
  const config = (await import('stonyx/config')).default;
47
73
  const mysqlConfig = config.orm.mysql;
48
74
 
75
+ if (config.orm.dynamodb) {
76
+ console.log('DynamoDB does not use file-based migrations. Use db:sync to provision tables.');
77
+ return;
78
+ }
79
+
49
80
  if (!mysqlConfig) {
50
81
  console.error('MySQL is not configured. Set MYSQL_HOST to enable MySQL mode.');
51
82
  process.exit(1);
@@ -92,6 +123,12 @@ const commands: Record<string, Command> = {
92
123
  bootstrap: true,
93
124
  run: async () => {
94
125
  const config = (await import('stonyx/config')).default;
126
+
127
+ if (config.orm.dynamodb) {
128
+ console.log('DynamoDB does not support migration rollback. Manage table changes via the AWS console or db:sync.');
129
+ return;
130
+ }
131
+
95
132
  const mysqlConfig = config.orm.mysql;
96
133
 
97
134
  if (!mysqlConfig) {
@@ -138,6 +175,12 @@ const commands: Record<string, Command> = {
138
175
  bootstrap: true,
139
176
  run: async () => {
140
177
  const config = (await import('stonyx/config')).default;
178
+
179
+ if (config.orm.dynamodb) {
180
+ console.log('DynamoDB does not use file-based migrations. Use db:sync to provision tables.');
181
+ return;
182
+ }
183
+
141
184
  const mysqlConfig = config.orm.mysql;
142
185
 
143
186
  if (!mysqlConfig) {
@@ -0,0 +1,49 @@
1
+ /**
2
+ * DynamoDB connection factory.
3
+ *
4
+ * Dynamically imports @aws-sdk/client-dynamodb and @aws-sdk/lib-dynamodb
5
+ * so these are optional peerDependencies (matching the pg/mysql2 pattern).
6
+ */
7
+
8
+ export interface DynamoDBConfig {
9
+ region?: string;
10
+ endpoint?: string;
11
+ [key: string]: unknown;
12
+ }
13
+
14
+ // Type aliases — declared loose so we don't need to import the real SDK types
15
+ // at compile time (they're optional peer deps).
16
+ export type DocumentClient = {
17
+ send(command: unknown): Promise<unknown>;
18
+ };
19
+
20
+ export type DocumentClientConstructor = new (options: { client: unknown }) => DocumentClient;
21
+ export type DynamoDBClientConstructor = new (options: unknown) => unknown;
22
+
23
+ /**
24
+ * Create a DynamoDBDocumentClient from the given config.
25
+ * Uses dynamic import so @aws-sdk/* are optional peer deps.
26
+ */
27
+ export async function createDocumentClient(dbConfig: DynamoDBConfig): Promise<DocumentClient> {
28
+ const { DynamoDB } = await import('@aws-sdk/client-dynamodb' as string) as {
29
+ DynamoDB: DynamoDBClientConstructor;
30
+ };
31
+ const { DynamoDBDocument } = await import('@aws-sdk/lib-dynamodb' as string) as {
32
+ DynamoDBDocument: DocumentClientConstructor;
33
+ };
34
+
35
+ const clientOptions: Record<string, unknown> = {};
36
+ if (dbConfig.region) clientOptions.region = dbConfig.region;
37
+ if (dbConfig.endpoint) clientOptions.endpoint = dbConfig.endpoint;
38
+
39
+ const rawClient = new DynamoDB(clientOptions);
40
+ return new DynamoDBDocument({ client: rawClient });
41
+ }
42
+
43
+ /**
44
+ * Nullify the document client reference (DynamoDB connections are HTTP-based
45
+ * and stateless — no explicit pool close needed, but we clear the reference).
46
+ */
47
+ export function destroyDocumentClient(_client: DocumentClient | null): null {
48
+ return null;
49
+ }