@mosaic-code/prisma-deadlock-avoidance-tests 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +207 -0
  2. package/README.md +248 -0
  3. package/dist/assertions/row-assertion.d.ts +18 -0
  4. package/dist/assertions/row-assertion.d.ts.map +1 -0
  5. package/dist/assertions/row-assertion.js +53 -0
  6. package/dist/assertions/row-assertion.js.map +1 -0
  7. package/dist/assertions/table-assertion.d.ts +17 -0
  8. package/dist/assertions/table-assertion.d.ts.map +1 -0
  9. package/dist/assertions/table-assertion.js +33 -0
  10. package/dist/assertions/table-assertion.js.map +1 -0
  11. package/dist/extension.d.ts +60 -0
  12. package/dist/extension.d.ts.map +1 -0
  13. package/dist/extension.js +322 -0
  14. package/dist/extension.js.map +1 -0
  15. package/dist/graphs/row-graph.d.ts +61 -0
  16. package/dist/graphs/row-graph.d.ts.map +1 -0
  17. package/dist/graphs/row-graph.js +231 -0
  18. package/dist/graphs/row-graph.js.map +1 -0
  19. package/dist/graphs/table-graph.d.ts +61 -0
  20. package/dist/graphs/table-graph.d.ts.map +1 -0
  21. package/dist/graphs/table-graph.js +123 -0
  22. package/dist/graphs/table-graph.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/types.d.ts +98 -0
  28. package/dist/types.d.ts.map +1 -0
  29. package/dist/types.js +2 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/utils/caller-extractor.d.ts +27 -0
  32. package/dist/utils/caller-extractor.d.ts.map +1 -0
  33. package/dist/utils/caller-extractor.js +144 -0
  34. package/dist/utils/caller-extractor.js.map +1 -0
  35. package/dist/utils/primary-key-extractor.d.ts +23 -0
  36. package/dist/utils/primary-key-extractor.d.ts.map +1 -0
  37. package/dist/utils/primary-key-extractor.js +128 -0
  38. package/dist/utils/primary-key-extractor.js.map +1 -0
  39. package/dist/utils/raw-query-parser.d.ts +17 -0
  40. package/dist/utils/raw-query-parser.d.ts.map +1 -0
  41. package/dist/utils/raw-query-parser.js +58 -0
  42. package/dist/utils/raw-query-parser.js.map +1 -0
  43. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primary-key-extractor.js","sourceRoot":"","sources":["../../src/utils/primary-key-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Attempt to infer the table name from a raw SQL query.
