@nest-boot/row-level-security 7.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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/dist/decorators/policy.decorator.d.ts +18 -0
  3. package/dist/decorators/policy.decorator.js +257 -0
  4. package/dist/decorators/policy.decorator.js.map +1 -0
  5. package/dist/decorators/policy.decorator.spec.d.ts +1 -0
  6. package/dist/decorators/policy.decorator.spec.js +498 -0
  7. package/dist/decorators/policy.decorator.spec.js.map +1 -0
  8. package/dist/enums/policy-command.enum.d.ts +13 -0
  9. package/dist/enums/policy-command.enum.js +18 -0
  10. package/dist/enums/policy-command.enum.js.map +1 -0
  11. package/dist/enums/policy-mode.enum.d.ts +7 -0
  12. package/dist/enums/policy-mode.enum.js +12 -0
  13. package/dist/enums/policy-mode.enum.js.map +1 -0
  14. package/dist/index.d.ts +9 -0
  15. package/dist/index.js +26 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.spec.d.ts +1 -0
  18. package/dist/index.spec.js +70 -0
  19. package/dist/index.spec.js.map +1 -0
  20. package/dist/interfaces/index.d.ts +5 -0
  21. package/dist/interfaces/index.js +21 -0
  22. package/dist/interfaces/index.js.map +1 -0
  23. package/dist/interfaces/policy-metadata.interface.d.ts +62 -0
  24. package/dist/interfaces/policy-metadata.interface.js +3 -0
  25. package/dist/interfaces/policy-metadata.interface.js.map +1 -0
  26. package/dist/interfaces/policy-options.interface.d.ts +21 -0
  27. package/dist/interfaces/policy-options.interface.js +3 -0
  28. package/dist/interfaces/policy-options.interface.js.map +1 -0
  29. package/dist/interfaces/policy-sql-options.interface.d.ts +21 -0
  30. package/dist/interfaces/policy-sql-options.interface.js +3 -0
  31. package/dist/interfaces/policy-sql-options.interface.js.map +1 -0
  32. package/dist/interfaces/row-level-security-migration-generator.interface.d.ts +65 -0
  33. package/dist/interfaces/row-level-security-migration-generator.interface.js +3 -0
  34. package/dist/interfaces/row-level-security-migration-generator.interface.js.map +1 -0
  35. package/dist/interfaces/row-level-security-options.interface.d.ts +18 -0
  36. package/dist/interfaces/row-level-security-options.interface.js +3 -0
  37. package/dist/interfaces/row-level-security-options.interface.js.map +1 -0
  38. package/dist/row-level-security-context.d.ts +14 -0
  39. package/dist/row-level-security-context.js +38 -0
  40. package/dist/row-level-security-context.js.map +1 -0
  41. package/dist/row-level-security-context.spec.d.ts +1 -0
  42. package/dist/row-level-security-context.spec.js +29 -0
  43. package/dist/row-level-security-context.spec.js.map +1 -0
  44. package/dist/row-level-security-entity-manager.d.ts +22 -0
  45. package/dist/row-level-security-entity-manager.js +135 -0
  46. package/dist/row-level-security-entity-manager.js.map +1 -0
  47. package/dist/row-level-security-entity-manager.spec.d.ts +1 -0
  48. package/dist/row-level-security-entity-manager.spec.js +200 -0
  49. package/dist/row-level-security-entity-manager.spec.js.map +1 -0
  50. package/dist/row-level-security-migration-generator.d.ts +14 -0
  51. package/dist/row-level-security-migration-generator.js +294 -0
  52. package/dist/row-level-security-migration-generator.js.map +1 -0
  53. package/dist/row-level-security-migration-generator.spec.d.ts +1 -0
  54. package/dist/row-level-security-migration-generator.spec.js +468 -0
  55. package/dist/row-level-security-migration-generator.spec.js.map +1 -0
  56. package/dist/row-level-security-migration.d.ts +11 -0
  57. package/dist/row-level-security-migration.js +28 -0
  58. package/dist/row-level-security-migration.js.map +1 -0
  59. package/dist/row-level-security-migration.spec.d.ts +1 -0
  60. package/dist/row-level-security-migration.spec.js +40 -0
  61. package/dist/row-level-security-migration.spec.js.map +1 -0
  62. package/dist/tsconfig.build.tsbuildinfo +1 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -0
  64. package/dist/utils/assert-identifier.d.ts +2 -0
  65. package/dist/utils/assert-identifier.js +11 -0
  66. package/dist/utils/assert-identifier.js.map +1 -0
  67. package/dist/utils/assert-snake-case.d.ts +2 -0
  68. package/dist/utils/assert-snake-case.js +10 -0
  69. package/dist/utils/assert-snake-case.js.map +1 -0
  70. package/dist/utils/create-policy-bootstrap-sql-statements.d.ts +2 -0
  71. package/dist/utils/create-policy-bootstrap-sql-statements.js +17 -0
  72. package/dist/utils/create-policy-bootstrap-sql-statements.js.map +1 -0
  73. package/dist/utils/create-policy-down-sql.d.ts +3 -0
  74. package/dist/utils/create-policy-down-sql.js +30 -0
  75. package/dist/utils/create-policy-down-sql.js.map +1 -0
  76. package/dist/utils/create-policy-up-sql-statements.d.ts +3 -0
  77. package/dist/utils/create-policy-up-sql-statements.js +114 -0
  78. package/dist/utils/create-policy-up-sql-statements.js.map +1 -0
  79. package/dist/utils/default-row-level-security-options.d.ts +3 -0
  80. package/dist/utils/default-row-level-security-options.js +9 -0
  81. package/dist/utils/default-row-level-security-options.js.map +1 -0
  82. package/dist/utils/escape-sql-literal.d.ts +2 -0
  83. package/dist/utils/escape-sql-literal.js +8 -0
  84. package/dist/utils/escape-sql-literal.js.map +1 -0
  85. package/dist/utils/get-row-level-security-options.d.ts +8 -0
  86. package/dist/utils/get-row-level-security-options.js +9 -0
  87. package/dist/utils/get-row-level-security-options.js.map +1 -0
  88. package/dist/utils/index.d.ts +13 -0
  89. package/dist/utils/index.js +29 -0
  90. package/dist/utils/index.js.map +1 -0
  91. package/dist/utils/policy-migration-sql.spec.d.ts +1 -0
  92. package/dist/utils/policy-migration-sql.spec.js +168 -0
  93. package/dist/utils/policy-migration-sql.spec.js.map +1 -0
  94. package/dist/utils/policy-sql-options.d.ts +12 -0
  95. package/dist/utils/policy-sql-options.js +3 -0
  96. package/dist/utils/policy-sql-options.js.map +1 -0
  97. package/dist/utils/quote-identifier.d.ts +2 -0
  98. package/dist/utils/quote-identifier.js +10 -0
  99. package/dist/utils/quote-identifier.js.map +1 -0
  100. package/dist/utils/quote-qualified-identifier.d.ts +2 -0
  101. package/dist/utils/quote-qualified-identifier.js +9 -0
  102. package/dist/utils/quote-qualified-identifier.js.map +1 -0
  103. package/dist/utils/row-level-security-context-builder.d.ts +12 -0
  104. package/dist/utils/row-level-security-context-builder.js +40 -0
  105. package/dist/utils/row-level-security-context-builder.js.map +1 -0
  106. package/dist/utils/row-level-security-context-builder.spec.d.ts +1 -0
  107. package/dist/utils/row-level-security-context-builder.spec.js +40 -0
  108. package/dist/utils/row-level-security-context-builder.spec.js.map +1 -0
  109. package/dist/utils/row-level-security-context-builder.types.d.ts +10 -0
  110. package/dist/utils/row-level-security-context-builder.types.js +3 -0
  111. package/dist/utils/row-level-security-context-builder.types.js.map +1 -0
  112. package/dist/utils/row-level-security-options-state.d.ts +4 -0
  113. package/dist/utils/row-level-security-options-state.js +8 -0
  114. package/dist/utils/row-level-security-options-state.js.map +1 -0
  115. package/dist/utils/set-row-level-security-options.d.ts +3 -0
  116. package/dist/utils/set-row-level-security-options.js +13 -0
  117. package/dist/utils/set-row-level-security-options.js.map +1 -0
  118. package/package.json +77 -0
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const postgresql_1 = require("@mikro-orm/postgresql");
4
+ const request_context_1 = require("@nest-boot/request-context");
5
+ const row_level_security_context_1 = require("./row-level-security-context");
6
+ const row_level_security_entity_manager_1 = require("./row-level-security-entity-manager");
7
+ const set_row_level_security_options_1 = require("./utils/set-row-level-security-options");
8
+ describe("RowLevelSecurityEntityManager", () => {
9
+ afterEach(() => {
10
+ jest.restoreAllMocks();
11
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)();
12
+ });
13
+ it("sets authenticated row level security transaction context", async () => {
14
+ const rawSql = [];
15
+ mockSuperTransactional(rawSql);
16
+ const result = await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
17
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
18
+ authenticatedRole: "app_authenticated",
19
+ isAuthenticated: () => true,
20
+ getContext: () => [["tenant_id", "42"]],
21
+ });
22
+ return await callTransactional();
23
+ });
24
+ expect(result).toBe("transaction-result");
25
+ expect(rawSql).toEqual([
26
+ "SET LOCAL ROLE app_authenticated;\nSELECT set_config('app.tenant_id', '42', true);",
27
+ ]);
28
+ });
29
+ it("omits context SQL when no row level security context values are present", async () => {
30
+ const rawSql = [];
31
+ mockSuperTransactional(rawSql);
32
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
33
+ await callTransactional();
34
+ });
35
+ expect(rawSql).toEqual(["SET LOCAL ROLE anonymous;"]);
36
+ });
37
+ it("throws when a transaction context is unavailable", async () => {
38
+ jest
39
+ .spyOn(postgresql_1.EntityManager.prototype, "transactional")
40
+ .mockImplementation(async (cb) => {
41
+ return await cb({
42
+ getTransactionContext: () => undefined,
43
+ });
44
+ });
45
+ await expect(request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), callTransactional)).rejects.toThrow("Transaction context is not available");
46
+ });
47
+ it("uses the anonymous role when no user is present", async () => {
48
+ const rawSql = [];
49
+ mockSuperTransactional(rawSql);
50
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
51
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
52
+ anonymousRole: "app_anonymous",
53
+ getContext: () => [["tenant_id", "42"]],
54
+ });
55
+ await callTransactional();
56
+ });
57
+ expect(rawSql).toEqual([
58
+ "SET LOCAL ROLE app_anonymous;\nSELECT set_config('app.tenant_id', '42', true);",
59
+ ]);
60
+ });
61
+ it("uses the default authenticated role when the tenant authentication marker is present", async () => {
62
+ const rawSql = [];
63
+ mockSuperTransactional(rawSql);
64
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
65
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
66
+ isAuthenticated: () => true,
67
+ getContext: () => [["tenant_id", "42"]],
68
+ });
69
+ await callTransactional();
70
+ });
71
+ expect(rawSql).toEqual([
72
+ "SET LOCAL ROLE authenticated;\nSELECT set_config('app.tenant_id', '42', true);",
73
+ ]);
74
+ });
75
+ it("uses the request context role when one is set", async () => {
76
+ const rawSql = [];
77
+ mockSuperTransactional(rawSql);
78
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
79
+ row_level_security_context_1.RowLevelSecurityContext.setRole("service_role");
80
+ row_level_security_context_1.RowLevelSecurityContext.set("tenant_id", "42");
81
+ await callTransactional();
82
+ });
83
+ expect(rawSql).toEqual([
84
+ "SET LOCAL ROLE service_role;\nSELECT set_config('app.tenant_id', '42', true);",
85
+ ]);
86
+ });
87
+ it("sets additional row level security context values from RequestContext", async () => {
88
+ const rawSql = [];
89
+ mockSuperTransactional(rawSql);
90
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
91
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
92
+ getContext: () => [["tenant_id", "42"]],
93
+ });
94
+ row_level_security_context_1.RowLevelSecurityContext.set("user_id", "7");
95
+ await callTransactional();
96
+ });
97
+ expect(rawSql).toEqual([
98
+ "SET LOCAL ROLE anonymous;\nSELECT set_config('app.tenant_id', '42', true),set_config('app.user_id', '7', true);",
99
+ ]);
100
+ });
101
+ it("uses the default anonymous role when the tenant authentication marker is absent", async () => {
102
+ const rawSql = [];
103
+ mockSuperTransactional(rawSql);
104
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), async () => {
105
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
106
+ getContext: () => [["tenant_id", "42"]],
107
+ });
108
+ await callTransactional();
109
+ });
110
+ expect(rawSql).toEqual([
111
+ "SET LOCAL ROLE anonymous;\nSELECT set_config('app.tenant_id', '42', true);",
112
+ ]);
113
+ });
114
+ it("delegates without tenant SQL when shouldApply returns false", async () => {
115
+ const rawSql = [];
116
+ const transactionalSpy = mockSuperTransactional(rawSql);
117
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
118
+ shouldApply: () => false,
119
+ });
120
+ const result = await callTransactional();
121
+ expect(result).toBe("transaction-result");
122
+ expect(rawSql).toEqual([]);
123
+ expect(transactionalSpy).toHaveBeenCalledTimes(1);
124
+ });
125
+ it("rejects unsafe database role names", async () => {
126
+ const rawSql = [];
127
+ mockSuperTransactional(rawSql);
128
+ (0, set_row_level_security_options_1.setRowLevelSecurityOptions)({
129
+ authenticatedRole: "app.authenticated",
130
+ isAuthenticated: () => true,
131
+ });
132
+ await expect(request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), callTransactional)).rejects.toThrow("Row level security database role must be snake_case");
133
+ });
134
+ it.each(getDelegatedMethodCases())("wraps %s in a row level security transaction when outside a transaction", async (methodName, args, result) => {
135
+ const delegatedMethod = jest.fn(() => Promise.resolve(result));
136
+ const transactional = jest.fn(async (cb) => {
137
+ return await cb({
138
+ [methodName]: delegatedMethod,
139
+ });
140
+ });
141
+ const entityManager = {
142
+ isInTransaction: () => false,
143
+ transactional,
144
+ };
145
+ const actual = await row_level_security_entity_manager_1.RowLevelSecurityEntityManager.prototype[methodName].call(entityManager, ...args);
146
+ expect(actual).toBe(result);
147
+ expect(transactional).toHaveBeenCalledTimes(1);
148
+ expect(delegatedMethod.mock.calls[0]?.slice(0, args.length)).toEqual(args);
149
+ });
150
+ it.each(getDelegatedMethodCases())("delegates %s directly when already inside a transaction", async (methodName, args, result) => {
151
+ const superMethod = jest
152
+ .spyOn(postgresql_1.EntityManager.prototype, methodName)
153
+ .mockResolvedValue(result);
154
+ const entityManager = {
155
+ isInTransaction: () => true,
156
+ };
157
+ const actual = await row_level_security_entity_manager_1.RowLevelSecurityEntityManager.prototype[methodName].call(entityManager, ...args);
158
+ expect(actual).toBe(result);
159
+ expect(superMethod.mock.calls[0]?.slice(0, args.length)).toEqual(args);
160
+ });
161
+ });
162
+ function mockSuperTransactional(rawSql) {
163
+ return jest
164
+ .spyOn(postgresql_1.EntityManager.prototype, "transactional")
165
+ .mockImplementation(async (cb) => {
166
+ const em = {
167
+ getTransactionContext: () => ({
168
+ raw: (sql) => {
169
+ rawSql.push(sql);
170
+ return Promise.resolve();
171
+ },
172
+ }),
173
+ };
174
+ return await cb(em);
175
+ });
176
+ }
177
+ async function callTransactional() {
178
+ return await row_level_security_entity_manager_1.RowLevelSecurityEntityManager.prototype.transactional.call({}, () => "transaction-result");
179
+ }
180
+ function getDelegatedMethodCases() {
181
+ class Entity {
182
+ }
183
+ return [
184
+ ["find", [Entity, { id: "1" }, { limit: 1 }], [{ id: "1" }]],
185
+ ["findAll", [Entity, { limit: 1 }], [{ id: "1" }]],
186
+ ["findOne", [Entity, { id: "1" }], { id: "1" }],
187
+ ["findOneOrFail", [Entity, { id: "1" }], { id: "1" }],
188
+ ["findAndCount", [Entity, { id: "1" }], [[{ id: "1" }], 1]],
189
+ ["findByCursor", [Entity, {}, { first: 10 }], { items: [] }],
190
+ ["count", [Entity, { active: true }], 1],
191
+ ["insert", [Entity, { name: "one" }], "1"],
192
+ ["insertMany", [Entity, [{ name: "one" }]], ["1"]],
193
+ ["nativeUpdate", [Entity, { id: "1" }, { name: "one" }], 1],
194
+ ["nativeDelete", [Entity, { id: "1" }], 1],
195
+ ["upsert", [Entity, { id: "1", name: "one" }], { id: "1" }],
196
+ ["upsertMany", [Entity, [{ id: "1", name: "one" }]], [{ id: "1" }]],
197
+ ["flush", [], undefined],
198
+ ];
199
+ }
200
+ //# sourceMappingURL=row-level-security-entity-manager.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-level-security-entity-manager.spec.js","sourceRoot":"","sources":["../src/row-level-security-entity-manager.spec.ts"],"names":[],"mappings":";;AAAA,sDAAsD;AACtD,gEAA4D;AAE5D,6EAAuE;AACvE,2FAAoF;AACpF,2FAAoF;AAEpF,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAA,2DAA0B,GAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,gCAAc,CAAC,GAAG,CACrC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACpC,KAAK,IAAI,EAAE;YACT,IAAA,2DAA0B,EAAC;gBACzB,iBAAiB,EAAE,mBAAmB;gBACtC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;gBAC3B,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aACxC,CAAC,CAAC;YAEH,OAAO,MAAM,iBAAiB,EAAE,CAAC;QACnC,CAAC,CACF,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,oFAAoF;SACrF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,IAAI;aACD,KAAK,CAAC,0BAAa,CAAC,SAAS,EAAE,eAAe,CAAC;aAC/C,kBAAkB,CAAC,KAAK,EAAE,EAAO,EAAE,EAAE;YACpC,OAAO,MAAM,EAAE,CAAC;gBACd,qBAAqB,EAAE,GAAG,EAAE,CAAC,SAAS;aACvC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEL,MAAM,MAAM,CACV,gCAAc,CAAC,GAAG,CAChB,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACpC,iBAAiB,CAClB,CACF,CAAC,OAAO,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,IAAA,2DAA0B,EAAC;gBACzB,aAAa,EAAE,eAAe;gBAC9B,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aACxC,CAAC,CAAC;YAEH,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,gFAAgF;SACjF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;QACpG,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,IAAA,2DAA0B,EAAC;gBACzB,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;gBAC3B,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aACxC,CAAC,CAAC;YAEH,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,gFAAgF;SACjF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,oDAAuB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAChD,oDAAuB,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAE/C,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,+EAA+E;SAChF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,IAAA,2DAA0B,EAAC;gBACzB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aACxC,CAAC,CAAC;YACH,oDAAuB,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAE5C,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,iHAAiH;SAClH,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAE/B,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACxE,IAAA,2DAA0B,EAAC;gBACzB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aACxC,CAAC,CAAC;YAEH,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,4EAA4E;SAC7E,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACxD,IAAA,2DAA0B,EAAC;YACzB,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK;SACzB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAA,2DAA0B,EAAC;YACzB,iBAAiB,EAAE,mBAAmB;YACtC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;SAC5B,CAAC,CAAC;QAEH,MAAM,MAAM,CACV,gCAAc,CAAC,GAAG,CAChB,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACpC,iBAAiB,CAClB,CACF,CAAC,OAAO,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAChC,yEAAyE,EACzE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QACjC,MAAM,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,EAAO,EAAE,EAAE;YAC9C,OAAO,MAAM,EAAE,CAAC;gBACd,CAAC,UAAU,CAAC,EAAE,eAAe;aAC9B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,aAAa,GAAG;YACpB,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK;YAC5B,aAAa;SACd,CAAC;QAEF,MAAM,MAAM,GAAG,MACb,iEAA6B,CAAC,SAAS,CAAC,UAAU,CACnD,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC;QAE/B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAClE,IAAI,CACL,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAChC,yDAAyD,EACzD,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,IAAI;aACrB,KAAK,CACJ,0BAAa,CAAC,SAGb,EACD,UAAU,CACX;aACA,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,aAAa,GAAG;YACpB,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;SAC5B,CAAC;QAEF,MAAM,MAAM,GAAG,MACb,iEAA6B,CAAC,SAAS,CAAC,UAAU,CACnD,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC;QAE/B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,sBAAsB,CAAC,MAAgB;IAC9C,OAAO,IAAI;SACR,KAAK,CAAC,0BAAa,CAAC,SAAS,EAAE,eAAe,CAAC;SAC/C,kBAAkB,CAAC,KAAK,EAAE,EAAO,EAAE,EAAE;QACpC,MAAM,EAAE,GAAG;YACT,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC5B,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE;oBACnB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC3B,CAAC;aACF,CAAC;SACH,CAAC;QAEF,OAAO,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,iBAAiB;IAC9B,OAAO,MAAM,iEAA6B,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CACrE,EAAmC,EACnC,GAAG,EAAE,CAAC,oBAAoB,CAC3B,CAAC;AACJ,CAAC;AAkBD,SAAS,uBAAuB;IAK9B,MAAM,MAAM;KAAG;IAEf,OAAO;QACL,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5D,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAClD,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;QAC/C,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;QACrD,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC5D,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACxC,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC;QAC1C,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;QAC3D,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { TSMigrationGenerator } from "@mikro-orm/migrations";
2
+ import type { MigrationDiff } from "./interfaces/row-level-security-migration-generator.interface";
3
+ /** MikroORM TypeScript migration generator that injects generated RLS SQL. */
4
+ export declare class RowLevelSecurityMigrationGenerator extends TSMigrationGenerator {
5
+ private existingPolicyDefinitions?;
6
+ private currentPolicyDefinitions?;
7
+ generate(diff: MigrationDiff, path?: string, name?: string): Promise<[string, string]>;
8
+ generateMigrationFile(className: string, diff: MigrationDiff): string;
9
+ private getPolicyDefinitionChanges;
10
+ private getRelevantPolicyDefinitions;
11
+ private getPolicyDefinitions;
12
+ private getEntityMetadata;
13
+ private getExistingPolicyDefinitionsFromDatabase;
14
+ }
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RowLevelSecurityMigrationGenerator = void 0;
4
+ const migrations_1 = require("@mikro-orm/migrations");
5
+ const policy_decorator_1 = require("./decorators/policy.decorator");
6
+ const policy_command_enum_1 = require("./enums/policy-command.enum");
7
+ const policy_mode_enum_1 = require("./enums/policy-mode.enum");
8
+ const create_policy_bootstrap_sql_statements_1 = require("./utils/create-policy-bootstrap-sql-statements");
9
+ const create_policy_down_sql_1 = require("./utils/create-policy-down-sql");
10
+ const create_policy_up_sql_statements_1 = require("./utils/create-policy-up-sql-statements");
11
+ const escape_sql_literal_1 = require("./utils/escape-sql-literal");
12
+ /** MikroORM TypeScript migration generator that injects generated RLS SQL. */
13
+ class RowLevelSecurityMigrationGenerator extends migrations_1.TSMigrationGenerator {
14
+ async generate(diff, path, name) {
15
+ const entityMetadata = this.getEntityMetadata();
16
+ const currentPolicyDefinitions = this.getPolicyDefinitions(entityMetadata);
17
+ const tableReferences = getPolicyDefinitionTableReferences(currentPolicyDefinitions);
18
+ this.existingPolicyDefinitions =
19
+ await this.getExistingPolicyDefinitionsFromDatabase(tableReferences);
20
+ this.currentPolicyDefinitions = currentPolicyDefinitions;
21
+ try {
22
+ return await super.generate(diff, path, name);
23
+ }
24
+ finally {
25
+ this.existingPolicyDefinitions = undefined;
26
+ this.currentPolicyDefinitions = undefined;
27
+ }
28
+ }
29
+ generateMigrationFile(className, diff) {
30
+ const currentPolicyDefinitions = this.currentPolicyDefinitions ?? this.getPolicyDefinitions();
31
+ const { added, removed } = this.getPolicyDefinitionChanges(diff, currentPolicyDefinitions);
32
+ if (added.length === 0 && removed.length === 0) {
33
+ return super.generateMigrationFile(className, diff);
34
+ }
35
+ const policyDiff = {
36
+ up: [
37
+ ...removed.map((definition) => (0, create_policy_down_sql_1.createPolicyDownSql)(definition)),
38
+ ...diff.up,
39
+ ...(added.length > 0 ? (0, create_policy_bootstrap_sql_statements_1.createPolicyBootstrapSqlStatements)() : []),
40
+ ...getDefinitionBootstrapSql(added),
41
+ ...added.flatMap((definition) => (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)(definition)),
42
+ ],
43
+ down: [
44
+ ...added.map((definition) => (0, create_policy_down_sql_1.createPolicyDownSql)(definition)),
45
+ ...diff.down,
46
+ ...(removed.length > 0 ? (0, create_policy_bootstrap_sql_statements_1.createPolicyBootstrapSqlStatements)() : []),
47
+ ...getDefinitionBootstrapSql(removed),
48
+ ...removed.flatMap((definition) => (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)(definition)),
49
+ ],
50
+ };
51
+ const migrationFile = super.generateMigrationFile(className, policyDiff);
52
+ return convertMigrationBaseClass(migrationFile);
53
+ }
54
+ getPolicyDefinitionChanges(diff, currentPolicyDefinitions) {
55
+ if (!this.existingPolicyDefinitions) {
56
+ return {
57
+ added: this.getRelevantPolicyDefinitions(diff, currentPolicyDefinitions),
58
+ removed: [],
59
+ };
60
+ }
61
+ const existingPolicyDefinitions = this.existingPolicyDefinitions;
62
+ return {
63
+ added: currentPolicyDefinitions.filter((definition) => !hasPolicyDefinitionWithSameContent(existingPolicyDefinitions, definition) || isPolicyDefinitionIntroduced(definition, diff.up)),
64
+ removed: existingPolicyDefinitions.filter((definition) => !hasPolicyDefinitionWithSameContent(currentPolicyDefinitions, definition)),
65
+ };
66
+ }
67
+ getRelevantPolicyDefinitions(diff, policyDefinitions) {
68
+ if (diff.up.length === 0 && diff.down.length === 0) {
69
+ return policyDefinitions;
70
+ }
71
+ return policyDefinitions.filter((definition) => isPolicyDefinitionIntroduced(definition, diff.up));
72
+ }
73
+ getPolicyDefinitions(metadata = this.getEntityMetadata()) {
74
+ return sortPolicyDefinitions(metadata.flatMap((entityMetadata) => {
75
+ if (!entityMetadata.class) {
76
+ return [];
77
+ }
78
+ const entityName = getEntityName(entityMetadata);
79
+ const schemaName = normalizeSchemaName(entityMetadata.schema);
80
+ const tableName = getTableName(entityMetadata);
81
+ const policyEntityMetadata = {
82
+ entityName,
83
+ schemaName,
84
+ tableName,
85
+ properties: entityMetadata.properties,
86
+ };
87
+ return (0, policy_decorator_1.getPolicyDefinitions)(entityMetadata.class, policyEntityMetadata).map((policy) => ({
88
+ entityName,
89
+ schemaName,
90
+ tableName,
91
+ policyName: policy.name,
92
+ mode: policy.mode,
93
+ command: policy.command,
94
+ using: policy.using,
95
+ withCheck: policy.withCheck,
96
+ roles: policy.roles,
97
+ bootstrapSql: policy.bootstrapSql,
98
+ }));
99
+ }));
100
+ }
101
+ getEntityMetadata() {
102
+ const driver = this
103
+ .driver;
104
+ const allMetadata = (driver.getMetadata?.() ?? driver.config?.getMetadata?.())?.getAll();
105
+ if (!allMetadata) {
106
+ throw new Error("MikroORM metadata storage is not available");
107
+ }
108
+ return Array.isArray(allMetadata)
109
+ ? allMetadata
110
+ : Object.values(allMetadata);
111
+ }
112
+ async getExistingPolicyDefinitionsFromDatabase(tableReferences) {
113
+ const uniqueTableReferences = dedupeTableReferences(tableReferences);
114
+ if (uniqueTableReferences.length === 0) {
115
+ return [];
116
+ }
117
+ const driver = this
118
+ .driver;
119
+ const connection = driver.getConnection?.();
120
+ if (!connection) {
121
+ return undefined;
122
+ }
123
+ const rows = await connection.execute(/* SQL */ `
124
+ SELECT
125
+ p.polname AS policy_name,
126
+ n.nspname AS schema_name,
127
+ c.relname AS table_name,
128
+ p.polpermissive AS permissive,
129
+ p.polcmd AS command,
130
+ pg_get_expr(p.polqual, p.polrelid) AS qual,
131
+ pg_get_expr(p.polwithcheck, p.polrelid) AS with_check,
132
+ ARRAY(
133
+ SELECT roles.rolname
134
+ FROM unnest(p.polroles) policy_role(role_oid)
135
+ INNER JOIN pg_roles roles ON roles.oid = policy_role.role_oid
136
+ WHERE policy_role.role_oid <> 0
137
+ ORDER BY roles.rolname
138
+ ) AS roles
139
+ FROM pg_policy p
140
+ INNER JOIN pg_class c ON c.oid = p.polrelid
141
+ INNER JOIN pg_namespace n ON n.oid = c.relnamespace
142
+ WHERE (n.nspname, c.relname) in (${uniqueTableReferences
143
+ .map((table) => `('${(0, escape_sql_literal_1.escapeSqlLiteral)(table.schemaName)}', '${(0, escape_sql_literal_1.escapeSqlLiteral)(table.tableName)}')`)
144
+ .join(", ")})
145
+ ORDER BY n.nspname, c.relname
146
+ `);
147
+ return sortPolicyDefinitions(rows.map(createPolicyDefinitionFromPolicyRow));
148
+ }
149
+ }
150
+ exports.RowLevelSecurityMigrationGenerator = RowLevelSecurityMigrationGenerator;
151
+ function convertMigrationBaseClass(migrationFile) {
152
+ const migrationImport = "import { Migration } from '@mikro-orm/migrations';";
153
+ const migrationBaseClass = "extends Migration";
154
+ if (!migrationFile.includes(migrationImport) ||
155
+ !migrationFile.includes(migrationBaseClass)) {
156
+ throw new Error("MikroORM migration output format is not supported");
157
+ }
158
+ return migrationFile
159
+ .replace(migrationImport, "import { RowLevelSecurityMigration } from '@nest-boot/row-level-security';")
160
+ .replace(migrationBaseClass, "extends RowLevelSecurityMigration");
161
+ }
162
+ function getDefinitionBootstrapSql(definitions) {
163
+ return [
164
+ ...new Set(definitions.flatMap((definition) => definition.bootstrapSql ?? [])),
165
+ ];
166
+ }
167
+ function getPolicyDefinitionTableReferences(definitions) {
168
+ return definitions.map((definition) => ({
169
+ schemaName: definition.schemaName,
170
+ tableName: definition.tableName,
171
+ }));
172
+ }
173
+ function dedupeTableReferences(tableReferences) {
174
+ return [
175
+ ...new Map(tableReferences.map((table) => [
176
+ `${table.schemaName}.${table.tableName}`,
177
+ table,
178
+ ])).values(),
179
+ ];
180
+ }
181
+ function isPolicyDefinitionIntroduced(definition, upSql) {
182
+ return upSql.some((sql) => isCreateTableStatement(sql, definition));
183
+ }
184
+ function hasPolicyDefinitionWithSameContent(definitions, definition) {
185
+ return definitions.some((candidate) => getPolicyDefinitionKey(candidate) ===
186
+ getPolicyDefinitionKey(definition) &&
187
+ hasSamePolicyDefinitionContent(candidate, definition));
188
+ }
189
+ function hasSamePolicyDefinitionContent(left, right) {
190
+ return (normalizePolicyMode(left.mode) === normalizePolicyMode(right.mode) &&
191
+ normalizePolicyCommand(left.command) ===
192
+ normalizePolicyCommand(right.command) &&
193
+ normalizePolicyExpression(left.using) ===
194
+ normalizePolicyExpression(right.using) &&
195
+ normalizePolicyExpression(left.withCheck) ===
196
+ normalizePolicyExpression(right.withCheck) &&
197
+ normalizePolicyRoles(left.roles).join("\n") ===
198
+ normalizePolicyRoles(right.roles).join("\n"));
199
+ }
200
+ function normalizePolicyMode(mode) {
201
+ return mode ?? policy_mode_enum_1.PolicyMode.PERMISSIVE;
202
+ }
203
+ function normalizePolicyCommand(command) {
204
+ return command ?? policy_command_enum_1.PolicyCommand.ALL;
205
+ }
206
+ function normalizePolicyExpression(expression) {
207
+ return expression?.trim() ?? "";
208
+ }
209
+ function normalizePolicyRoles(roles) {
210
+ return [
211
+ ...new Set((roles ?? []).filter((role) => role.toLowerCase() !== "public")),
212
+ ].sort();
213
+ }
214
+ function sortPolicyDefinitions(definitions) {
215
+ return [...definitions].sort((left, right) => getPolicyDefinitionKey(left).localeCompare(getPolicyDefinitionKey(right)));
216
+ }
217
+ function getPolicyDefinitionKey(definition) {
218
+ return [
219
+ definition.schemaName,
220
+ definition.tableName,
221
+ definition.policyName,
222
+ ].join(".");
223
+ }
224
+ function createPolicyDefinitionFromPolicyRow(row) {
225
+ return {
226
+ entityName: `${row.schema_name}.${row.table_name}`,
227
+ schemaName: row.schema_name,
228
+ tableName: row.table_name,
229
+ policyName: row.policy_name,
230
+ mode: row.permissive === false ? policy_mode_enum_1.PolicyMode.RESTRICTIVE : policy_mode_enum_1.PolicyMode.PERMISSIVE,
231
+ command: getPolicyCommandFromDatabase(row.command),
232
+ using: row.qual ?? undefined,
233
+ withCheck: row.with_check ?? undefined,
234
+ roles: normalizePolicyRowRoles(row.roles),
235
+ };
236
+ }
237
+ function normalizePolicyRowRoles(roles) {
238
+ if (!roles) {
239
+ return [];
240
+ }
241
+ if (Array.isArray(roles)) {
242
+ return normalizePolicyRoles(roles);
243
+ }
244
+ return normalizePolicyRoles(roles
245
+ .replace(/^{|}$/g, "")
246
+ .split(",")
247
+ .map((role) => role.trim())
248
+ .filter(Boolean));
249
+ }
250
+ function getPolicyCommandFromDatabase(command) {
251
+ if (command === "r") {
252
+ return policy_command_enum_1.PolicyCommand.SELECT;
253
+ }
254
+ if (command === "a") {
255
+ return policy_command_enum_1.PolicyCommand.INSERT;
256
+ }
257
+ if (command === "w") {
258
+ return policy_command_enum_1.PolicyCommand.UPDATE;
259
+ }
260
+ if (command === "d") {
261
+ return policy_command_enum_1.PolicyCommand.DELETE;
262
+ }
263
+ return policy_command_enum_1.PolicyCommand.ALL;
264
+ }
265
+ function isCreateTableStatement(sql, definition) {
266
+ return new RegExp(`create\\s+table\\s+(?:if\\s+not\\s+exists\\s+)?${createTableReferencePattern(definition)}(?:\\s|\\()`, "i").test(sql);
267
+ }
268
+ function createTableReferencePattern(definition) {
269
+ const table = `"${escapeRegExp(definition.tableName)}"`;
270
+ if (definition.schemaName === "public") {
271
+ return `(?:"public"\\.)?${table}`;
272
+ }
273
+ return `"${escapeRegExp(definition.schemaName)}"\\.${table}`;
274
+ }
275
+ function normalizeSchemaName(schemaName) {
276
+ return !schemaName || schemaName === "*" ? "public" : schemaName;
277
+ }
278
+ function getTableName(entityMetadata) {
279
+ const tableName = entityMetadata.tableName ?? entityMetadata.collection;
280
+ if (!tableName) {
281
+ throw new Error(`Policy entity ${getEntityName(entityMetadata)} does not have a table name`);
282
+ }
283
+ return tableName;
284
+ }
285
+ function getEntityName(entityMetadata) {
286
+ return (entityMetadata.class?.name ??
287
+ entityMetadata.className ??
288
+ entityMetadata.name ??
289
+ "UnknownEntity");
290
+ }
291
+ function escapeRegExp(value) {
292
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
293
+ }
294
+ //# sourceMappingURL=row-level-security-migration-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-level-security-migration-generator.js","sourceRoot":"","sources":["../src/row-level-security-migration-generator.ts"],"names":[],"mappings":"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"}