@sqldoc/ns-rls 0.0.1 → 0.0.3

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sqldoc/ns-rls",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "description": "Row-Level Security namespace for sqldoc -- generates CREATE POLICY and ALTER TABLE statements",
6
6
  "exports": {
7
7
  ".": {
@@ -14,17 +14,19 @@
14
14
  "types": "./src/index.ts",
15
15
  "files": [
16
16
  "src",
17
+ "!src/__tests__",
17
18
  "package.json"
18
19
  ],
20
+ "scripts": {
21
+ "test": "node --test 'src/__tests__/**/*.test.ts'",
22
+ "typecheck": "tsc --noEmit"
23
+ },
19
24
  "peerDependencies": {
20
- "@sqldoc/core": "0.0.1"
25
+ "@sqldoc/core": "workspace:*"
21
26
  },
22
27
  "devDependencies": {
23
- "typescript": "^5.9.3",
24
- "vitest": "^4.1.0",
25
- "@sqldoc/core": "0.0.1"
26
- },
27
- "scripts": {
28
- "test": "vitest run"
28
+ "@sqldoc/core": "workspace:*",
29
+ "typescript": "catalog:",
30
+ "@sqldoc/test-utils": "workspace:*"
29
31
  }
30
- }
32
+ }
package/src/index.ts CHANGED
@@ -2,6 +2,8 @@ import type { NamespacePlugin, TagContext, TagOutput } from '@sqldoc/core'
2
2
 
3
3
  const plugin: NamespacePlugin = {
4
4
  apiVersion: 1,
5
+ databases: ['postgres'],
6
+ description: 'Row-Level Security policies for PostgreSQL',
5
7
  name: 'rls',
6
8
  tags: {
7
9
  policy: {
@@ -1,119 +0,0 @@
1
- import type { TagContext } from '@sqldoc/core'
2
- import { describe, expect, it } from 'vitest'
3
- import plugin from '../index'
4
-
5
- function makeCtx(overrides: Partial<TagContext> = {}): TagContext {
6
- return {
7
- target: 'table',
8
- objectName: 'users',
9
- tag: { name: '$self', args: {} },
10
- namespaceTags: [],
11
- siblingTags: [],
12
- fileTags: [],
13
- astNode: null,
14
- fileStatements: [],
15
- config: {},
16
- filePath: 'test.sql',
17
- ...overrides,
18
- }
19
- }
20
-
21
- describe('ns-rls plugin', () => {
22
- it('exports apiVersion === 1', () => {
23
- expect(plugin.apiVersion).toBe(1)
24
- })
25
-
26
- it('exports name === "rls"', () => {
27
- expect(plugin.name).toBe('rls')
28
- })
29
-
30
- it('has policy and $self tag entries', () => {
31
- expect(plugin.tags).toHaveProperty('policy')
32
- expect(plugin.tags).toHaveProperty('$self')
33
- })
34
-
35
- describe('onTag', () => {
36
- it('@rls.$self produces ALTER TABLE ENABLE ROW LEVEL SECURITY', () => {
37
- const ctx = makeCtx({
38
- objectName: 'users',
39
- tag: { name: '$self', args: {} },
40
- })
41
- const result = plugin.onTag!(ctx) as any
42
- expect(result.sql).toEqual([{ sql: 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;' }])
43
- })
44
-
45
- it('@rls with null tag name produces ALTER TABLE ENABLE ROW LEVEL SECURITY', () => {
46
- const ctx = makeCtx({
47
- objectName: 'users',
48
- tag: { name: null, args: {} },
49
- })
50
- const result = plugin.onTag!(ctx) as any
51
- expect(result.sql).toEqual([{ sql: 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;' }])
52
- })
53
-
54
- it('@rls.policy with for/to/using produces CREATE POLICY', () => {
55
- const ctx = makeCtx({
56
- objectName: 'users',
57
- tag: {
58
- name: 'policy',
59
- args: { for: 'select', to: 'viewer_role', using: 'true' },
60
- },
61
- })
62
- const result = plugin.onTag!(ctx) as any
63
- expect(result.sql).toHaveLength(1)
64
- expect(result.sql[0].sql).toContain('CREATE POLICY')
65
- expect(result.sql[0].sql).toContain('"users_viewer_role_select"')
66
- expect(result.sql[0].sql).toContain('ON "users"')
67
- expect(result.sql[0].sql).toContain('FOR SELECT')
68
- expect(result.sql[0].sql).toContain('TO viewer_role')
69
- expect(result.sql[0].sql).toContain('USING (true)')
70
- })
71
-
72
- it('@rls.policy with using and check produces both clauses', () => {
73
- const ctx = makeCtx({
74
- objectName: 'users',
75
- tag: {
76
- name: 'policy',
77
- args: {
78
- for: 'all',
79
- to: 'authenticated',
80
- using: 'user_id = current_user_id()',
81
- check: 'user_id = current_user_id()',
82
- },
83
- },
84
- })
85
- const result = plugin.onTag!(ctx) as any
86
- expect(result.sql).toHaveLength(1)
87
- expect(result.sql[0].sql).toContain('"users_authenticated_all"')
88
- expect(result.sql[0].sql).toContain('FOR ALL')
89
- expect(result.sql[0].sql).toContain('TO authenticated')
90
- expect(result.sql[0].sql).toContain('USING (user_id = current_user_id())')
91
- expect(result.sql[0].sql).toContain('WITH CHECK (user_id = current_user_id())')
92
- })
93
-
94
- it('policy name is auto-generated from table + role + command', () => {
95
- const ctx = makeCtx({
96
- objectName: 'orders',
97
- tag: {
98
- name: 'policy',
99
- args: { for: 'insert', to: 'admin_role', using: 'true' },
100
- },
101
- })
102
- const result = plugin.onTag!(ctx) as any
103
- expect(result.sql[0].sql).toContain('"orders_admin_role_insert"')
104
- })
105
-
106
- it('@rls.policy with missing to arg defaults to PUBLIC', () => {
107
- const ctx = makeCtx({
108
- objectName: 'users',
109
- tag: {
110
- name: 'policy',
111
- args: { for: 'select', using: 'true' },
112
- },
113
- })
114
- const result = plugin.onTag!(ctx) as any
115
- expect(result.sql[0].sql).toContain('TO PUBLIC')
116
- expect(result.sql[0].sql).toContain('"users_public_select"')
117
- })
118
- })
119
- })