sql-guard 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -78,6 +78,7 @@ export interface Policy {
78
78
  allowedFunctions?: string[];
79
79
  tableIdentifierMatching?: 'strict' | 'caseInsensitive';
80
80
  resolver?: (unqualified: string) => string | null;
81
+ defaultSchema?: string;
81
82
  }
82
83
  ```
83
84
 
@@ -90,19 +91,47 @@ Defaults and behavior:
90
91
  - `allowedFunctions` defaults to `[]`, which means any function call is denied unless allowlisted.
91
92
  - `tableIdentifierMatching` defaults to `'strict'` (exact case-sensitive table matching).
92
93
  - Set `tableIdentifierMatching: 'caseInsensitive'` to preserve case-insensitive table matching.
93
- - Unqualified table references in SQL are denied unless you provide `resolver` to map them to `schema.table`.
94
+ - Unqualified table references in SQL are denied unless you provide `defaultSchema` or `resolver` to map them to `schema.table`.
95
+ - `defaultSchema`: when provided, unqualified `allowedTables` entries are auto-qualified with this schema, and unqualified SQL references resolve to it.
96
+ - `resolver`: optional function to map unqualified names to qualified names. Takes precedence over `defaultSchema`.
97
+ - Metadata schemas (`information_schema`, `pg_catalog`) are treated specially and must be explicitly allowlisted even when using `defaultSchema`. Setting `defaultSchema` to a metadata schema name does not grant automatic access.
94
98
  - Unqualified function allowlist entries (for example, `lower`) match only unqualified calls (`lower(...)`).
95
99
  - Schema-qualified function calls require schema-qualified allowlist entries (`pg_catalog.current_database`).
96
100
 
97
- Strict policy examples:
101
+ Policy examples:
98
102
 
99
103
  ```ts
104
+ // Explicit schema-qualified tables
100
105
  const strictPolicy = {
101
106
  allowedTables: ['public.users', 'analytics.events'],
102
107
  allowedFunctions: ['lower', 'pg_catalog.current_database'],
103
108
  resolver: (unqualified: string) =>
104
109
  unqualified === 'users' ? 'public.users' : null,
105
110
  };