3
+ * This is a best-effort parser for PostgreSQL queries.
4
+ *
5
+ * @param sql The SQL query string
6
+ * @returns The table name if found, or null if inference fails
7
+ */
8
+ export declare function inferTableFromSql(sql: string): string | null;
9
+ /**
10
+ * Check if a SQL query contains a FOR UPDATE clause
11
+ */
12
+ export declare function hasForUpdateClause(sql: string): boolean;
13
+ /**
14
+ * Check if a SQL query is a locking operation (modifies data or acquires locks)
15
+ */
16
+ export declare function isLockingSql(sql: string): boolean;
17
+ //# sourceMappingURL=raw-query-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-query-parser.d.ts","sourceRoot":"","sources":["../../src/utils/raw-query-parser.ts"],"names":[],"mappings":"AAeA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAcjD"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Patterns to extract table names from PostgreSQL queries.
3
+ * Handles both quoted ("TableName") and unquoted (tablename) identifiers.
4
+ */
5
+ const TABLE_PATTERNS = [
6
+ // SELECT ... FROM "Table" or FROM Table (including FOR UPDATE)
7
+ /\bFROM\s+(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))/i,
8
+ // UPDATE "Table" or UPDATE Table
9
+ /\bUPDATE\s+(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))/i,
10
+ // DELETE FROM "Table"
11
+ /\bDELETE\s+FROM\s+(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))/i,
12
+ // INSERT INTO "Table"
13
+ /\bINSERT\s+INTO\s+(?:"([^"]+)"|([a-zA-Z_][a-zA-Z0-9_]*))/i,
14
+ ];
15
+ /**
16
+ * Attempt to infer the table name from a raw SQL query.
17
+ * This is a best-effort parser for PostgreSQL queries.
18
+ *
19
+ * @param sql The SQL query string
20
+ * @returns The table name if found, or null if inference fails
21
+ */
22
+ export function inferTableFromSql(sql) {
23
+ // Normalize whitespace for easier matching
24
+ const normalized = sql.replace(/\s+/g, ' ').trim();
25
+ for (const pattern of TABLE_PATTERNS) {
26
+ const match = normalized.match(pattern);
27
+ if (match) {
28
+ // Return quoted name (match[1]) or unquoted name (match[2])
29
+ const tableName = match[1] || match[2];
30
+ if (tableName) {
31
+ return tableName;
32
+ }
33
+ }
34
+ }
35
+ return null;
36
+ }
37
+ /**
38
+ * Check if a SQL query contains a FOR UPDATE clause
39
+ */
40
+ export function hasForUpdateClause(sql) {
41
+ return /\bFOR\s+(UPDATE|NO\s+KEY\s+UPDATE|SHARE|KEY\s+SHARE)\b/i.test(sql);
42
+ }
43
+ /**
44
+ * Check if a SQL query is a locking operation (modifies data or acquires locks)
45
+ */
46
+ export function isLockingSql(sql) {
47
+ const normalized = sql.replace(/\s+/g, ' ').trim().toUpperCase();
48
+ // Check for DML operations
49
+ if (/^(UPDATE|DELETE|INSERT)\b/.test(normalized)) {
50
+ return true;
51
+ }
52
+ // Check for SELECT ... FOR UPDATE/SHARE
53
+ if (hasForUpdateClause(sql)) {
54
+ return true;
55
+ }
56
+ return false;
57
+ }
58
+ //# sourceMappingURL=raw-query-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-query-parser.js","sourceRoot":"","sources":["../../src/utils/raw-query-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,cAAc,GAAG;IACrB,+DAA+D;IAC/D,kDAAkD;IAClD,iCAAiC;IACjC,oDAAoD;IACpD,sBAAsB;IACtB,2DAA2D;IAC3D,sBAAsB;IACtB,2DAA2D;CAC5D,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,2CAA2C;IAC3C,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAElD,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,4DAA4D;YAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAA;YACtC,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,yDAAyD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAEhE,2BAA2B;IAC3B,IAAI,2BAA2B,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,wCAAwC;IACxC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@mosaic-code/prisma-deadlock-avoidance-tests",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "Prisma extension for detecting deadlock risks by tracking table and row locking order",
8
+ "type": "module",
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "clean": "rm -rf dist",
19
+ "build": "tsc",
20
+ "typecheck": "tsc --noEmit",
21
+ "prepublishOnly": "npm run clean && npm run build",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:unit": "vitest run tests/unit",
25
+ "test:integration": "vitest run tests/integration",
26
+ "db:up": "docker compose up -d",
27
+ "db:down": "docker compose down",
28
+ "db:push": "prisma db push",
29
+ "db:generate": "prisma generate",
30
+ "db:setup": "npm run db:up && sleep 2 && npm run db:push",
31
+ "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
32
+ "release:patch": "npm run changelog && git add CHANGELOG.md && git commit -m \"chore: update changelog\" && npm version patch && git push --follow-tags && npm run build && npm publish",
33
+ "release:minor": "npm run changelog && git add CHANGELOG.md && git commit -m \"chore: update changelog\" && npm version minor && git push --follow-tags && npm run build && npm publish",
34
+ "release:major": "npm run changelog && git add CHANGELOG.md && git commit -m \"chore: update changelog\" && npm version major && git push --follow-tags && npm run build && npm publish",
35
+ "release:dry": "npm run changelog -- --dry-run"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.18.0"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md",
43
+ "LICENSE"
44
+ ],
45
+ "peerDependencies": {
46
+ "@prisma/client": "^7.0.0"
47
+ },
48
+ "dependencies": {
49
+ "@dagrejs/graphlib": "^2.2.4"
50
+ },
51
+ "devDependencies": {
52
+ "@prisma/adapter-pg": "^7.2.0",
53
+ "@prisma/client": "^7.0.0",
54
+ "@types/node": "^22.0.0",
55
+ "conventional-changelog-cli": "^5.0.0",
56
+ "dotenv": "^17.2.3",
57
+ "pg": "^8.16.3",
58
+ "prisma": "^7.0.0",
59
+ "typescript": "^5.7.0",
60
+ "vitest": "^2.1.0"
61
+ },
62
+ "keywords": [
63
+ "prisma",
64
+ "deadlock",
65
+ "testing",
66
+ "row-locking",
67
+ "transaction"
68
+ ],
69
+ "license": "NoHarm",
70
+ "repository": {
71
+ "type": "git",
72
+ "url": "git+https://github.com/mosaic-code-coop/prisma-deadlock-avoidance-tests.git"
73
+ },
74
+ "homepage": "https://github.com/mosaic-code-coop/prisma-deadlock-avoidance-tests#readme",
75
+ "bugs": {
76
+ "url": "https://github.com/mosaic-code-coop/prisma-deadlock-avoidance-tests/issues"
77
+ },
78
+ "author": "Chris Jensen <2920476+chrisjensen@users.noreply.github.com> (https://github.com/chrisjensen)"
79
+ }