111
+
112
+ // Using defaultSchema for simpler configuration
113
+ const defaultSchemaPolicy = {
114
+ defaultSchema: 'public',
115
+ allowedTables: ['users', 'orders', 'products'],
116
+ // Treated as ['public.users', 'public.orders', 'public.products']
117
+ };
118
+
119
+ // Mixed: defaultSchema + explicit qualified tables
120
+ const mixedPolicy = {
121
+ defaultSchema: 'public',
122
+ allowedTables: ['users', 'analytics.events'],
123
+ // Treated as ['public.users', 'analytics.events']
124
+ };
125
+
126
+ // Resolver takes precedence over defaultSchema
127
+ const resolverPolicy = {
128
+ defaultSchema: 'public',
129
+ allowedTables: ['public.users', 'archive.users'],
130
+ resolver: (name: string) =>
131
+ name === 'old_users' ? 'archive.users' : null,
132
+ // 'users' resolves to 'public.users' via defaultSchema
133
+ // 'old_users' resolves to 'archive.users' via resolver
134
+ };
106
135
  ```
107
136
 
108
137
  ## Security Model
@@ -151,19 +180,6 @@ This is a guardrail for LLM output. It helps enforce least privilege at the quer
151
180
  - `table`
152
181
  - `function`
153
182
 
154
- ## Publishing
155
-
156
- For first time npm publish:
157
-
158
- ```bash
159
- npm login
160
- npm publish --access public
161
- ```
162
-
163
- Notes:
164
-
165
- - `prepublishOnly` runs typecheck, tests, and build, so publishing requires Bun in your environment.
166
-
167
183
  ## License
168
184
 
169
185
  MIT
@@ -2,27 +2,37 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __moduleCache = /* @__PURE__ */ new WeakMap;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
6
8
  var __toCommonJS = (from) => {
7
- var entry = __moduleCache.get(from), desc;
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
8
10
  if (entry)
9
11
  return entry;
10
12
  entry = __defProp({}, "__esModule", { value: true });
11
- if (from && typeof from === "object" || typeof from === "function")
12
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
- get: () => from[key],
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- }));
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
16
21
  __moduleCache.set(from, entry);
17
22
  return entry;
18
23
  };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
19
29
  var __export = (target, all) => {
20
30
  for (var name in all)
21
31
  __defProp(target, name, {
22
32
  get: all[name],
23
33
  enumerable: true,
24
34
  configurable: true,
25
- set: (newValue) => all[name] = () => newValue
35
+ set: __exportSetter.bind(all, name)
26
36
  });
27
37
  };
28
38
 
@@ -458,6 +468,13 @@ function parseIdentifierSegment(value) {
458
468
  }
459
469
  return { value: trimmed };
460
470
  }
471
+ function isUnqualifiedName(value) {
472
+ if (typeof value !== "string") {
473
+ return false;
474
+ }
475
+ const segments = splitQualifiedNameSegments(value.trim());
476
+ return segments !== null && segments.length === 1;
477
+ }
461
478
  function splitQualifiedNameSegments(value) {
462
479
  if (!value) {
463
480
  return null;
@@ -534,9 +551,21 @@ function normalizeTableReference(ref, policy, mode = policy.tableIdentifierMatch
534
551
  };
535
552
  }
536
553
  }
554
+ if (policy.defaultSchema) {
555
+ const schema = normalizeIdentifier(policy.defaultSchema, mode);
556
+ const name = normalizeIdentifier(ref.name, mode);
557
+ return {
558
+ success: true,
559
+ table: {
560
+ schema,
561
+ name,
562
+ fullyQualified: `${schema}.${name}`
563
+ }
564
+ };
565
+ }
537
566
  return {
538
567
  success: false,
539
- error: `Unqualified table reference '${ref.name}' not allowed without resolver`
568
+ error: `Unqualified table reference '${ref.name}' not allowed. Provide 'defaultSchema' or 'resolver' in policy.`
540
569
  };
541
570
  }
542
571
  function normalizeIdentifier(ident, mode) {
@@ -811,9 +840,27 @@ function compilePolicy(policy) {
811
840
  if (tableIdentifierMatching !== "strict" && tableIdentifierMatching !== "caseInsensitive") {
812
841
  return invalidPolicy("Policy 'tableIdentifierMatching' must be either 'strict' or 'caseInsensitive'");
813
842
  }
843
+ const METADATA_SCHEMAS = new Set(["information_schema", "pg_catalog"]);
844
+ const defaultSchema = policy.defaultSchema?.trim();
845
+ if (defaultSchema !== undefined) {
846
+ if (defaultSchema.length === 0) {
847
+ return invalidPolicy("Policy 'defaultSchema' must be a non-empty string when provided");
848
+ }
849
+ if (defaultSchema.includes(".") || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(defaultSchema)) {
850
+ return invalidPolicy("Policy 'defaultSchema' must be a valid SQL identifier without dots");
851
+ }
852
+ if (METADATA_SCHEMAS.has(defaultSchema.toLowerCase())) {
853
+ return invalidPolicy("Policy 'defaultSchema' cannot be a metadata schema (information_schema, pg_catalog). Metadata tables must be explicitly allowlisted.");
854
+ }
855
+ }
856
+ const normalizedDefaultSchema = defaultSchema ? canonicalizeIdentifier(defaultSchema, tableIdentifierMatching) : undefined;
814
857
  const allowedTables = new Set;
815
858
  for (const table of policy.allowedTables) {
816
- const canonical = canonicalizeQualifiedName(table, tableIdentifierMatching);
859
+ let tableToCanonicalize = table;
860
+ if (normalizedDefaultSchema && isUnqualifiedName(table)) {
861
+ tableToCanonicalize = `${normalizedDefaultSchema}.${table}`;
862
+ }
863
+ const canonical = canonicalizeQualifiedName(tableToCanonicalize, tableIdentifierMatching);
817
864
  if (!canonical) {
818
865
  return invalidPolicy(`Policy entry '${String(table)}' is invalid. allowedTables entries must be schema-qualified as 'schema.table'`);
819
866
  }
@@ -844,7 +891,8 @@ function compilePolicy(policy) {
844
891
  allowedTables,
845
892
  allowedFunctionsUnqualified,
846
893
  allowedFunctionsQualified,
847
- tableIdentifierMatching
894
+ tableIdentifierMatching,
895
+ defaultSchema: normalizedDefaultSchema
848
896
  }
849
897
  };
850
898
  }
package/dist/esm/index.js CHANGED
@@ -411,6 +411,13 @@ function parseIdentifierSegment(value) {
411
411
  }
412
412
  return { value: trimmed };
413
413
  }
414
+ function isUnqualifiedName(value) {
415
+ if (typeof value !== "string") {
416
+ return false;
417
+ }
418
+ const segments = splitQualifiedNameSegments(value.trim());
419
+ return segments !== null && segments.length === 1;
420
+ }
414
421
  function splitQualifiedNameSegments(value) {
415
422
  if (!value) {
416
423
  return null;
@@ -487,9 +494,21 @@ function normalizeTableReference(ref, policy, mode = policy.tableIdentifierMatch
487
494
  };
488
495
  }
489
496
  }
497
+ if (policy.defaultSchema) {
498
+ const schema = normalizeIdentifier(policy.defaultSchema, mode);
499
+ const name = normalizeIdentifier(ref.name, mode);
500
+ return {
501
+ success: true,
502
+ table: {
503
+ schema,
504
+ name,
505
+ fullyQualified: `${schema}.${name}`
506
+ }
507
+ };
508
+ }
490
509
  return {
491
510
  success: false,
492
- error: `Unqualified table reference '${ref.name}' not allowed without resolver`
511
+ error: `Unqualified table reference '${ref.name}' not allowed. Provide 'defaultSchema' or 'resolver' in policy.`
493
512
  };
494
513
  }
495
514
  function normalizeIdentifier(ident, mode) {
@@ -764,9 +783,27 @@ function compilePolicy(policy) {
764
783
  if (tableIdentifierMatching !== "strict" && tableIdentifierMatching !== "caseInsensitive") {
765
784
  return invalidPolicy("Policy 'tableIdentifierMatching' must be either 'strict' or 'caseInsensitive'");
766
785
  }
786
+ const METADATA_SCHEMAS = new Set(["information_schema", "pg_catalog"]);
787
+ const defaultSchema = policy.defaultSchema?.trim();
788
+ if (defaultSchema !== undefined) {
789
+ if (defaultSchema.length === 0) {
790
+ return invalidPolicy("Policy 'defaultSchema' must be a non-empty string when provided");
791
+ }
792
+ if (defaultSchema.includes(".") || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(defaultSchema)) {
793
+ return invalidPolicy("Policy 'defaultSchema' must be a valid SQL identifier without dots");
794
+ }
795
+ if (METADATA_SCHEMAS.has(defaultSchema.toLowerCase())) {
796
+ return invalidPolicy("Policy 'defaultSchema' cannot be a metadata schema (information_schema, pg_catalog). Metadata tables must be explicitly allowlisted.");
797
+ }
798
+ }
799
+ const normalizedDefaultSchema = defaultSchema ? canonicalizeIdentifier(defaultSchema, tableIdentifierMatching) : undefined;
767
800
  const allowedTables = new Set;
768
801
  for (const table of policy.allowedTables) {
769
- const canonical = canonicalizeQualifiedName(table, tableIdentifierMatching);
802
+ let tableToCanonicalize = table;
803
+ if (normalizedDefaultSchema && isUnqualifiedName(table)) {
804
+ tableToCanonicalize = `${normalizedDefaultSchema}.${table}`;
805
+ }
806
+ const canonical = canonicalizeQualifiedName(tableToCanonicalize, tableIdentifierMatching);
770
807
  if (!canonical) {
771
808
  return invalidPolicy(`Policy entry '${String(table)}' is invalid. allowedTables entries must be schema-qualified as 'schema.table'`);
772
809
  }
@@ -797,7 +834,8 @@ function compilePolicy(policy) {
797
834
  allowedTables,
798
835
  allowedFunctionsUnqualified,
799
836
  allowedFunctionsQualified,
800
- tableIdentifierMatching
837
+ tableIdentifierMatching,
838
+ defaultSchema: normalizedDefaultSchema
801
839
  }
802
840
  };
803
841
  }
@@ -1 +1 @@
1
- {"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../src/normalize/identifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,uBAAoE,GACzE,mBAAmB,CAmDrB;AAcD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,EAC3B,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC/B,IAAI,GAAE,uBAAkC,GACvC,OAAO,CAcT"}
1
+ {"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../src/normalize/identifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,uBAAoE,GACzE,mBAAmB,CAiErB;AAcD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,EAC3B,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC/B,IAAI,GAAE,uBAAkC,GACvC,OAAO,CAcT"}
@@ -6,4 +6,18 @@ export interface QualifiedNameParts {
6
6
  }
7
7
  export declare function parseQualifiedName(value: unknown, mode?: TableIdentifierMatching): QualifiedNameParts | null;
8
8
  export declare function canonicalizeIdentifier(value: string, mode: TableIdentifierMatching): string;
9
+ /**
10
+ * Check if a table name is unqualified (has no schema prefix).
11
+ * Uses quote-aware parsing to correctly handle quoted identifiers with dots.
12
+ *
13
+ * Examples:
14
+ * - `users` → true (unqualified)
15
+ * - `"audit.log"` → true (unqualified, dot is inside identifier)
16
+ * - `public.users` → false (qualified)
17
+ * - `"public"."users"` → false (qualified)
18
+ *
19
+ * @param value The table name to check
20
+ * @returns True if the name is unqualified (single segment)
21
+ */
22
+ export declare function isUnqualifiedName(value: unknown): boolean;
9
23
  //# sourceMappingURL=qualified-name.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"qualified-name.d.ts","sourceRoot":"","sources":["../../src/normalize/qualified-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,uBAAkC,GACvC,kBAAkB,GAAG,IAAI,CA2B3B;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,uBAAuB,GAC5B,MAAM,CAGR"}
1
+ {"version":3,"file":"qualified-name.d.ts","sourceRoot":"","sources":["../../src/normalize/qualified-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,uBAAkC,GACvC,kBAAkB,GAAG,IAAI,CA2B3B;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,uBAAuB,GAC5B,MAAM,CAGR;AA6BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOzD"}
@@ -5,6 +5,7 @@ export interface CompiledPolicy {
5
5
  allowedFunctionsUnqualified: Set<string>;
6
6
  allowedFunctionsQualified: Set<string>;
7
7
  tableIdentifierMatching: TableIdentifierMatching;
8
+ defaultSchema?: string;
8
9
  }
9
10
  type CompilePolicyResult = {
10
11
  success: true;
@@ -1 +1 @@
1
- {"version":3,"file":"compile-policy.d.ts","sourceRoot":"","sources":["../../src/policy/compile-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,2BAA2B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,uBAAuB,EAAE,uBAAuB,CAAC;CAClD;AAED,KAAK,mBAAmB,GACpB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC;AAElF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAwDjE;AA2BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,uBAAkC,GACvC,MAAM,GAAG,IAAI,CAGf"}
1
+ {"version":3,"file":"compile-policy.d.ts","sourceRoot":"","sources":["../../src/policy/compile-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,2BAA2B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,KAAK,mBAAmB,GACpB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC;AAElF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAuFjE;AA2BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,uBAAkC,GACvC,MAAM,GAAG,IAAI,CAGf"}
@@ -97,6 +97,19 @@ export interface Policy {
97
97
  * ```
98
98
  */
99
99
  resolver?: (unqualified: string) => string | null;
100
+ /**
101
+ * Default schema to use for unqualified table references.
102
+ * When provided, entries in `allowedTables` without a schema qualifier are
103
+ * automatically prefixed with this schema. Also used to resolve unqualified
104
+ * table references in SQL (unless a resolver is provided that returns non-null).
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * defaultSchema: 'public',
109
+ * allowedTables: ['users', 'orders'] // treated as ['public.users', 'public.orders']
110
+ * ```
111
+ */
112
+ defaultSchema?: string;
100
113
  }
101
114
  /**
102
115
  * Result of validating a SQL query against a policy.
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,oBAAY,SAAS;IACnB,0CAA0C;IAC1C,WAAW,gBAAgB;IAC3B,8EAA8E;IAC9E,uBAAuB,4BAA4B;IACnD,wDAAwD;IACxD,iBAAiB,sBAAsB;IACvC,yEAAyE;IACzE,qBAAqB,0BAA0B;IAC/C,qDAAqD;IACrD,oBAAoB,yBAAyB;IAC7C,+EAA+E;IAC/E,wBAAwB,6BAA6B;IACrD,sCAAsC;IACtC,cAAc,mBAAmB;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,iBAAiB,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;IAElE;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,EAAE,EAAE,OAAO,CAAC;IACZ,uEAAuE;IACvE,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;IAC9E,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IASzC,2DAA2D;aAC3C,IAAI,EAAE,SAAS;IAC/B,kDAAkD;aAClC,UAAU,EAAE,SAAS,EAAE;IAXzC;;;;;OAKG;gBAED,OAAO,EAAE,MAAM;IACf,2DAA2D;IAC3C,IAAI,EAAE,SAAS;IAC/B,kDAAkD;IAClC,UAAU,EAAE,SAAS,EAAE;CAK1C"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,oBAAY,SAAS;IACnB,0CAA0C;IAC1C,WAAW,gBAAgB;IAC3B,8EAA8E;IAC9E,uBAAuB,4BAA4B;IACnD,wDAAwD;IACxD,iBAAiB,sBAAsB;IACvC,yEAAyE;IACzE,qBAAqB,0BAA0B;IAC/C,qDAAqD;IACrD,oBAAoB,yBAAyB;IAC7C,+EAA+E;IAC/E,wBAAwB,6BAA6B;IACrD,sCAAsC;IACtC,cAAc,mBAAmB;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,iBAAiB,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;IAElE;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAElD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAElD;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,EAAE,EAAE,OAAO,CAAC;IACZ,uEAAuE;IACvE,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;IAC9E,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IASzC,2DAA2D;aAC3C,IAAI,EAAE,SAAS;IAC/B,kDAAkD;aAClC,UAAU,EAAE,SAAS,EAAE;IAXzC;;;;;OAKG;gBAED,OAAO,EAAE,MAAM;IACf,2DAA2D;IAC3C,IAAI,EAAE,SAAS;IAC/B,kDAAkD;IAClC,UAAU,EAAE,SAAS,EAAE;CAK1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sql-guard",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Validate AI-generated PostgreSQL queries against explicit table allowlists",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -43,8 +43,36 @@
43
43
  "security",
44
44
  "llm",
45
45
  "guard",
46
- "allowlist"
46
+ "allowlist",
47
+ "validation",
48
+ "postgresql",
49
+ "postgres",
50
+ "ast",
51
+ "parser",
52
+ "sanitize",
53
+ "injection",
54
+ "prevent",
55
+ "ai",
56
+ "chatgpt",
57
+ "codegen",
58
+ "database",
59
+ "query",
60
+ "policy",
61
+ "whitelist",
62
+ "rbac",
63
+ "least-privilege"
47
64
  ],
48
- "author": "",
49
- "license": "MIT"
65
+ "author": "Nur Zaman",
66
+ "license": "MIT",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/nur-zaman/sql-guard.git"
70
+ },
71
+ "bugs": {
72
+ "url": "https://github.com/nur-zaman/sql-guard/issues"
73
+ },
74
+ "homepage": "https://github.com/nur-zaman/sql-guard#readme",
75
+ "engines": {
76
+ "node": ">=18"
77
+ }
50
78
  }